mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 09:16:01 +08:00
Merge branch '3.7' of https://github.com/esotericsoftware/spine-runtimes into 3.7
This commit is contained in:
commit
b0629e51ec
@ -99,6 +99,8 @@
|
||||
* Updated to Unreal Engine 4.20 (samples require 4.17+), see the `spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.build.cs` file on how to compile in 4.20 with the latest UBT API changes.
|
||||
* Updated to Unreal Engine 4.21 (samples require 4.21).
|
||||
* **Breaking change**: `UBoneDriverComponent` and `UBoneFollowerComponent` are now `USceneComponent` instead of `UActorComponent`. They either update only themselves, or also the owning `UActor`, depending on whether the new flag `UseComponentTransform` is set. See https://github.com/EsotericSoftware/spine-runtimes/pull/1175
|
||||
* Added query methods for slots, bones, skins and animations to `SpineSkeletonComponent` and `UTrackEntry`. These allow you to query these objects by name in both C++ and blueprints.
|
||||
* Added `Preview Animation` and `Preview Skin` properties to `SpineSkeletonAnimationComponent`. Enter an animation or skin name to live-preview it in the editor. Enter an empty string to reset the animation or skin.
|
||||
|
||||
## C# ##
|
||||
* **Breaking changes**
|
||||
|
||||
@ -8,7 +8,7 @@ This spine Runtime may only be used for personal or internal use, typically to e
|
||||
|
||||
The spine Runtimes are developed with the intent to be used with data exported from spine. By purchasing spine, `Section 2` of the [spine Software License](https://esotericsoftware.com/files/license.txt) grants the right to create and distribute derivative works of the spine Runtimes.
|
||||
|
||||
## spine version
|
||||
## Spine version
|
||||
|
||||
spine-cpp works with data exported from spine 3.7.xx.
|
||||
|
||||
@ -19,6 +19,9 @@ spine-cpp supports all spine features.
|
||||
1. Download the spine Runtimes source using [git](https://help.github.com/articles/set-up-git) or by downloading it as a zip via the download button above.
|
||||
2. Copy the contents of the `spine-cpp/spine-cpp/src` and `spine-cpp/spine-cpp/include` directories into your project. Be sure your header search is configured to find the contents of the `spine-cpp/spine-cpp/include` directory. Note that the includes use `spine/Xxx.h`, so the `spine` directory cannot be omitted when copying the files.
|
||||
|
||||
## Usage
|
||||
### [Please see the spine-cpp guide for full documentation](http://esotericsoftware.com/spine-cpp)
|
||||
|
||||
## Extension
|
||||
|
||||
Extending spine-cpp requires implementing both the `SpineExtension` class and the TextureLoader class:
|
||||
|
||||
@ -171,6 +171,8 @@ void TrackEntry::reset() {
|
||||
_mixingFrom = NULL;
|
||||
_mixingTo = NULL;
|
||||
|
||||
setRendererObject(NULL);
|
||||
|
||||
_timelineMode.clear();
|
||||
_timelineHoldMix.clear();
|
||||
_timelinesRotation.clear();
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<groupId>com.esotericsoftware.spine</groupId>
|
||||
<artifactId>spine-libgdx</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.7.83.2-SNAPSHOT</version>
|
||||
<version>3.7.92.1-SNAPSHOT</version>
|
||||
|
||||
|
||||
<name>spine-libgdx</name>
|
||||
|
||||
@ -81,9 +81,9 @@ UObject* USpineSkeletonAssetFactory::FactoryCreateFile (UClass * InClass, UObjec
|
||||
if (!FFileHelper::LoadFileToArray(rawData, *Filename, 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
asset->SetSkeletonDataFileName(FName(*Filename));
|
||||
asset->SetRawData(rawData);
|
||||
|
||||
asset->SetSkeletonDataFileName(FName(*Filename));
|
||||
const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
|
||||
LoadAtlas(Filename, longPackagePath);
|
||||
return asset;
|
||||
|
||||
@ -96,6 +96,17 @@ void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDe
|
||||
CheckState();
|
||||
|
||||
if (state && bAutoPlaying) {
|
||||
if (lastPreviewAnimation != PreviewAnimation) {
|
||||
if (PreviewAnimation != "") SetAnimation(0, PreviewAnimation, true);
|
||||
else SetEmptyAnimation(0, 0);
|
||||
lastPreviewAnimation = PreviewAnimation;
|
||||
}
|
||||
|
||||
if (lastPreviewSkin != PreviewSkin) {
|
||||
if (PreviewSkin != "") SetSkin(PreviewSkin);
|
||||
else SetSkin("default");
|
||||
lastPreviewSkin = PreviewSkin;
|
||||
}
|
||||
state->update(DeltaTime);
|
||||
state->apply(*skeleton);
|
||||
if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
|
||||
|
||||
@ -42,7 +42,7 @@ USpineSkeletonComponent::USpineSkeletonComponent () {
|
||||
bAutoActivate = true;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetSkin(const FString& skinName) {
|
||||
bool USpineSkeletonComponent::SetSkin (const FString skinName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Skin* skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
||||
@ -53,7 +53,24 @@ bool USpineSkeletonComponent::SetSkin(const FString& skinName) {
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetAttachment (const FString& slotName, const FString& attachmentName) {
|
||||
void USpineSkeletonComponent::GetSkins (TArray<FString> &Skins) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getData()->getSkins().size(); i < n; i++) {
|
||||
Skins.Add(skeleton->getData()->getSkins()[i]->getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasSkin (const FString skinName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*skinName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::SetAttachment (const FString slotName, const FString attachmentName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
if (!skeleton->getAttachment(TCHAR_TO_UTF8(*slotName), TCHAR_TO_UTF8(*attachmentName))) return false;
|
||||
@ -127,7 +144,7 @@ void USpineSkeletonComponent::SetBoneWorldPosition (const FString& BoneName, con
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::UpdateWorldTransform() {
|
||||
void USpineSkeletonComponent::UpdateWorldTransform () {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
skeleton->updateWorldTransform();
|
||||
@ -154,24 +171,24 @@ void USpineSkeletonComponent::SetScaleX (float scaleX) {
|
||||
if (skeleton) skeleton->setScaleX(scaleX);
|
||||
}
|
||||
|
||||
float USpineSkeletonComponent::GetScaleX() {
|
||||
float USpineSkeletonComponent::GetScaleX () {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->getScaleX();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::SetScaleY(float scaleY) {
|
||||
void USpineSkeletonComponent::SetScaleY (float scaleY) {
|
||||
CheckState();
|
||||
if (skeleton) skeleton->setScaleY(scaleY);
|
||||
}
|
||||
|
||||
float USpineSkeletonComponent::GetScaleY() {
|
||||
float USpineSkeletonComponent::GetScaleY () {
|
||||
CheckState();
|
||||
if (skeleton) return skeleton->getScaleY();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetBones(TArray<FString> &Bones) {
|
||||
void USpineSkeletonComponent::GetBones (TArray<FString> &Bones) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getBones().size(); i < n; i++) {
|
||||
@ -180,6 +197,58 @@ void USpineSkeletonComponent::GetBones(TArray<FString> &Bones) {
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasBone (const FString BoneName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findBone(TCHAR_TO_UTF8(*BoneName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetSlots (TArray<FString> &Slots) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getSlots().size(); i < n; i++) {
|
||||
Slots.Add(skeleton->getSlots()[i]->getData().getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasSlot (const FString SlotName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findSlot(TCHAR_TO_UTF8(*SlotName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::GetAnimations(TArray<FString> &Animations) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
for (size_t i = 0, n = skeleton->getData()->getAnimations().size(); i < n; i++) {
|
||||
Animations.Add(skeleton->getData()->getAnimations()[i]->getName().buffer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool USpineSkeletonComponent::HasAnimation(FString AnimationName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
return skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*AnimationName)) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float USpineSkeletonComponent::GetAnimationDuration(FString AnimationName) {
|
||||
CheckState();
|
||||
if (skeleton) {
|
||||
Animation *animation = skeleton->getData()->findAnimation(TCHAR_TO_UTF8(*AnimationName));
|
||||
if (animation == nullptr) return 0;
|
||||
else return animation->getDuration();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USpineSkeletonComponent::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@ void USpineSkeletonDataAsset::Serialize (FArchive& Ar) {
|
||||
Super::Serialize(Ar);
|
||||
if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
|
||||
importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
|
||||
LoadInfo();
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -92,13 +93,92 @@ void USpineSkeletonDataAsset::BeginDestroy () {
|
||||
Super::BeginDestroy();
|
||||
}
|
||||
|
||||
class SP_API NullAttachmentLoader : public AttachmentLoader {
|
||||
public:
|
||||
|
||||
virtual RegionAttachment* newRegionAttachment(Skin& skin, const String& name, const String& path) {
|
||||
return new(__FILE__, __LINE__) RegionAttachment(name);
|
||||
}
|
||||
|
||||
virtual MeshAttachment* newMeshAttachment(Skin& skin, const String& name, const String& path) {
|
||||
return new(__FILE__, __LINE__) MeshAttachment(name);
|
||||
}
|
||||
|
||||
virtual BoundingBoxAttachment* newBoundingBoxAttachment(Skin& skin, const String& name) {
|
||||
return new(__FILE__, __LINE__) BoundingBoxAttachment(name);
|
||||
}
|
||||
|
||||
virtual PathAttachment* newPathAttachment(Skin& skin, const String& name) {
|
||||
return new(__FILE__, __LINE__) PathAttachment(name);
|
||||
}
|
||||
|
||||
virtual PointAttachment* newPointAttachment(Skin& skin, const String& name) {
|
||||
return new(__FILE__, __LINE__) PointAttachment(name);
|
||||
}
|
||||
|
||||
virtual ClippingAttachment* newClippingAttachment(Skin& skin, const String& name) {
|
||||
return new(__FILE__, __LINE__) ClippingAttachment(name);
|
||||
}
|
||||
|
||||
virtual void configureAttachment(Attachment* attachment) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
void USpineSkeletonDataAsset::LoadInfo() {
|
||||
#if WITH_EDITORONLY_DATA
|
||||
int dataLen = rawData.Num();
|
||||
if (dataLen == 0) return;
|
||||
NullAttachmentLoader loader;
|
||||
SkeletonData* skeletonData = nullptr;
|
||||
if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) {
|
||||
SkeletonJson* json = new (__FILE__, __LINE__) SkeletonJson(&loader);
|
||||
skeletonData = json->readSkeletonData((const char*)rawData.GetData());
|
||||
if (!skeletonData) {
|
||||
FMessageDialog::Debugf(FText::FromString(UTF8_TO_TCHAR(json->getError().buffer())));
|
||||
UE_LOG(SpineLog, Error, TEXT("Couldn't load skeleton data and atlas: %s"), UTF8_TO_TCHAR(json->getError().buffer()));
|
||||
}
|
||||
delete json;
|
||||
} else {
|
||||
SkeletonBinary* binary = new (__FILE__, __LINE__) SkeletonBinary(&loader);
|
||||
skeletonData = binary->readSkeletonData((const unsigned char*)rawData.GetData(), (int)rawData.Num());
|
||||
if (!skeletonData) {
|
||||
FMessageDialog::Debugf(FText::FromString(UTF8_TO_TCHAR(binary->getError().buffer())));
|
||||
UE_LOG(SpineLog, Error, TEXT("Couldn't load skeleton data and atlas: %s"), UTF8_TO_TCHAR(binary->getError().buffer()));
|
||||
}
|
||||
delete binary;
|
||||
}
|
||||
if (skeletonData) {
|
||||
Bones.Empty();
|
||||
for (int i = 0; i < skeletonData->getBones().size(); i++)
|
||||
Bones.Add(UTF8_TO_TCHAR(skeletonData->getBones()[i]->getName().buffer()));
|
||||
Skins.Empty();
|
||||
for (int i = 0; i < skeletonData->getSkins().size(); i++)
|
||||
Skins.Add(UTF8_TO_TCHAR(skeletonData->getSkins()[i]->getName().buffer()));
|
||||
Slots.Empty();
|
||||
for (int i = 0; i < skeletonData->getSlots().size(); i++)
|
||||
Slots.Add(UTF8_TO_TCHAR(skeletonData->getSlots()[i]->getName().buffer()));
|
||||
Animations.Empty();
|
||||
for (int i = 0; i < skeletonData->getAnimations().size(); i++)
|
||||
Animations.Add(UTF8_TO_TCHAR(skeletonData->getAnimations()[i]->getName().buffer()));
|
||||
Events.Empty();
|
||||
for (int i = 0; i < skeletonData->getEvents().size(); i++)
|
||||
Events.Add(UTF8_TO_TCHAR(skeletonData->getEvents()[i]->getName().buffer()));
|
||||
delete skeletonData;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void USpineSkeletonDataAsset::SetRawData(TArray<uint8> &Data) {
|
||||
this->rawData.Empty();
|
||||
this->rawData.Append(Data);
|
||||
|
||||
if (skeletonData) {
|
||||
delete skeletonData;
|
||||
skeletonData = nullptr;
|
||||
}
|
||||
|
||||
LoadInfo();
|
||||
}
|
||||
|
||||
SkeletonData* USpineSkeletonDataAsset::GetSkeletonData (Atlas* Atlas) {
|
||||
|
||||
@ -76,6 +76,12 @@ void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick
|
||||
UClass* skeletonClass = USpineSkeletonComponent::StaticClass();
|
||||
USpineSkeletonComponent* skeleton = Cast<USpineSkeletonComponent>(owner->GetComponentByClass(skeletonClass));
|
||||
|
||||
UpdateRenderer(skeleton);
|
||||
}
|
||||
}
|
||||
|
||||
void USpineSkeletonRendererComponent::UpdateRenderer(USpineSkeletonComponent* skeleton)
|
||||
{
|
||||
if (skeleton && !skeleton->IsBeingDestroyed() && skeleton->GetSkeleton() && skeleton->Atlas) {
|
||||
skeleton->GetSkeleton()->getColor().set(Color.R, Color.G, Color.B, Color.A);
|
||||
|
||||
@ -92,27 +98,28 @@ void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick
|
||||
for (int i = 0; i < skeleton->Atlas->atlasPages.Num(); i++) {
|
||||
AtlasPage* currPage = skeleton->Atlas->GetAtlas()->getPages()[i];
|
||||
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, owner);
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasNormalBlendMaterials.Add(material);
|
||||
pageToNormalBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, owner);
|
||||
material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasAdditiveBlendMaterials.Add(material);
|
||||
pageToAdditiveBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, owner);
|
||||
material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasMultiplyBlendMaterials.Add(material);
|
||||
pageToMultiplyBlendMaterial.Add(currPage, material);
|
||||
|
||||
material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, owner);
|
||||
material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, skeleton->Atlas->atlasPages[i]);
|
||||
atlasScreenBlendMaterials.Add(material);
|
||||
pageToScreenBlendMaterial.Add(currPage, material);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
pageToNormalBlendMaterial.Empty();
|
||||
pageToAdditiveBlendMaterial.Empty();
|
||||
pageToMultiplyBlendMaterial.Empty();
|
||||
@ -125,32 +132,32 @@ void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick
|
||||
UTexture* oldTexture = nullptr;
|
||||
|
||||
UMaterialInstanceDynamic* current = atlasNormalBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, owner);
|
||||
if (!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(NormalBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasNormalBlendMaterials[i] = material;
|
||||
}
|
||||
pageToNormalBlendMaterial.Add(currPage, atlasNormalBlendMaterials[i]);
|
||||
|
||||
current = atlasAdditiveBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, owner);
|
||||
if (!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(AdditiveBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasAdditiveBlendMaterials[i] = material;
|
||||
}
|
||||
pageToAdditiveBlendMaterial.Add(currPage, atlasAdditiveBlendMaterials[i]);
|
||||
|
||||
current = atlasMultiplyBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, owner);
|
||||
if (!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(MultiplyBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasMultiplyBlendMaterials[i] = material;
|
||||
}
|
||||
pageToMultiplyBlendMaterial.Add(currPage, atlasMultiplyBlendMaterials[i]);
|
||||
|
||||
current = atlasScreenBlendMaterials[i];
|
||||
if(!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, owner);
|
||||
if (!current || !current->GetTextureParameterValue(TextureParameterName, oldTexture) || oldTexture != texture) {
|
||||
UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(ScreenBlendMaterial, this);
|
||||
material->SetTextureParameterValue(TextureParameterName, texture);
|
||||
atlasScreenBlendMaterials[i] = material;
|
||||
}
|
||||
@ -158,13 +165,12 @@ void USpineSkeletonRendererComponent::TickComponent (float DeltaTime, ELevelTick
|
||||
}
|
||||
}
|
||||
UpdateMesh(skeleton->GetSkeleton());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ClearAllMeshSections();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void USpineSkeletonRendererComponent::Flush (int &Idx, TArray<FVector> &Vertices, TArray<int32> &Indices, TArray<FVector2D> &Uvs, TArray<FColor> &Colors, TArray<FVector>& Colors2, UMaterialInstanceDynamic* Material) {
|
||||
if (Vertices.Num() == 0) return;
|
||||
SetMaterial(Idx, Material);
|
||||
|
||||
@ -157,6 +157,15 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
|
||||
void SetMixDuration(float mixDuration) { if (entry) entry->setMixDuration(mixDuration); }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
FString getAnimationName() { return entry ? entry->getAnimation()->getName().buffer() : ""; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float getAnimationDuration() { return entry ? entry->getAnimation()->getDuration(): 0; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|TrackEntry")
|
||||
float isValidAnimation() { return entry != nullptr; }
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|TrackEntry")
|
||||
FSpineAnimationStartDelegate AnimationStart;
|
||||
|
||||
@ -251,6 +260,12 @@ public:
|
||||
UPROPERTY(BlueprintAssignable, Category="Components|Spine|Animation")
|
||||
FSpineAnimationDisposeDelegate AnimationDispose;
|
||||
|
||||
UPROPERTY(Transient, EditAnywhere, Category=Spine)
|
||||
FString PreviewAnimation;
|
||||
|
||||
UPROPERTY(Transient, EditAnywhere, Category=Spine)
|
||||
FString PreviewSkin;
|
||||
|
||||
// used in C event callback. Needs to be public as we can't call
|
||||
// protected methods from plain old C function.
|
||||
void GCTrackEntry(UTrackEntry* entry) { trackEntries.Remove(entry); }
|
||||
@ -270,4 +285,7 @@ private:
|
||||
/* If the animation should update automatically. */
|
||||
UPROPERTY()
|
||||
bool bAutoPlaying;
|
||||
|
||||
FString lastPreviewAnimation;
|
||||
FString lastPreviewSkin;
|
||||
};
|
||||
|
||||
@ -54,11 +54,17 @@ public:
|
||||
|
||||
spine::Skeleton* GetSkeleton () { return skeleton; };
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetSkin (const FString& SkinName);
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetSkins(TArray<FString> &Skins);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetAttachment (const FString& slotName, const FString& attachmentName);
|
||||
bool SetSkin (const FString SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasSkin(const FString SkinName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool SetAttachment (const FString slotName, const FString attachmentName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
FTransform GetBoneWorldTransform (const FString& BoneName);
|
||||
@ -93,6 +99,24 @@ public:
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetBones(TArray<FString> &Bones);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasBone(const FString BoneName);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetSlots(TArray<FString> &Slots);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasSlot(const FString SlotName);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton")
|
||||
void GetAnimations(TArray<FString> &Animations);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
bool HasAnimation(FString AnimationName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton")
|
||||
float GetAnimationDuration(FString AnimationName);
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton")
|
||||
FSpineBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform;
|
||||
|
||||
|
||||
@ -71,6 +71,21 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TArray<FSpineAnimationStateMixData> MixData;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Bones;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Slots;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Skins;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Animations;
|
||||
|
||||
UPROPERTY(Transient, VisibleAnywhere)
|
||||
TArray<FString> Events;
|
||||
|
||||
protected:
|
||||
UPROPERTY()
|
||||
TArray<uint8> rawData;
|
||||
@ -94,4 +109,6 @@ protected:
|
||||
virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override;
|
||||
virtual void Serialize (FArchive& Ar) override;
|
||||
#endif
|
||||
|
||||
void LoadInfo();
|
||||
};
|
||||
|
||||
@ -47,6 +47,9 @@ public:
|
||||
|
||||
virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
/* Updates this skeleton renderer using the provided skeleton animation component. */
|
||||
void UpdateRenderer(USpineSkeletonComponent* Skeleton);
|
||||
|
||||
// Material Instance parents
|
||||
UPROPERTY(Category = Spine, EditAnywhere, BlueprintReadOnly)
|
||||
UMaterialInterface* NormalBlendMaterial;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user