mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Merge branch '3.8' into 4.0-beta
This commit is contained in:
commit
ac23599638
@ -240,7 +240,8 @@
|
|||||||
* Removed dependency on `RHI`, `RenderCore`, and `ShaderCore`.
|
* Removed dependency on `RHI`, `RenderCore`, and `ShaderCore`.
|
||||||
* Re-importing atlases and their textures now works consistently in all situations.
|
* Re-importing atlases and their textures now works consistently in all situations.
|
||||||
* Added mix-and-match example to demonstrate the new Skin API.
|
* Added mix-and-match example to demonstrate the new Skin API.
|
||||||
* Materials on `SkeletonRendererComponent` are now blueprint read and writeable. This allows setting dynamic material instances at runtime
|
* Materials on `SkeletonRendererComponent` are now blueprint read and writeable. This allows setting dynamic material instances at runtime.
|
||||||
|
* Added `InitialSkin` property to `USpineWidget`. This allows previewing different skins in the UMG Designer. Initial skins can still be overridden via blueprint events such as `On Initialized`.
|
||||||
|
|
||||||
## C# ##
|
## C# ##
|
||||||
* **Breaking changes**
|
* **Breaking changes**
|
||||||
|
|||||||
@ -281,8 +281,16 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Skins. */
|
/* Skins. */
|
||||||
for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i)
|
for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i) {
|
||||||
skeletonData->_skins.add(readSkin(input, false, skeletonData, nonessential));
|
Skin* skin = readSkin(input, false, skeletonData, nonessential);
|
||||||
|
if (skin)
|
||||||
|
skeletonData->_skins.add(skin);
|
||||||
|
else {
|
||||||
|
delete input;
|
||||||
|
delete skeletonData;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Linked meshes. */
|
/* Linked meshes. */
|
||||||
for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) {
|
for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) {
|
||||||
@ -470,7 +478,12 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
|
|||||||
for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
|
for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
|
||||||
String name(readStringRef(input, skeletonData));
|
String name(readStringRef(input, skeletonData));
|
||||||
Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential);
|
Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential);
|
||||||
if (attachment) skin->setAttachment(slotIndex, String(name), attachment);
|
if (attachment)
|
||||||
|
skin->setAttachment(slotIndex, String(name), attachment);
|
||||||
|
else {
|
||||||
|
delete skin;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return skin;
|
return skin;
|
||||||
@ -488,6 +501,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
String path(readStringRef(input, skeletonData));
|
String path(readStringRef(input, skeletonData));
|
||||||
if (path.isEmpty()) path = name;
|
if (path.isEmpty()) path = name;
|
||||||
RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
|
RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
|
||||||
|
if (!region) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
region->_path = path;
|
region->_path = path;
|
||||||
region->_rotation = readFloat(input);
|
region->_rotation = readFloat(input);
|
||||||
region->_x = readFloat(input) * _scale;
|
region->_x = readFloat(input) * _scale;
|
||||||
@ -504,6 +521,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
case AttachmentType_Boundingbox: {
|
case AttachmentType_Boundingbox: {
|
||||||
int vertexCount = readVarint(input, true);
|
int vertexCount = readVarint(input, true);
|
||||||
BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
|
BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
|
||||||
|
if (!box) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
|
readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
/* Skip color. */
|
/* Skip color. */
|
||||||
@ -519,6 +540,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
if (path.isEmpty()) path = name;
|
if (path.isEmpty()) path = name;
|
||||||
|
|
||||||
mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
|
mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
|
||||||
|
if (!mesh) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
mesh->_path = path;
|
mesh->_path = path;
|
||||||
readColor(input, mesh->getColor());
|
readColor(input, mesh->getColor());
|
||||||
vertexCount = readVarint(input, true);
|
vertexCount = readVarint(input, true);
|
||||||
@ -543,6 +568,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
if (path.isEmpty()) path = name;
|
if (path.isEmpty()) path = name;
|
||||||
|
|
||||||
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
|
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
|
||||||
|
if (!mesh) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
mesh->_path = path;
|
mesh->_path = path;
|
||||||
readColor(input, mesh->getColor());
|
readColor(input, mesh->getColor());
|
||||||
String skinName(readStringRef(input, skeletonData));
|
String skinName(readStringRef(input, skeletonData));
|
||||||
@ -559,7 +588,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
case AttachmentType_Path: {
|
case AttachmentType_Path: {
|
||||||
PathAttachment *path = _attachmentLoader->newPathAttachment(*skin, String(name));
|
PathAttachment* path = _attachmentLoader->newPathAttachment(*skin, String(name));
|
||||||
|
if (!path) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
path->_closed = readBoolean(input);
|
path->_closed = readBoolean(input);
|
||||||
path->_constantSpeed = readBoolean(input);
|
path->_constantSpeed = readBoolean(input);
|
||||||
int vertexCount = readVarint(input, true);
|
int vertexCount = readVarint(input, true);
|
||||||
@ -577,7 +610,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
case AttachmentType_Point: {
|
case AttachmentType_Point: {
|
||||||
PointAttachment *point = _attachmentLoader->newPointAttachment(*skin, String(name));
|
PointAttachment* point = _attachmentLoader->newPointAttachment(*skin, String(name));
|
||||||
|
if (!point) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
point->_rotation = readFloat(input);
|
point->_rotation = readFloat(input);
|
||||||
point->_x = readFloat(input) * _scale;
|
point->_x = readFloat(input) * _scale;
|
||||||
point->_y = readFloat(input) * _scale;
|
point->_y = readFloat(input) * _scale;
|
||||||
@ -592,7 +629,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
case AttachmentType_Clipping: {
|
case AttachmentType_Clipping: {
|
||||||
int endSlotIndex = readVarint(input, true);
|
int endSlotIndex = readVarint(input, true);
|
||||||
int vertexCount = readVarint(input, true);
|
int vertexCount = readVarint(input, true);
|
||||||
ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name);
|
ClippingAttachment* clip = _attachmentLoader->newClippingAttachment(*skin, name);
|
||||||
|
if (!clip) {
|
||||||
|
setError("Error reading attachment: ", name.buffer());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
|
readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
|
||||||
clip->_endSlot = skeletonData->_slots[endSlotIndex];
|
clip->_endSlot = skeletonData->_slots[endSlotIndex];
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
@ -603,7 +644,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return clip;
|
return clip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) {
|
void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) {
|
||||||
|
|||||||
@ -99,6 +99,15 @@ void USpineWidget::SynchronizeProperties() {
|
|||||||
if (slateWidget.IsValid()) {
|
if (slateWidget.IsValid()) {
|
||||||
CheckState();
|
CheckState();
|
||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
|
if (!bSkinInitialized) { // blueprint On Initialized may be called beforehand
|
||||||
|
if (InitialSkin != "") SetSkin(InitialSkin);
|
||||||
|
#if WITH_EDITOR
|
||||||
|
if (IsDesignTime()) {
|
||||||
|
if (InitialSkin == "") SetSkin("default");
|
||||||
|
bSkinInitialized = false; // allow multiple edits in editor
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Tick(0, false);
|
Tick(0, false);
|
||||||
slateWidget->SetData(this);
|
slateWidget->SetData(this);
|
||||||
} else {
|
} else {
|
||||||
@ -204,6 +213,7 @@ bool USpineWidget::SetSkin(const FString skinName) {
|
|||||||
spine::Skin* skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
spine::Skin* skin = skeleton->getData()->findSkin(TCHAR_TO_UTF8(*skinName));
|
||||||
if (!skin) return false;
|
if (!skin) return false;
|
||||||
skeleton->setSkin(skin);
|
skeleton->setSkin(skin);
|
||||||
|
bSkinInitialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
@ -222,6 +232,7 @@ bool USpineWidget::SetSkins(UPARAM(ref) TArray<FString>& SkinNames) {
|
|||||||
newSkin->addSkin(skin);
|
newSkin->addSkin(skin);
|
||||||
}
|
}
|
||||||
skeleton->setSkin(newSkin);
|
skeleton->setSkin(newSkin);
|
||||||
|
bSkinInitialized = true;
|
||||||
if (customSkin != nullptr) {
|
if (customSkin != nullptr) {
|
||||||
delete customSkin;
|
delete customSkin;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,9 @@ public:
|
|||||||
virtual const FText GetPaletteCategory() override;
|
virtual const FText GetPaletteCategory() override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||||
|
FString InitialSkin;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
|
||||||
USpineAtlasAsset* Atlas;
|
USpineAtlasAsset* Atlas;
|
||||||
|
|
||||||
@ -254,4 +257,5 @@ private:
|
|||||||
/* If the animation should update automatically. */
|
/* If the animation should update automatically. */
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
bool bAutoPlaying;
|
bool bAutoPlaying;
|
||||||
|
bool bSkinInitialized = false;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user