diff --git a/spine-ue4/Content/Maps/example.umap b/spine-ue4/Content/Maps/example.umap index b24243d82..31083c262 100644 Binary files a/spine-ue4/Content/Maps/example.umap and b/spine-ue4/Content/Maps/example.umap differ diff --git a/spine-ue4/Content/SpineBoy/Spineboy_Blueprint.uasset b/spine-ue4/Content/SpineBoy/Spineboy_Blueprint.uasset index 619ac0154..cd5da0b47 100644 Binary files a/spine-ue4/Content/SpineBoy/Spineboy_Blueprint.uasset and b/spine-ue4/Content/SpineBoy/Spineboy_Blueprint.uasset differ diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonAnimationComponent.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonAnimationComponent.cpp index 6a883f3b0..e514e03cb 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonAnimationComponent.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonAnimationComponent.cpp @@ -54,9 +54,21 @@ void USpineSkeletonAnimationComponent::BeginPlay() { trackEntries.Empty(); } -void USpineSkeletonAnimationComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { +void USpineSkeletonAnimationComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - + + CheckState(); + + if (state) { + spAnimationState_update(state, DeltaTime); + spAnimationState_apply(state, skeleton); + BeforeUpdateWorldTransform.Broadcast(this); + spSkeleton_updateWorldTransform(skeleton); + AfterUpdateWorldTransform.Broadcast(this); + } +} + +void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime) { CheckState(); if (state) { @@ -106,6 +118,17 @@ void USpineSkeletonAnimationComponent::FinishDestroy () { Super::FinishDestroy(); } +void USpineSkeletonAnimationComponent::SetTimeScale(float timeScale) { + CheckState(); + if (state) state->timeScale = timeScale; +} + +float USpineSkeletonAnimationComponent::GetTimeScale() { + CheckState(); + if (state) return state->timeScale; + return 1; +} + UTrackEntry* USpineSkeletonAnimationComponent::SetAnimation (int trackIndex, FString animationName, bool loop) { CheckState(); if (state && spSkeletonData_findAnimation(skeleton->data, TCHAR_TO_UTF8(*animationName))) { diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp index 682f07bbc..3fa17f599 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp @@ -17,11 +17,39 @@ bool USpineSkeletonComponent::SetSkin(const FString& skinName) { bool USpineSkeletonComponent::setAttachment (const FString& slotName, const FString& attachmentName) { CheckState(); - if (skeleton) return spSkeleton_setAttachment(skeleton, TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName)); + if (skeleton) return spSkeleton_setAttachment(skeleton, TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName)) != 0; return false; } FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneName) { + CheckState(); + if (skeleton) { + spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName)); + if (!bone->appliedValid) this->InternalTick(0); + if (!bone) return FTransform(); + + // Need to fetch the renderer component to get world transform of actor plus + // offset by renderer component and its parent component(s). + // FIXME add overloaded method that takes a base world transform? + FTransform baseTransform; + AActor* owner = GetOwner(); + if (owner) { + USpineSkeletonRendererComponent* rendererComponent = static_cast(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass())); + if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform(); + } + + FVector position(bone->worldX, 0, bone->worldY); + FMatrix localTransform; + localTransform.SetIdentity(); + localTransform.SetAxis(2, FVector(bone->a, 0, bone->c)); + localTransform.SetAxis(0, FVector(bone->b, 0, bone->d)); + localTransform.SetOrigin(FVector(bone->worldX, 0, bone->worldY)); + localTransform = localTransform * baseTransform.ToMatrixWithScale(); + + FTransform result; + result.SetFromMatrix(localTransform); + return result; + } return FTransform(); } @@ -50,7 +78,10 @@ void USpineSkeletonComponent::BeginPlay() { void USpineSkeletonComponent::TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - + InternalTick(DeltaTime); +} + +void USpineSkeletonComponent::InternalTick(float DeltaTime) { CheckState(); if (skeleton) { diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonAnimationComponent.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonAnimationComponent.h index caa9e8253..37bd795e8 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonAnimationComponent.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonAnimationComponent.h @@ -188,6 +188,12 @@ public: virtual void FinishDestroy () override; // Blueprint functions + UFUNCTION(BlueprintCallable, Category = "Components|Spine") + void SetTimeScale(float timeScale); + + UFUNCTION(BlueprintCallable, Category = "Components|Spine") + float GetTimeScale(); + UFUNCTION(BlueprintCallable, Category="Components|Spine") UTrackEntry* SetAnimation (int trackIndex, FString animationName, bool loop); @@ -232,6 +238,7 @@ public: void GCTrackEntry(UTrackEntry* entry) { trackEntries.Remove(entry); } protected: virtual void CheckState () override; + virtual void InternalTick(float DeltaTime) override; virtual void DisposeState () override; spAnimationState* state; diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h index 66ee0091b..2a20fb93e 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h @@ -56,12 +56,13 @@ public: virtual void BeginPlay () override; - virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; virtual void FinishDestroy () override; protected: virtual void CheckState (); + virtual void InternalTick(float DeltaTime); virtual void DisposeState (); spSkeleton* skeleton;