mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[ue4] Fixed delegatepocalypse when callin InternalTick in BP functions. Added bone driver component, still freaking out like crazy.
This commit is contained in:
parent
8287e90298
commit
84766e3a99
Binary file not shown.
Binary file not shown.
BIN
spine-ue4/Content/SpineBoy/spineboy-hover.uasset
Normal file
BIN
spine-ue4/Content/SpineBoy/spineboy-hover.uasset
Normal file
Binary file not shown.
@ -0,0 +1,33 @@
|
||||
#include "SpinePluginPrivatePCH.h"
|
||||
|
||||
USpineBoneDriverComponent::USpineBoneDriverComponent () {
|
||||
bWantsBeginPlay = true;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
bTickInEditor = true;
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::BeginPlay () {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::BeforeUpdateWorldTransform(USpineSkeletonComponent* skeleton) {
|
||||
AActor* owner = GetOwner();
|
||||
if (owner) {
|
||||
skeleton->SetBoneWorldPosition(BoneName, owner->GetActorLocation() );
|
||||
}
|
||||
}
|
||||
|
||||
void USpineBoneDriverComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) {
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
if (Target) {
|
||||
USpineSkeletonComponent* skeleton = static_cast<USpineSkeletonComponent*>(Target->GetComponentByClass(USpineSkeletonComponent::StaticClass()));
|
||||
if (skeleton != lastBoundComponent) {
|
||||
// if (lastBoundComponent) lastBoundComponent->BeforeUpdateWorldTransform.RemoveAll(this);
|
||||
skeleton->BeforeUpdateWorldTransform.AddDynamic(this, &USpineBoneDriverComponent::BeforeUpdateWorldTransform);
|
||||
lastBoundComponent = skeleton;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ void USpineBoneFollowerComponent::BeginPlay () {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
|
||||
void USpineBoneFollowerComponent::TickComponent ( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
|
||||
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
|
||||
|
||||
|
||||
@ -10,3 +10,4 @@
|
||||
#include "SpineSkeletonAnimationComponent.h"
|
||||
#include "SpineSkeletonRendererComponent.h"
|
||||
#include "SpineBoneFollowerComponent.h"
|
||||
#include "SpineBoneDriverComponent.h"
|
||||
|
||||
@ -60,15 +60,15 @@ void USpineSkeletonAnimationComponent::TickComponent(float DeltaTime, ELevelTick
|
||||
InternalTick(DeltaTime);
|
||||
}
|
||||
|
||||
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime) {
|
||||
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (state) {
|
||||
spAnimationState_update(state, DeltaTime);
|
||||
spAnimationState_apply(state, skeleton);
|
||||
BeforeUpdateWorldTransform.Broadcast(this);
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
spSkeleton_updateWorldTransform(skeleton);
|
||||
AfterUpdateWorldTransform.Broadcast(this);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneNa
|
||||
if (skeleton) {
|
||||
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return FTransform();
|
||||
if (!bone->appliedValid) this->InternalTick(0);
|
||||
if (!bone->appliedValid) this->InternalTick(0, false);
|
||||
|
||||
// Need to fetch the renderer component to get world transform of actor plus
|
||||
// offset by renderer component and its parent component(s). If no renderer
|
||||
@ -57,7 +57,9 @@ FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneNa
|
||||
void USpineSkeletonComponent::SetBoneWorldPosition (const FString& BoneName, const FVector& position) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||
if (!bone) return;
|
||||
if (!bone->appliedValid) this->InternalTick(0, false);
|
||||
|
||||
// Need to fetch the renderer component to get world transform of actor plus
|
||||
// offset by renderer component and its parent component(s). If no renderer
|
||||
@ -71,9 +73,9 @@ void USpineSkeletonComponent::SetBoneWorldPosition (const FString& BoneName, con
|
||||
}
|
||||
|
||||
baseTransform = baseTransform.Inverse();
|
||||
baseTransform.TransformVector(position);
|
||||
FVector localPosition = baseTransform.TransformVector(position);
|
||||
float localX = 0, localY = 0;
|
||||
spBone_worldToLocal(bone, position.X, position.Z, &localX, &localY);
|
||||
spBone_worldToLocal(bone, localPosition.X, localPosition.Z, &localX, &localY);
|
||||
bone->x = localX;
|
||||
bone->y = localY;
|
||||
}
|
||||
@ -132,13 +134,13 @@ void USpineSkeletonComponent::TickComponent (float DeltaTime, ELevelTick TickTyp
|
||||
InternalTick(DeltaTime);
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::InternalTick(float DeltaTime) {
|
||||
void USpineSkeletonComponent::InternalTick(float DeltaTime, bool CallDelegates) {
|
||||
CheckState();
|
||||
|
||||
if (skeleton) {
|
||||
BeforeUpdateWorldTransform.Broadcast(this);
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
spSkeleton_updateWorldTransform(skeleton);
|
||||
AfterUpdateWorldTransform.Broadcast(this);
|
||||
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpineBoneDriverComponent.generated.h"
|
||||
|
||||
class USpineSkeletonComponent;
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class SPINEPLUGIN_API USpineBoneDriverComponent : public UActorComponent {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
AActor* Target = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FString BoneName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UsePosition = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseRotation = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool UseScale = true;
|
||||
|
||||
USpineBoneDriverComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
|
||||
|
||||
protected:
|
||||
UFUNCTION()
|
||||
void BeforeUpdateWorldTransform(USpineSkeletonComponent* skeleton);
|
||||
|
||||
USpineSkeletonComponent* lastBoundComponent = nullptr;
|
||||
};
|
||||
@ -238,7 +238,7 @@ public:
|
||||
void GCTrackEntry(UTrackEntry* entry) { trackEntries.Remove(entry); }
|
||||
protected:
|
||||
virtual void CheckState () override;
|
||||
virtual void InternalTick(float DeltaTime) override;
|
||||
virtual void InternalTick(float DeltaTime, bool CallDelegates = true) override;
|
||||
virtual void DisposeState () override;
|
||||
|
||||
spAnimationState* state;
|
||||
|
||||
@ -77,7 +77,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void CheckState ();
|
||||
virtual void InternalTick(float DeltaTime);
|
||||
virtual void InternalTick(float DeltaTime, bool CallDelegates = true);
|
||||
virtual void DisposeState ();
|
||||
|
||||
spSkeleton* skeleton;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user