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();
|
Super::BeginPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void USpineBoneFollowerComponent::TickComponent ( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
|
void USpineBoneFollowerComponent::TickComponent ( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
|
||||||
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
|
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
|
||||||
|
|
||||||
|
|||||||
@ -10,3 +10,4 @@
|
|||||||
#include "SpineSkeletonAnimationComponent.h"
|
#include "SpineSkeletonAnimationComponent.h"
|
||||||
#include "SpineSkeletonRendererComponent.h"
|
#include "SpineSkeletonRendererComponent.h"
|
||||||
#include "SpineBoneFollowerComponent.h"
|
#include "SpineBoneFollowerComponent.h"
|
||||||
|
#include "SpineBoneDriverComponent.h"
|
||||||
|
|||||||
@ -60,15 +60,15 @@ void USpineSkeletonAnimationComponent::TickComponent(float DeltaTime, ELevelTick
|
|||||||
InternalTick(DeltaTime);
|
InternalTick(DeltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime) {
|
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDelegates) {
|
||||||
CheckState();
|
CheckState();
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
spAnimationState_update(state, DeltaTime);
|
spAnimationState_update(state, DeltaTime);
|
||||||
spAnimationState_apply(state, skeleton);
|
spAnimationState_apply(state, skeleton);
|
||||||
BeforeUpdateWorldTransform.Broadcast(this);
|
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||||
spSkeleton_updateWorldTransform(skeleton);
|
spSkeleton_updateWorldTransform(skeleton);
|
||||||
AfterUpdateWorldTransform.Broadcast(this);
|
if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneNa
|
|||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||||
if (!bone) return FTransform();
|
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
|
// 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
|
// 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) {
|
void USpineSkeletonComponent::SetBoneWorldPosition (const FString& BoneName, const FVector& position) {
|
||||||
CheckState();
|
CheckState();
|
||||||
if (skeleton) {
|
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
|
// 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
|
// 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 = baseTransform.Inverse();
|
||||||
baseTransform.TransformVector(position);
|
FVector localPosition = baseTransform.TransformVector(position);
|
||||||
float localX = 0, localY = 0;
|
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->x = localX;
|
||||||
bone->y = localY;
|
bone->y = localY;
|
||||||
}
|
}
|
||||||
@ -132,13 +134,13 @@ void USpineSkeletonComponent::TickComponent (float DeltaTime, ELevelTick TickTyp
|
|||||||
InternalTick(DeltaTime);
|
InternalTick(DeltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USpineSkeletonComponent::InternalTick(float DeltaTime) {
|
void USpineSkeletonComponent::InternalTick(float DeltaTime, bool CallDelegates) {
|
||||||
CheckState();
|
CheckState();
|
||||||
|
|
||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
BeforeUpdateWorldTransform.Broadcast(this);
|
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||||
spSkeleton_updateWorldTransform(skeleton);
|
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); }
|
void GCTrackEntry(UTrackEntry* entry) { trackEntries.Remove(entry); }
|
||||||
protected:
|
protected:
|
||||||
virtual void CheckState () override;
|
virtual void CheckState () override;
|
||||||
virtual void InternalTick(float DeltaTime) override;
|
virtual void InternalTick(float DeltaTime, bool CallDelegates = true) override;
|
||||||
virtual void DisposeState () override;
|
virtual void DisposeState () override;
|
||||||
|
|
||||||
spAnimationState* state;
|
spAnimationState* state;
|
||||||
|
|||||||
@ -77,7 +77,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void CheckState ();
|
virtual void CheckState ();
|
||||||
virtual void InternalTick(float DeltaTime);
|
virtual void InternalTick(float DeltaTime, bool CallDelegates = true);
|
||||||
virtual void DisposeState ();
|
virtual void DisposeState ();
|
||||||
|
|
||||||
spSkeleton* skeleton;
|
spSkeleton* skeleton;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user