mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[ue4] Added bone follower component, fixed up SkeletonComponent::SetBoneWorldPosition
This commit is contained in:
parent
3b21f24027
commit
8287e90298
Binary file not shown.
Binary file not shown.
BIN
spine-ue4/Content/Vine/Textures/vine.uasset
Normal file
BIN
spine-ue4/Content/Vine/Textures/vine.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/Vine/Vine_Blueprint.uasset
Normal file
BIN
spine-ue4/Content/Vine/Vine_Blueprint.uasset
Normal file
Binary file not shown.
BIN
spine-ue4/Content/Vine/vine.uasset
Normal file
BIN
spine-ue4/Content/Vine/vine.uasset
Normal file
Binary file not shown.
@ -0,0 +1,29 @@
|
|||||||
|
#include "SpinePluginPrivatePCH.h"
|
||||||
|
|
||||||
|
USpineBoneFollowerComponent::USpineBoneFollowerComponent () {
|
||||||
|
bWantsBeginPlay = true;
|
||||||
|
PrimaryComponentTick.bCanEverTick = true;
|
||||||
|
bTickInEditor = true;
|
||||||
|
bAutoActivate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USpineBoneFollowerComponent::BeginPlay () {
|
||||||
|
Super::BeginPlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USpineBoneFollowerComponent::TickComponent ( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
|
||||||
|
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
|
||||||
|
|
||||||
|
AActor* owner = GetOwner();
|
||||||
|
if (Target && owner) {
|
||||||
|
USpineSkeletonComponent* skeleton = static_cast<USpineSkeletonComponent*>(Target->GetComponentByClass(USpineSkeletonComponent::StaticClass()));
|
||||||
|
if (skeleton) {
|
||||||
|
FTransform transform = skeleton->GetBoneWorldTransform(BoneName);
|
||||||
|
if (UsePosition) owner->SetActorLocation(transform.GetLocation());
|
||||||
|
if (UseRotation) owner->SetActorRotation(transform.GetRotation());
|
||||||
|
if (UseScale) owner->SetActorScale3D(transform.GetScale3D());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -9,3 +9,4 @@
|
|||||||
#include "SpineSkeletonComponent.h"
|
#include "SpineSkeletonComponent.h"
|
||||||
#include "SpineSkeletonAnimationComponent.h"
|
#include "SpineSkeletonAnimationComponent.h"
|
||||||
#include "SpineSkeletonRendererComponent.h"
|
#include "SpineSkeletonRendererComponent.h"
|
||||||
|
#include "SpineBoneFollowerComponent.h"
|
||||||
|
|||||||
@ -24,18 +24,19 @@ bool USpineSkeletonComponent::setAttachment (const FString& slotName, const FStr
|
|||||||
FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneName) {
|
FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneName) {
|
||||||
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->appliedValid) this->InternalTick(0);
|
|
||||||
if (!bone) return FTransform();
|
if (!bone) return FTransform();
|
||||||
|
if (!bone->appliedValid) this->InternalTick(0);
|
||||||
|
|
||||||
// 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).
|
// offset by renderer component and its parent component(s). If no renderer
|
||||||
// FIXME add overloaded method that takes a base world transform?
|
// component is found, this components owner's transform is used as a fallback
|
||||||
FTransform baseTransform;
|
FTransform baseTransform;
|
||||||
AActor* owner = GetOwner();
|
AActor* owner = GetOwner();
|
||||||
if (owner) {
|
if (owner) {
|
||||||
USpineSkeletonRendererComponent* rendererComponent = static_cast<USpineSkeletonRendererComponent*>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
USpineSkeletonRendererComponent* rendererComponent = static_cast<USpineSkeletonRendererComponent*>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
||||||
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
||||||
|
else baseTransform = owner->GetActorTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector position(bone->worldX, 0, bone->worldY);
|
FVector position(bone->worldX, 0, bone->worldY);
|
||||||
@ -53,8 +54,36 @@ FTransform USpineSkeletonComponent::GetBoneWorldTransform (const FString& BoneNa
|
|||||||
return FTransform();
|
return FTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
FTransform USpineSkeletonComponent::GetBoneLocalTransform (const FString& BoneName) {
|
void USpineSkeletonComponent::SetBoneWorldPosition (const FString& BoneName, const FVector& position) {
|
||||||
return FTransform();
|
CheckState();
|
||||||
|
if (skeleton) {
|
||||||
|
spBone* bone = spSkeleton_findBone(skeleton, TCHAR_TO_UTF8(*BoneName));
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// component is found, this components owner's transform is used as a fallback
|
||||||
|
FTransform baseTransform;
|
||||||
|
AActor* owner = GetOwner();
|
||||||
|
if (owner) {
|
||||||
|
USpineSkeletonRendererComponent* rendererComponent = static_cast<USpineSkeletonRendererComponent*>(owner->GetComponentByClass(USpineSkeletonRendererComponent::StaticClass()));
|
||||||
|
if (rendererComponent) baseTransform = rendererComponent->GetComponentTransform();
|
||||||
|
else baseTransform = owner->GetActorTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
baseTransform = baseTransform.Inverse();
|
||||||
|
baseTransform.TransformVector(position);
|
||||||
|
float localX = 0, localY = 0;
|
||||||
|
spBone_worldToLocal(bone, position.X, position.Z, &localX, &localY);
|
||||||
|
bone->x = localX;
|
||||||
|
bone->y = localY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USpineSkeletonComponent::UpdateWorldTransform() {
|
||||||
|
CheckState();
|
||||||
|
if (skeleton) {
|
||||||
|
spSkeleton_updateWorldTransform(skeleton);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USpineSkeletonComponent::SetToSetupPose () {
|
void USpineSkeletonComponent::SetToSetupPose () {
|
||||||
@ -72,6 +101,28 @@ void USpineSkeletonComponent::SetSlotsToSetupPose () {
|
|||||||
if (skeleton) spSkeleton_setSlotsToSetupPose(skeleton);
|
if (skeleton) spSkeleton_setSlotsToSetupPose(skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USpineSkeletonComponent::SetFlipX (bool flipX) {
|
||||||
|
CheckState();
|
||||||
|
if (skeleton) skeleton->flipX = flipX ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USpineSkeletonComponent::GetFlipX() {
|
||||||
|
CheckState();
|
||||||
|
if (skeleton) return skeleton->flipX != 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USpineSkeletonComponent::SetFlipY(bool flipY) {
|
||||||
|
CheckState();
|
||||||
|
if (skeleton) skeleton->flipY = flipY ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USpineSkeletonComponent::GetFlipY() {
|
||||||
|
CheckState();
|
||||||
|
if (skeleton) return skeleton->flipY != 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void USpineSkeletonComponent::BeginPlay() {
|
void USpineSkeletonComponent::BeginPlay() {
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Components/ActorComponent.h"
|
||||||
|
#include "SpineBoneFollowerComponent.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||||
|
class SPINEPLUGIN_API USpineBoneFollowerComponent : 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;
|
||||||
|
|
||||||
|
USpineBoneFollowerComponent ();
|
||||||
|
|
||||||
|
virtual void BeginPlay () override;
|
||||||
|
|
||||||
|
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||||
|
};
|
||||||
@ -35,16 +35,31 @@ public:
|
|||||||
FTransform GetBoneWorldTransform (const FString& BoneName);
|
FTransform GetBoneWorldTransform (const FString& BoneName);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
FTransform GetBoneLocalTransform (const FString& BoneName);
|
void SetBoneWorldPosition (const FString& BoneName, const FVector& position);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
void SetToSetupPose ();
|
void SetToSetupPose ();
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
void SetBonesToSetupPose ();
|
void SetBonesToSetupPose ();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
|
void UpdateWorldTransform ();
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
void SetSlotsToSetupPose ();
|
void SetSlotsToSetupPose ();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
|
void SetFlipX(bool flipX);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
|
bool GetFlipX();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
|
void SetFlipY(bool flipY);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Components|Spine")
|
||||||
|
bool GetFlipY();
|
||||||
|
|
||||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine")
|
UPROPERTY(BlueprintAssignable, Category = "Components|Spine")
|
||||||
FSpineBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform;
|
FSpineBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user