[ue4] Fixed delegatepocalypse when callin InternalTick in BP functions. Added bone driver component, still freaking out like crazy.

This commit is contained in:
badlogic 2016-12-13 16:39:33 +01:00
parent 8287e90298
commit 84766e3a99
11 changed files with 87 additions and 13 deletions

Binary file not shown.

Binary file not shown.

View File

@ -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;
}
}
}

View File

@ -11,7 +11,6 @@ void USpineBoneFollowerComponent::BeginPlay () {
Super::BeginPlay();
}
void USpineBoneFollowerComponent::TickComponent ( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );

View File

@ -10,3 +10,4 @@
#include "SpineSkeletonAnimationComponent.h"
#include "SpineSkeletonRendererComponent.h"
#include "SpineBoneFollowerComponent.h"
#include "SpineBoneDriverComponent.h"

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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;