[csharp][unity] Adjusted spine-csharp and dependent modules to being used as separate UPM packages. See #1676.

This commit is contained in:
Harald Csaszar 2021-09-14 17:06:06 +02:00
parent 2d34b84f46
commit 91f7969cdc
37 changed files with 465 additions and 389 deletions

View File

@ -546,6 +546,26 @@ namespace Spine {
} }
float x, y; float x, y;
EvaluateCurve(out x, out y, time); // note: reference implementation has code inlined
switch (blend) {
case MixBlend.Setup:
bone.x = bone.data.x + x * alpha;
bone.y = bone.data.y + y * alpha;
break;
case MixBlend.First:
case MixBlend.Replace:
bone.x += (bone.data.x + x - bone.x) * alpha;
bone.y += (bone.data.y + y - bone.y) * alpha;
break;
case MixBlend.Add:
bone.x += x * alpha;
bone.y += y * alpha;
break;
}
}
protected void EvaluateCurve (out float x, out float y, float time) {
int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
@ -565,21 +585,26 @@ namespace Spine {
y = GetBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER); y = GetBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER);
break; break;
} }
}
switch (blend) { /// <summary>Evaluates the resulting value of a TranslateTimeline at a given time.
case MixBlend.Setup: /// If no SkeletonData is given, values are returned as difference to setup pose
bone.x = bone.data.x + x * alpha; /// instead of absolute values.</summary>
bone.y = bone.data.y + y * alpha; public void Evaluate (out float outX, out float outY, float time, SkeletonData skeletonData) {
break; outX = outY = 0;
case MixBlend.First: if (time < frames[0]) return;
case MixBlend.Replace:
bone.x += (bone.data.x + x - bone.x) * alpha; float x, y;
bone.y += (bone.data.y + y - bone.y) * alpha; EvaluateCurve(out x, out y, time);
break;
case MixBlend.Add: if (skeletonData == null) {
bone.x += x * alpha; outX = x;
bone.y += y * alpha; outY = y;
break; return;
} else {
var boneData = skeletonData.bones.Items[boneIndex];
outX = x + boneData.x;
outY = y + boneData.y;
} }
} }
} }

View File

@ -1139,6 +1139,8 @@ namespace Spine {
/// </summary> /// </summary>
public float Alpha { get { return alpha; } set { alpha = value; } } public float Alpha { get { return alpha; } set { alpha = value; } }
public float InterruptAlpha { get { return interruptAlpha; } }
/// <summary> /// <summary>
/// When the mix percentage (<see cref="TrackEntry.MixTime"/> / <see cref="TrackEntry.MixDuration"/>) is less than the /// When the mix percentage (<see cref="TrackEntry.MixTime"/> / <see cref="TrackEntry.MixDuration"/>) is less than the
/// <code>EventThreshold</code>, event timelines are applied while this animation is being mixed out. Defaults to 0, so event /// <code>EventThreshold</code>, event timelines are applied while this animation is being mixed out. Defaults to 0, so event
@ -1257,6 +1259,14 @@ namespace Spine {
override public string ToString () { override public string ToString () {
return animation == null ? "<none>" : animation.name; return animation == null ? "<none>" : animation.name;
} }
// Note: This method is required by SpineAnimationStateMixerBehaviour,
// which is part of the timeline extension package. Thus the internal member variable
// nextTrackLast is not accessible. We favor providing this method
// over exposing nextTrackLast as public property, which would rather confuse users.
public void AllowImmediateQueue () {
if (nextTrackLast < 0) nextTrackLast = 0;
}
} }
class EventQueue { class EventQueue {

View File

@ -0,0 +1,34 @@
{
"name": "com.esotericsoftware.spine.spine-csharp",
"displayName": "spine-csharp Runtime",
"description": "This plugin provides the spine-csharp core runtime.",
"version": "4.0.0",
"unity": "2018.3",
"author": {
"name": "Esoteric Software",
"email": "contact@esotericsoftware.com",
"url": "http://esotericsoftware.com/"
},
"dependencies": {
},
"files": [
"src"
],
"repository": {
"type": "git",
"url": "git@github.com:EsotericSoftware/spine-runtimes.git"
},
"keywords": [
"spine",
"spine-csharp",
"runtimes",
"2d",
"skeletal",
"animation"
],
"license": "SEE LICENSE IN LICENSE",
"bugs": {
"url": "https://github.com/EsotericSoftware/spine-runtimes/issues"
},
"homepage": "https://github.com/EsotericSoftware/spine-runtimes#readme"
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 84ca0094807afe74295fdf4864a0ceca
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,4 @@
{
"name": "spine-csharp",
"references": []
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 72d1fea872bd7a449bf3818f2b0a6708
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,20 +1,33 @@
{ {
"name": "com.esotericsoftware.spine.spine-unity-examples", "name": "com.esotericsoftware.spine.spine-unity-examples",
"displayName": "spine-unity Runtime Examples", "displayName": "spine-unity Runtime Examples",
"description": "This plugin provides example scenes and scripts for the spine-unity runtime.", "description": "This plugin provides example scenes and scripts for the spine-unity runtime.",
"version": "3.9.0", "version": "4.0.0",
"unity": "2018.3", "unity": "2018.3",
"author": { "author": {
"name": "Esoteric Software", "name": "Esoteric Software",
"email": "contact@esotericsoftware.com", "email": "contact@esotericsoftware.com",
"url": "http://esotericsoftware.com/" "url": "http://esotericsoftware.com/"
}, },
"dependencies": { "dependencies": {
"com.esotericsoftware.spine.spine-unity": "3.9.0" "com.esotericsoftware.spine.spine-unity": "4.0.0"
}, },
"keywords": [ "repository": {
"spine", "type": "git",
"spine-unity", "url": "git@github.com:EsotericSoftware/spine-runtimes.git"
"core" },
] "keywords": [
"spine",
"spine-unity",
"runtimes",
"2d",
"skeletal",
"animation"
],
"license": "SEE LICENSE IN LICENSE",
"bugs": {
"url": "https://github.com/EsotericSoftware/spine-runtimes/issues"
},
"homepage": "https://github.com/EsotericSoftware/spine-runtimes#readme",
"type": "sample"
} }

View File

@ -1,4 +1,4 @@
{ {
"name": "spine-unity-examples", "name": "spine-unity-examples",
"references": [ "spine-unity" ] "references": [ "spine-unity", "spine-csharp" ]
} }

View File

@ -1,6 +1,7 @@
{ {
"name": "spine-unity-editor", "name": "spine-unity-editor",
"references": [ "references": [
"spine-csharp",
"spine-unity" "spine-unity"
], ],
"optionalUnityReferences": [], "optionalUnityReferences": [],

View File

@ -1,4 +1,4 @@
{ {
"name": "spine-unity", "name": "spine-unity",
"references": [] "references": [ "spine-csharp" ]
} }

View File

@ -76,8 +76,8 @@ namespace Spine.Unity {
var slotsItems = skeletonData.Slots.Items; var slotsItems = skeletonData.Slots.Items;
for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) { for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) {
var slot = slotsItems[slotIndex]; var slot = slotsItems[slotIndex];
if (slot.blendMode == BlendMode.Normal) continue; if (slot.BlendMode == BlendMode.Normal) continue;
if (!applyAdditiveMaterial && slot.blendMode == BlendMode.Additive) continue; if (!applyAdditiveMaterial && slot.BlendMode == BlendMode.Additive) continue;
skinEntries.Clear(); skinEntries.Clear();
foreach (var skin in skeletonData.Skins) foreach (var skin in skeletonData.Skins)
@ -102,11 +102,11 @@ namespace Spine.Unity {
var slotsItems = skeletonData.Slots.Items; var slotsItems = skeletonData.Slots.Items;
for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) { for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) {
var slot = slotsItems[slotIndex]; var slot = slotsItems[slotIndex];
if (slot.blendMode == BlendMode.Normal) continue; if (slot.BlendMode == BlendMode.Normal) continue;
if (!applyAdditiveMaterial && slot.blendMode == BlendMode.Additive) continue; if (!applyAdditiveMaterial && slot.BlendMode == BlendMode.Additive) continue;
List<ReplacementMaterial> replacementMaterials = null; List<ReplacementMaterial> replacementMaterials = null;
switch (slot.blendMode) { switch (slot.BlendMode) {
case BlendMode.Multiply: case BlendMode.Multiply:
replacementMaterials = multiplyMaterials; replacementMaterials = multiplyMaterials;
break; break;

View File

@ -219,7 +219,7 @@ namespace Spine.Unity {
public void FillStateData () { public void FillStateData () {
if (stateData != null) { if (stateData != null) {
stateData.defaultMix = defaultMix; stateData.DefaultMix = defaultMix;
for (int i = 0, n = fromAnimation.Length; i < n; i++) { for (int i = 0, n = fromAnimation.Length; i < n; i++) {
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)

View File

@ -156,12 +156,12 @@ namespace Spine.Unity {
float additionalFlipScale = 1; float additionalFlipScale = 1;
if (skeletonTransformIsParent) { if (skeletonTransformIsParent) {
// Recommended setup: Use local transform properties if Spine GameObject is the immediate parent // Recommended setup: Use local transform properties if Spine GameObject is the immediate parent
thisTransform.localPosition = new Vector3(followXYPosition ? bone.worldX : thisTransform.localPosition.x, thisTransform.localPosition = new Vector3(followXYPosition ? bone.WorldX : thisTransform.localPosition.x,
followXYPosition ? bone.worldY : thisTransform.localPosition.y, followXYPosition ? bone.WorldY : thisTransform.localPosition.y,
followZPosition ? 0f : thisTransform.localPosition.z); followZPosition ? 0f : thisTransform.localPosition.z);
if (followBoneRotation) { if (followBoneRotation) {
float halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f; float halfRotation = Mathf.Atan2(bone.C, bone.A) * 0.5f;
if (followLocalScale && bone.scaleX < 0) // Negate rotation from negative scaleX. Don't use negative determinant. local scaleY doesn't factor into used rotation. if (followLocalScale && bone.ScaleX < 0) // Negate rotation from negative scaleX. Don't use negative determinant. local scaleY doesn't factor into used rotation.
halfRotation += Mathf.PI * 0.5f; halfRotation += Mathf.PI * 0.5f;
var q = default(Quaternion); var q = default(Quaternion);
@ -171,7 +171,7 @@ namespace Spine.Unity {
} }
} else { } else {
// For special cases: Use transform world properties if transform relationship is complicated // For special cases: Use transform world properties if transform relationship is complicated
Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f)); Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.WorldX, bone.WorldY, 0f));
if (!followZPosition) targetWorldPosition.z = thisTransform.position.z; if (!followZPosition) targetWorldPosition.z = thisTransform.position.z;
if (!followXYPosition) { if (!followXYPosition) {
targetWorldPosition.x = thisTransform.position.x; targetWorldPosition.x = thisTransform.position.x;
@ -196,7 +196,7 @@ namespace Spine.Unity {
} }
Vector3 worldRotation = skeletonTransform.rotation.eulerAngles; Vector3 worldRotation = skeletonTransform.rotation.eulerAngles;
if (followLocalScale && bone.scaleX < 0) boneWorldRotation += 180f; if (followLocalScale && bone.ScaleX < 0) boneWorldRotation += 180f;
thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation)); thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation));
} else { } else {
thisTransform.position = targetWorldPosition; thisTransform.position = targetWorldPosition;
@ -206,9 +206,9 @@ namespace Spine.Unity {
* skeletonLossyScale.y * parentLossyScale.y); * skeletonLossyScale.y * parentLossyScale.y);
} }
Vector3 localScale = followLocalScale ? new Vector3(bone.scaleX, bone.scaleY, 1f) : new Vector3(1f, 1f, 1f); Vector3 localScale = followLocalScale ? new Vector3(bone.ScaleX, bone.ScaleY, 1f) : new Vector3(1f, 1f, 1f);
if (followSkeletonFlip) if (followSkeletonFlip)
localScale.y *= Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY) * additionalFlipScale; localScale.y *= Mathf.Sign(bone.Skeleton.ScaleX * bone.Skeleton.ScaleY) * additionalFlipScale;
thisTransform.localScale = localScale; thisTransform.localScale = localScale;
} }

View File

@ -144,13 +144,13 @@ namespace Spine.Unity {
float additionalFlipScale = 1; float additionalFlipScale = 1;
if (skeletonTransformIsParent) { if (skeletonTransformIsParent) {
// Recommended setup: Use local transform properties if Spine GameObject is the immediate parent // Recommended setup: Use local transform properties if Spine GameObject is the immediate parent
thisTransform.localPosition = new Vector3(followXYPosition ? bone.worldX * scale : thisTransform.localPosition.x, thisTransform.localPosition = new Vector3(followXYPosition ? bone.WorldX * scale : thisTransform.localPosition.x,
followXYPosition ? bone.worldY * scale : thisTransform.localPosition.y, followXYPosition ? bone.WorldY * scale : thisTransform.localPosition.y,
followZPosition ? 0f : thisTransform.localPosition.z); followZPosition ? 0f : thisTransform.localPosition.z);
if (followBoneRotation) thisTransform.localRotation = bone.GetQuaternion(); if (followBoneRotation) thisTransform.localRotation = bone.GetQuaternion();
} else { } else {
// For special cases: Use transform world properties if transform relationship is complicated // For special cases: Use transform world properties if transform relationship is complicated
Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX * scale, bone.worldY * scale, 0f)); Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.WorldX * scale, bone.WorldY * scale, 0f));
if (!followZPosition) targetWorldPosition.z = thisTransform.position.z; if (!followZPosition) targetWorldPosition.z = thisTransform.position.z;
if (!followXYPosition) { if (!followXYPosition) {
targetWorldPosition.x = thisTransform.position.x; targetWorldPosition.x = thisTransform.position.x;
@ -175,7 +175,7 @@ namespace Spine.Unity {
} }
Vector3 worldRotation = skeletonTransform.rotation.eulerAngles; Vector3 worldRotation = skeletonTransform.rotation.eulerAngles;
if (followLocalScale && bone.scaleX < 0) boneWorldRotation += 180f; if (followLocalScale && bone.ScaleX < 0) boneWorldRotation += 180f;
thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation)); thisTransform.SetPositionAndRotation(targetWorldPosition, Quaternion.Euler(worldRotation.x, worldRotation.y, worldRotation.z + boneWorldRotation));
} else { } else {
thisTransform.position = targetWorldPosition; thisTransform.position = targetWorldPosition;
@ -185,9 +185,9 @@ namespace Spine.Unity {
* skeletonLossyScale.y * parentLossyScale.y); * skeletonLossyScale.y * parentLossyScale.y);
} }
Vector3 localScale = followLocalScale ? new Vector3(bone.scaleX, bone.scaleY, 1f) : new Vector3(1f, 1f, 1f); Vector3 localScale = followLocalScale ? new Vector3(bone.ScaleX, bone.ScaleY, 1f) : new Vector3(1f, 1f, 1f);
if (followSkeletonFlip) if (followSkeletonFlip)
localScale.y *= Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY) * additionalFlipScale; localScale.y *= Mathf.Sign(bone.Skeleton.ScaleX * bone.Skeleton.ScaleY) * additionalFlipScale;
thisTransform.localScale = localScale; thisTransform.localScale = localScale;
} }

View File

@ -97,13 +97,10 @@ namespace Spine.Unity {
return; return;
// Don't reinitialize if the setup did not change. // Don't reinitialize if the setup did not change.
if (!overwrite if (!overwrite &&
&& colliderTable.Count > 0 && slot != null && // Slot is set and colliders already populated.
colliderTable.Count > 0 && slot != null // Slot is set and colliders already populated. skeletonRenderer.skeleton == slot.Skeleton && // Skeleton object did not change.
&& slotName == slot.Data.Name // Slot object did not change.
skeletonRenderer.skeleton == slot.Skeleton // Skeleton object did not change.
&&
slotName == slot.data.name // Slot object did not change.
) )
return; return;
@ -131,8 +128,8 @@ namespace Spine.Unity {
foreach (var skin in skeleton.Data.Skins) foreach (var skin in skeleton.Data.Skins)
AddCollidersForSkin(skin, slotIndex, colliders, ref requiredCollidersCount); AddCollidersForSkin(skin, slotIndex, colliders, ref requiredCollidersCount);
if (skeleton.skin != null) if (skeleton.Skin != null)
AddCollidersForSkin(skeleton.skin, slotIndex, colliders, ref requiredCollidersCount); AddCollidersForSkin(skeleton.Skin, slotIndex, colliders, ref requiredCollidersCount);
} }
DisposeExcessCollidersAfter(requiredCollidersCount); DisposeExcessCollidersAfter(requiredCollidersCount);

View File

@ -97,13 +97,10 @@ namespace Spine.Unity {
return; return;
// Don't reinitialize if the setup did not change. // Don't reinitialize if the setup did not change.
if (!overwrite if (!overwrite &&
&& colliderTable.Count > 0 && slot != null && // Slot is set and colliders already populated.
colliderTable.Count > 0 && slot != null // Slot is set and colliders already populated. skeletonGraphic.Skeleton == slot.Skeleton && // Skeleton object did not change.
&& slotName == slot.Data.Name // Slot object did not change.
skeletonGraphic.Skeleton == slot.Skeleton // Skeleton object did not change.
&&
slotName == slot.data.name // Slot object did not change.
) )
return; return;
@ -135,8 +132,8 @@ namespace Spine.Unity {
foreach (var skin in skeleton.Data.Skins) foreach (var skin in skeleton.Data.Skins)
AddCollidersForSkin(skin, slotIndex, colliders, scale, ref requiredCollidersCount); AddCollidersForSkin(skin, slotIndex, colliders, scale, ref requiredCollidersCount);
if (skeleton.skin != null) if (skeleton.Skin != null)
AddCollidersForSkin(skeleton.skin, slotIndex, colliders, scale, ref requiredCollidersCount); AddCollidersForSkin(skeleton.Skin, slotIndex, colliders, scale, ref requiredCollidersCount);
} }
DisposeExcessCollidersAfter(requiredCollidersCount); DisposeExcessCollidersAfter(requiredCollidersCount);

View File

@ -95,7 +95,7 @@ namespace Spine.Unity {
Slot slot = skeleton.FindSlot(slotName); Slot slot = skeleton.FindSlot(slotName);
if (slot != null) { if (slot != null) {
int slotIndex = slot.Data.Index; int slotIndex = slot.Data.Index;
bone = slot.bone; bone = slot.Bone;
point = skeleton.GetAttachment(slotIndex, pointAttachmentName) as PointAttachment; point = skeleton.GetAttachment(slotIndex, pointAttachmentName) as PointAttachment;
} }
} }
@ -156,7 +156,7 @@ namespace Spine.Unity {
if (followSkeletonFlip) { if (followSkeletonFlip) {
Vector3 localScale = thisTransform.localScale; Vector3 localScale = thisTransform.localScale;
localScale.y = Mathf.Abs(localScale.y) * Mathf.Sign(bone.skeleton.ScaleX * bone.skeleton.ScaleY); localScale.y = Mathf.Abs(localScale.y) * Mathf.Sign(bone.Skeleton.ScaleX * bone.Skeleton.ScaleY);
thisTransform.localScale = localScale; thisTransform.localScale = localScale;
} }
} }

View File

@ -69,7 +69,7 @@ namespace Spine.Unity {
return Vector2.zero; return Vector2.zero;
float start = time; float start = time;
float end = animation.duration; float end = animation.Duration;
return GetAnimationRootMotion(start, end, animation); return GetAnimationRootMotion(start, end, animation);
} }

View File

@ -63,7 +63,7 @@ namespace Spine.Unity {
var animation = track.Animation; var animation = track.Animation;
float start = track.AnimationTime; float start = track.AnimationTime;
float end = animation.duration; float end = animation.Duration;
return GetAnimationRootMotion(start, end, animation); return GetAnimationRootMotion(start, end, animation);
} }
@ -112,7 +112,7 @@ namespace Spine.Unity {
TrackEntry next = null; TrackEntry next = null;
while (track != null) { while (track != null) {
var animation = track.Animation; var animation = track.Animation;
float start = track.animationLast; float start = track.AnimationLast;
float end = track.AnimationTime; float end = track.AnimationTime;
var currentDelta = GetAnimationRootMotion(start, end, animation); var currentDelta = GetAnimationRootMotion(start, end, animation);
if (currentDelta != Vector2.zero) { if (currentDelta != Vector2.zero) {
@ -122,7 +122,7 @@ namespace Spine.Unity {
// Traverse mixingFrom chain. // Traverse mixingFrom chain.
next = track; next = track;
track = track.mixingFrom; track = track.MixingFrom;
} }
} }
return localDelta; return localDelta;
@ -132,19 +132,19 @@ namespace Spine.Unity {
// Apply mix alpha to the delta position (based on AnimationState.cs). // Apply mix alpha to the delta position (based on AnimationState.cs).
float mix; float mix;
if (next != null) { if (next != null) {
if (next.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. if (next.MixDuration == 0) { // Single frame mix to undo mixingFrom changes.
mix = 1; mix = 1;
} else { } else {
mix = next.mixTime / next.mixDuration; mix = next.MixTime / next.MixDuration;
if (mix > 1) mix = 1; if (mix > 1) mix = 1;
} }
float mixAndAlpha = track.alpha * next.interruptAlpha * (1 - mix); float mixAndAlpha = track.Alpha * next.InterruptAlpha * (1 - mix);
currentDelta *= mixAndAlpha; currentDelta *= mixAndAlpha;
} else { } else {
if (track.mixDuration == 0) { if (track.MixDuration == 0) {
mix = 1; mix = 1;
} else { } else {
mix = track.alpha * (track.mixTime / track.mixDuration); mix = track.Alpha * (track.MixTime / track.MixDuration);
if (mix > 1) mix = 1; if (mix > 1) mix = 1;
} }
currentDelta *= mix; currentDelta *= mix;

View File

@ -80,7 +80,7 @@ namespace Spine.Unity {
GatherTopLevelBones(); GatherTopLevelBones();
SetRootMotionBone(rootMotionBoneName); SetRootMotionBone(rootMotionBoneName);
if (rootMotionBone != null) if (rootMotionBone != null)
initialOffset = new Vector2(rootMotionBone.x, rootMotionBone.y); initialOffset = new Vector2(rootMotionBone.X, rootMotionBone.Y);
var skeletonAnimation = skeletonComponent as ISkeletonAnimation; var skeletonAnimation = skeletonComponent as ISkeletonAnimation;
if (skeletonAnimation != null) { if (skeletonAnimation != null) {
@ -190,7 +190,7 @@ namespace Spine.Unity {
} }
public Vector2 GetAnimationRootMotion (Animation animation) { public Vector2 GetAnimationRootMotion (Animation animation) {
return GetAnimationRootMotion(0, animation.duration, animation); return GetAnimationRootMotion(0, animation.Duration, animation);
} }
public Vector2 GetAnimationRootMotion (float startTime, float endTime, public Vector2 GetAnimationRootMotion (float startTime, float endTime,
@ -207,7 +207,7 @@ namespace Spine.Unity {
RootMotionInfo rootMotion = new RootMotionInfo(); RootMotionInfo rootMotion = new RootMotionInfo();
var timeline = animation.FindTranslateTimelineForBone(rootMotionBoneIndex); var timeline = animation.FindTranslateTimelineForBone(rootMotionBoneIndex);
if (timeline != null) { if (timeline != null) {
float duration = animation.duration; float duration = animation.Duration;
float mid = duration * 0.5f; float mid = duration * 0.5f;
rootMotion.start = timeline.Evaluate(0); rootMotion.start = timeline.Evaluate(0);
rootMotion.current = timeline.Evaluate(currentTime); rootMotion.current = timeline.Evaluate(currentTime);
@ -223,7 +223,7 @@ namespace Spine.Unity {
Vector2 currentDelta; Vector2 currentDelta;
if (startTime > endTime) // Looped if (startTime > endTime) // Looped
currentDelta = (timeline.Evaluate(animation.duration) - timeline.Evaluate(startTime)) currentDelta = (timeline.Evaluate(animation.Duration) - timeline.Evaluate(startTime))
+ (timeline.Evaluate(endTime) - timeline.Evaluate(0)); + (timeline.Evaluate(endTime) - timeline.Evaluate(0));
else if (startTime != endTime) // Non-looped else if (startTime != endTime) // Non-looped
currentDelta = timeline.Evaluate(endTime) - timeline.Evaluate(startTime); currentDelta = timeline.Evaluate(endTime) - timeline.Evaluate(startTime);
@ -280,7 +280,7 @@ namespace Spine.Unity {
parentBoneScale = Vector2.one; parentBoneScale = Vector2.one;
Bone scaleBone = rootMotionBone; Bone scaleBone = rootMotionBone;
while ((scaleBone = scaleBone.parent) != null) { while ((scaleBone = scaleBone.Parent) != null) {
parentBoneScale.x *= scaleBone.ScaleX; parentBoneScale.x *= scaleBone.ScaleX;
parentBoneScale.y *= scaleBone.ScaleY; parentBoneScale.y *= scaleBone.ScaleY;
} }
@ -313,13 +313,13 @@ namespace Spine.Unity {
var skeleton = skeletonComponent.Skeleton; var skeleton = skeletonComponent.Skeleton;
foreach (var topLevelBone in topLevelBones) { foreach (var topLevelBone in topLevelBones) {
if (topLevelBone == rootMotionBone) { if (topLevelBone == rootMotionBone) {
if (transformPositionX) topLevelBone.x = displacementSkeletonSpace.x / skeleton.ScaleX; if (transformPositionX) topLevelBone.X = displacementSkeletonSpace.x / skeleton.ScaleX;
if (transformPositionY) topLevelBone.y = displacementSkeletonSpace.y / skeleton.ScaleY; if (transformPositionY) topLevelBone.Y = displacementSkeletonSpace.y / skeleton.ScaleY;
} else { } else {
float offsetX = (initialOffset.x - rootMotionBone.x) * parentBoneScale.x; float offsetX = (initialOffset.x - rootMotionBone.X) * parentBoneScale.x;
float offsetY = (initialOffset.y - rootMotionBone.y) * parentBoneScale.y; float offsetY = (initialOffset.y - rootMotionBone.Y) * parentBoneScale.y;
if (transformPositionX) topLevelBone.x = (displacementSkeletonSpace.x / skeleton.ScaleX) + offsetX; if (transformPositionX) topLevelBone.X = (displacementSkeletonSpace.x / skeleton.ScaleX) + offsetX;
if (transformPositionY) topLevelBone.y = (displacementSkeletonSpace.y / skeleton.ScaleY) + offsetY; if (transformPositionY) topLevelBone.Y = (displacementSkeletonSpace.y / skeleton.ScaleY) + offsetY;
} }
} }
} }

View File

@ -113,7 +113,7 @@ namespace Spine.Unity {
Initialize(false); Initialize(false);
if (_animationName == value) { if (_animationName == value) {
TrackEntry entry = state.GetCurrent(0); TrackEntry entry = state.GetCurrent(0);
if (entry != null && entry.loop == loop) if (entry != null && entry.Loop == loop)
return; return;
} }
_animationName = value; _animationName = value;

View File

@ -108,7 +108,7 @@ namespace Spine.Unity {
Clear(); Clear();
} else if (skeletonDataAsset.skeletonJSON == null) { } else if (skeletonDataAsset.skeletonJSON == null) {
Clear(); Clear();
} else if (skeletonDataAsset.GetSkeletonData(true) != skeleton.data) { } else if (skeletonDataAsset.GetSkeletonData(true) != skeleton.Data) {
Clear(); Clear();
Initialize(true); Initialize(true);
if (!allowMultipleCanvasRenderers && (skeletonDataAsset.atlasAssets.Length > 1 || skeletonDataAsset.atlasAssets[0].MaterialCount > 1)) if (!allowMultipleCanvasRenderers && (skeletonDataAsset.atlasAssets.Length > 1 || skeletonDataAsset.atlasAssets[0].MaterialCount > 1))
@ -117,9 +117,9 @@ namespace Spine.Unity {
if (freeze) return; if (freeze) return;
if (!string.IsNullOrEmpty(initialSkinName)) { if (!string.IsNullOrEmpty(initialSkinName)) {
var skin = skeleton.data.FindSkin(initialSkinName); var skin = skeleton.Data.FindSkin(initialSkinName);
if (skin != null) { if (skin != null) {
if (skin == skeleton.data.defaultSkin) if (skin == skeleton.Data.DefaultSkin)
skeleton.SetSkin((Skin)null); skeleton.SetSkin((Skin)null);
else else
skeleton.SetSkin(skin); skeleton.SetSkin(skin);
@ -378,7 +378,7 @@ namespace Spine.Unity {
skeleton = value; skeleton = value;
} }
} }
public SkeletonData SkeletonData { get { return skeleton == null ? null : skeleton.data; } } public SkeletonData SkeletonData { get { return skeleton == null ? null : skeleton.Data; } }
public bool IsValid { get { return skeleton != null; } } public bool IsValid { get { return skeleton != null; } }
public delegate void SkeletonRendererDelegate (SkeletonGraphic skeletonGraphic); public delegate void SkeletonRendererDelegate (SkeletonGraphic skeletonGraphic);

View File

@ -270,9 +270,10 @@ namespace Spine.Unity {
float speedFactor = stateInfo.speedMultiplier * stateInfo.speed; float speedFactor = stateInfo.speedMultiplier * stateInfo.speed;
float lastTime = time - (Time.deltaTime * speedFactor); float lastTime = time - (Time.deltaTime * speedFactor);
if (isLooping && clip.duration != 0) { float clipDuration = clip.Duration;
time %= clip.duration; if (isLooping && clipDuration != 0) {
lastTime %= clip.duration; time %= clipDuration;
lastTime %= clipDuration;
} }
_OnClipApplied(clip, layerIndex, weight, time, lastTime, speedFactor < 0); _OnClipApplied(clip, layerIndex, weight, time, lastTime, speedFactor < 0);
} }

View File

@ -582,16 +582,16 @@ namespace Spine.Unity {
if (clearExistingSeparators) if (clearExistingSeparators)
separatorSlots.Clear(); separatorSlots.Clear();
var slots = skeleton.slots; var slots = skeleton.Slots;
foreach (var slot in slots) { foreach (var slot in slots) {
if (slotNamePredicate.Invoke(slot.data.name)) if (slotNamePredicate.Invoke(slot.Data.Name))
separatorSlots.Add(slot); separatorSlots.Add(slot);
} }
if (updateStringArray) { if (updateStringArray) {
var detectedSeparatorNames = new List<string>(); var detectedSeparatorNames = new List<string>();
foreach (var slot in skeleton.slots) { foreach (var slot in skeleton.Slots) {
string slotName = slot.data.name; string slotName = slot.Data.Name;
if (slotNamePredicate.Invoke(slotName)) if (slotNamePredicate.Invoke(slotName))
detectedSeparatorNames.Add(slotName); detectedSeparatorNames.Add(slotName);
} }

View File

@ -47,7 +47,7 @@ namespace Spine.Unity {
#region BoundingBoxAttachment #region BoundingBoxAttachment
public static PolygonCollider2D AddBoundingBoxGameObject (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) { public static PolygonCollider2D AddBoundingBoxGameObject (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) {
Skin skin = string.IsNullOrEmpty(skinName) ? skeleton.data.defaultSkin : skeleton.data.FindSkin(skinName); Skin skin = string.IsNullOrEmpty(skinName) ? skeleton.Data.DefaultSkin : skeleton.Data.FindSkin(skinName);
if (skin == null) { if (skin == null) {
Debug.LogError("Skin " + skinName + " not found!"); Debug.LogError("Skin " + skinName + " not found!");
return null; return null;
@ -55,7 +55,7 @@ namespace Spine.Unity {
var attachment = skin.GetAttachment(skeleton.Data.FindSlot(slotName).Index, attachmentName); var attachment = skin.GetAttachment(skeleton.Data.FindSlot(slotName).Index, attachmentName);
if (attachment == null) { if (attachment == null) {
Debug.LogFormat("Attachment in slot '{0}' named '{1}' not found in skin '{2}'.", slotName, attachmentName, skin.name); Debug.LogFormat("Attachment in slot '{0}' named '{1}' not found in skin '{2}'.", slotName, attachmentName, skin.Name);
return null; return null;
} }
@ -310,11 +310,11 @@ namespace Spine.Unity {
var constraintTargets = new List<System.Object>(); var constraintTargets = new List<System.Object>();
var ikConstraints = skeleton.IkConstraints; var ikConstraints = skeleton.IkConstraints;
for (int i = 0, n = ikConstraints.Count; i < n; i++) for (int i = 0, n = ikConstraints.Count; i < n; i++)
constraintTargets.Add(ikConstraints.Items[i].target); constraintTargets.Add(ikConstraints.Items[i].Target);
var transformConstraints = skeleton.TransformConstraints; var transformConstraints = skeleton.TransformConstraints;
for (int i = 0, n = transformConstraints.Count; i < n; i++) for (int i = 0, n = transformConstraints.Count; i < n; i++)
constraintTargets.Add(transformConstraints.Items[i].target); constraintTargets.Add(transformConstraints.Items[i].Target);
var boneComponents = this.boneComponents; var boneComponents = this.boneComponents;
for (int i = 0, n = boneComponents.Count; i < n; i++) { for (int i = 0, n = boneComponents.Count; i < n; i++) {
@ -456,7 +456,7 @@ namespace Spine.Unity {
if (mode == SkeletonUtilityBone.Mode.Override) { if (mode == SkeletonUtilityBone.Mode.Override) {
if (rot) goTransform.localRotation = Quaternion.Euler(0, 0, b.bone.AppliedRotation); if (rot) goTransform.localRotation = Quaternion.Euler(0, 0, b.bone.AppliedRotation);
if (pos) goTransform.localPosition = new Vector3(b.bone.X * positionScale, b.bone.Y * positionScale, 0); if (pos) goTransform.localPosition = new Vector3(b.bone.X * positionScale, b.bone.Y * positionScale, 0);
goTransform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0); goTransform.localScale = new Vector3(b.bone.ScaleX, b.bone.ScaleY, 0);
} }
return go; return go;

View File

@ -130,11 +130,11 @@ namespace Spine.Unity {
switch (phase) { switch (phase) {
case UpdatePhase.Local: case UpdatePhase.Local:
if (position) if (position)
thisTransform.localPosition = new Vector3(bone.x * positionScale, bone.y * positionScale, 0); thisTransform.localPosition = new Vector3(bone.X * positionScale, bone.Y * positionScale, 0);
if (rotation) { if (rotation) {
if (bone.data.transformMode.InheritsRotation()) { if (bone.Data.TransformMode.InheritsRotation()) {
thisTransform.localRotation = Quaternion.Euler(0, 0, bone.rotation); thisTransform.localRotation = Quaternion.Euler(0, 0, bone.Rotation);
} else { } else {
Vector3 euler = skeletonTransform.rotation.eulerAngles; Vector3 euler = skeletonTransform.rotation.eulerAngles;
thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation)); thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
@ -142,17 +142,17 @@ namespace Spine.Unity {
} }
if (scale) { if (scale) {
thisTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1f); thisTransform.localScale = new Vector3(bone.ScaleX, bone.ScaleY, 1f);
incompatibleTransformMode = BoneTransformModeIncompatible(bone); incompatibleTransformMode = BoneTransformModeIncompatible(bone);
} }
break; break;
case UpdatePhase.World: case UpdatePhase.World:
case UpdatePhase.Complete: case UpdatePhase.Complete:
if (position) if (position)
thisTransform.localPosition = new Vector3(bone.ax * positionScale, bone.ay * positionScale, 0); thisTransform.localPosition = new Vector3(bone.AX * positionScale, bone.AY * positionScale, 0);
if (rotation) { if (rotation) {
if (bone.data.transformMode.InheritsRotation()) { if (bone.Data.TransformMode.InheritsRotation()) {
thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation); thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
} else { } else {
Vector3 euler = skeletonTransform.rotation.eulerAngles; Vector3 euler = skeletonTransform.rotation.eulerAngles;
@ -161,7 +161,7 @@ namespace Spine.Unity {
} }
if (scale) { if (scale) {
thisTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f); thisTransform.localScale = new Vector3(bone.AScaleX, bone.AScaleY, 1f);
incompatibleTransformMode = BoneTransformModeIncompatible(bone); incompatibleTransformMode = BoneTransformModeIncompatible(bone);
} }
break; break;
@ -174,8 +174,8 @@ namespace Spine.Unity {
if (parentReference == null) { if (parentReference == null) {
if (position) { if (position) {
Vector3 clp = thisTransform.localPosition / positionScale; Vector3 clp = thisTransform.localPosition / positionScale;
bone.x = Mathf.Lerp(bone.x, clp.x, overrideAlpha); bone.X = Mathf.Lerp(bone.X, clp.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, clp.y, overrideAlpha); bone.Y = Mathf.Lerp(bone.Y, clp.y, overrideAlpha);
} }
if (rotation) { if (rotation) {
@ -186,8 +186,8 @@ namespace Spine.Unity {
if (scale) { if (scale) {
Vector3 cls = thisTransform.localScale; Vector3 cls = thisTransform.localScale;
bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha); bone.ScaleX = Mathf.Lerp(bone.ScaleX, cls.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha); bone.ScaleY = Mathf.Lerp(bone.ScaleY, cls.y, overrideAlpha);
} }
} else { } else {
@ -196,8 +196,8 @@ namespace Spine.Unity {
if (position) { if (position) {
Vector3 pos = parentReference.InverseTransformPoint(thisTransform.position) / positionScale; Vector3 pos = parentReference.InverseTransformPoint(thisTransform.position) / positionScale;
bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha); bone.X = Mathf.Lerp(bone.X, pos.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha); bone.Y = Mathf.Lerp(bone.Y, pos.y, overrideAlpha);
} }
if (rotation) { if (rotation) {
@ -208,8 +208,8 @@ namespace Spine.Unity {
if (scale) { if (scale) {
Vector3 cls = thisTransform.localScale; Vector3 cls = thisTransform.localScale;
bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha); bone.ScaleX = Mathf.Lerp(bone.ScaleX, cls.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha); bone.ScaleY = Mathf.Lerp(bone.ScaleY, cls.y, overrideAlpha);
} }
incompatibleTransformMode = BoneTransformModeIncompatible(bone); incompatibleTransformMode = BoneTransformModeIncompatible(bone);
@ -220,12 +220,12 @@ namespace Spine.Unity {
} }
public static bool BoneTransformModeIncompatible (Bone bone) { public static bool BoneTransformModeIncompatible (Bone bone) {
return !bone.data.transformMode.InheritsScale(); return !bone.Data.TransformMode.InheritsScale();
} }
public void AddBoundingBox (string skinName, string slotName, string attachmentName) { public void AddBoundingBox (string skinName, string slotName, string attachmentName) {
SkeletonUtility.AddBoneRigidbody2D(transform.gameObject); SkeletonUtility.AddBoneRigidbody2D(transform.gameObject);
SkeletonUtility.AddBoundingBoxGameObject(bone.skeleton, skinName, slotName, attachmentName, transform); SkeletonUtility.AddBoundingBoxGameObject(bone.Skeleton, skinName, slotName, attachmentName, transform);
} }
#if UNITY_EDITOR #if UNITY_EDITOR

View File

@ -149,7 +149,7 @@ namespace Spine.Unity {
/// <param name="material">Material to be set at the renderer instruction. When null, the last attachment /// <param name="material">Material to be set at the renderer instruction. When null, the last attachment
/// in the draw order list is assigned as the instruction's material.</param> /// in the draw order list is assigned as the instruction's material.</param>
public static void GenerateSingleSubmeshInstruction (SkeletonRendererInstruction instructionOutput, Skeleton skeleton, Material material) { public static void GenerateSingleSubmeshInstruction (SkeletonRendererInstruction instructionOutput, Skeleton skeleton, Material material) {
ExposedList<Slot> drawOrder = skeleton.drawOrder; ExposedList<Slot> drawOrder = skeleton.DrawOrder;
int drawOrderCount = drawOrder.Count; int drawOrderCount = drawOrder.Count;
// Clear last state of attachments and submeshes // Clear last state of attachments and submeshes
@ -180,9 +180,9 @@ namespace Spine.Unity {
var drawOrderItems = drawOrder.Items; var drawOrderItems = drawOrder.Items;
for (int i = 0; i < drawOrderCount; i++) { for (int i = 0; i < drawOrderCount; i++) {
Slot slot = drawOrderItems[i]; Slot slot = drawOrderItems[i];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
if (slot.data.blendMode == BlendMode.Additive) current.hasPMAAdditiveSlot = true; if (slot.Data.BlendMode == BlendMode.Additive) current.hasPMAAdditiveSlot = true;
Attachment attachment = slot.attachment; Attachment attachment = slot.Attachment;
workingAttachmentsItems[i] = attachment; workingAttachmentsItems[i] = attachment;
int attachmentTriangleCount; int attachmentTriangleCount;
@ -197,8 +197,8 @@ namespace Spine.Unity {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
rendererObject = meshAttachment.RendererObject; rendererObject = meshAttachment.RendererObject;
attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1;
attachmentTriangleCount = meshAttachment.triangles.Length; attachmentTriangleCount = meshAttachment.Triangles.Length;
} else { } else {
var clippingAttachment = attachment as ClippingAttachment; var clippingAttachment = attachment as ClippingAttachment;
if (clippingAttachment != null) { if (clippingAttachment != null) {
@ -239,15 +239,15 @@ namespace Spine.Unity {
#if SPINE_TK2D #if SPINE_TK2D
return false; return false;
#endif #endif
ExposedList<Slot> drawOrder = skeleton.drawOrder; ExposedList<Slot> drawOrder = skeleton.DrawOrder;
int drawOrderCount = drawOrder.Count; int drawOrderCount = drawOrder.Count;
var drawOrderItems = drawOrder.Items; var drawOrderItems = drawOrder.Items;
Material lastRendererMaterial = null; Material lastRendererMaterial = null;
for (int i = 0; i < drawOrderCount; i++) { for (int i = 0; i < drawOrderCount; i++) {
Slot slot = drawOrderItems[i]; Slot slot = drawOrderItems[i];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
Attachment attachment = slot.attachment; Attachment attachment = slot.Attachment;
var rendererAttachment = attachment as IHasRendererObject; var rendererAttachment = attachment as IHasRendererObject;
if (rendererAttachment != null) { if (rendererAttachment != null) {
AtlasRegion atlasRegion = (AtlasRegion)rendererAttachment.RendererObject; AtlasRegion atlasRegion = (AtlasRegion)rendererAttachment.RendererObject;
@ -267,7 +267,7 @@ namespace Spine.Unity {
// if (skeleton == null) throw new ArgumentNullException("skeleton"); // if (skeleton == null) throw new ArgumentNullException("skeleton");
// if (instructionOutput == null) throw new ArgumentNullException("instructionOutput"); // if (instructionOutput == null) throw new ArgumentNullException("instructionOutput");
ExposedList<Slot> drawOrder = skeleton.drawOrder; ExposedList<Slot> drawOrder = skeleton.DrawOrder;
int drawOrderCount = drawOrder.Count; int drawOrderCount = drawOrder.Count;
// Clear last state of attachments and submeshes // Clear last state of attachments and submeshes
@ -299,9 +299,9 @@ namespace Spine.Unity {
var drawOrderItems = drawOrder.Items; var drawOrderItems = drawOrder.Items;
for (int i = 0; i < drawOrderCount; i++) { for (int i = 0; i < drawOrderCount; i++) {
Slot slot = drawOrderItems[i]; Slot slot = drawOrderItems[i];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
if (slot.data.blendMode == BlendMode.Additive) current.hasPMAAdditiveSlot = true; if (slot.Data.BlendMode == BlendMode.Additive) current.hasPMAAdditiveSlot = true;
Attachment attachment = slot.attachment; Attachment attachment = slot.Attachment;
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
workingAttachmentsItems[i] = attachment; workingAttachmentsItems[i] = attachment;
int attachmentVertexCount = 0, attachmentTriangleCount = 0; int attachmentVertexCount = 0, attachmentTriangleCount = 0;
@ -322,14 +322,14 @@ namespace Spine.Unity {
if (meshAttachment != null) { if (meshAttachment != null) {
rendererObject = meshAttachment.RendererObject; rendererObject = meshAttachment.RendererObject;
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1;
attachmentTriangleCount = meshAttachment.triangles.Length; attachmentTriangleCount = meshAttachment.Triangles.Length;
#endif #endif
} else { } else {
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
var clippingAttachment = attachment as ClippingAttachment; var clippingAttachment = attachment as ClippingAttachment;
if (clippingAttachment != null) { if (clippingAttachment != null) {
clippingEndSlot = clippingAttachment.endSlot; clippingEndSlot = clippingAttachment.EndSlot;
clippingAttachmentSource = i; clippingAttachmentSource = i;
current.hasClipping = true; current.hasClipping = true;
skeletonHasClipping = true; skeletonHasClipping = true;
@ -414,7 +414,7 @@ namespace Spine.Unity {
#endif #endif
} }
if (clippingEndSlot != null && slot.data == clippingEndSlot && i != clippingAttachmentSource) { if (clippingEndSlot != null && slot.Data == clippingEndSlot && i != clippingAttachmentSource) {
clippingEndSlot = null; clippingEndSlot = null;
clippingAttachmentSource = -1; clippingAttachmentSource = -1;
} }
@ -486,10 +486,10 @@ namespace Spine.Unity {
submesh.Clear(false); submesh.Clear(false);
var skeleton = instruction.skeleton; var skeleton = instruction.skeleton;
var drawOrderItems = skeleton.drawOrder.Items; var drawOrderItems = skeleton.DrawOrder.Items;
Color32 color = default(Color32); Color32 color = default(Color32);
float skeletonA = skeleton.a, skeletonR = skeleton.r, skeletonG = skeleton.g, skeletonB = skeleton.b; float skeletonA = skeleton.A, skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B;
Vector2 meshBoundsMin = this.meshBoundsMin, meshBoundsMax = this.meshBoundsMax; Vector2 meshBoundsMin = this.meshBoundsMin, meshBoundsMax = this.meshBoundsMax;
// Settings // Settings
@ -506,17 +506,17 @@ namespace Spine.Unity {
if (useClipping) { if (useClipping) {
if (instruction.preActiveClippingSlotSource >= 0) { if (instruction.preActiveClippingSlotSource >= 0) {
var slot = drawOrderItems[instruction.preActiveClippingSlotSource]; var slot = drawOrderItems[instruction.preActiveClippingSlotSource];
clipper.ClipStart(slot, slot.attachment as ClippingAttachment); clipper.ClipStart(slot, slot.Attachment as ClippingAttachment);
} }
} }
for (int slotIndex = instruction.startSlot; slotIndex < instruction.endSlot; slotIndex++) { for (int slotIndex = instruction.startSlot; slotIndex < instruction.endSlot; slotIndex++) {
var slot = drawOrderItems[slotIndex]; var slot = drawOrderItems[slotIndex];
if (!slot.bone.active) { if (!slot.Bone.Active) {
clipper.ClipEnd(slot); clipper.ClipEnd(slot);
continue; continue;
} }
var attachment = slot.attachment; var attachment = slot.Attachment;
float z = zSpacing * slotIndex; float z = zSpacing * slotIndex;
var workingVerts = this.tempVerts; var workingVerts = this.tempVerts;
@ -530,26 +530,26 @@ namespace Spine.Unity {
// Identify and prepare values. // Identify and prepare values.
var region = attachment as RegionAttachment; var region = attachment as RegionAttachment;
if (region != null) { if (region != null) {
region.ComputeWorldVertices(slot.bone, workingVerts, 0); region.ComputeWorldVertices(slot.Bone, workingVerts, 0);
uvs = region.uvs; uvs = region.UVs;
attachmentTriangleIndices = regionTriangles; attachmentTriangleIndices = regionTriangles;
c.r = region.r; c.g = region.g; c.b = region.b; c.a = region.a; c.r = region.R; c.g = region.G; c.b = region.B; c.a = region.A;
attachmentVertexCount = 4; attachmentVertexCount = 4;
attachmentIndexCount = 6; attachmentIndexCount = 6;
} else { } else {
var mesh = attachment as MeshAttachment; var mesh = attachment as MeshAttachment;
if (mesh != null) { if (mesh != null) {
int meshVerticesLength = mesh.worldVerticesLength; int meshVerticesLength = mesh.WorldVerticesLength;
if (workingVerts.Length < meshVerticesLength) { if (workingVerts.Length < meshVerticesLength) {
workingVerts = new float[meshVerticesLength]; workingVerts = new float[meshVerticesLength];
this.tempVerts = workingVerts; this.tempVerts = workingVerts;
} }
mesh.ComputeWorldVertices(slot, 0, meshVerticesLength, workingVerts, 0); //meshAttachment.ComputeWorldVertices(slot, tempVerts); mesh.ComputeWorldVertices(slot, 0, meshVerticesLength, workingVerts, 0); //meshAttachment.ComputeWorldVertices(slot, tempVerts);
uvs = mesh.uvs; uvs = mesh.UVs;
attachmentTriangleIndices = mesh.triangles; attachmentTriangleIndices = mesh.Triangles;
c.r = mesh.r; c.g = mesh.g; c.b = mesh.b; c.a = mesh.a; c.r = mesh.R; c.g = mesh.G; c.b = mesh.B; c.a = mesh.A;
attachmentVertexCount = meshVerticesLength >> 1; // meshVertexCount / 2; attachmentVertexCount = meshVerticesLength >> 1; // meshVertexCount / 2;
attachmentIndexCount = mesh.triangles.Length; attachmentIndexCount = mesh.Triangles.Length;
} else { } else {
if (useClipping) { if (useClipping) {
var clippingAttachment = attachment as ClippingAttachment; var clippingAttachment = attachment as ClippingAttachment;
@ -567,12 +567,12 @@ namespace Spine.Unity {
float tintBlackAlpha = 1.0f; float tintBlackAlpha = 1.0f;
if (pmaVertexColors) { if (pmaVertexColors) {
float colorA = skeletonA * slot.a * c.a; float colorA = skeletonA * slot.A * c.a;
color.a = (byte)(colorA * 255); color.a = (byte)(colorA * 255);
color.r = (byte)(skeletonR * slot.r * c.r * color.a); color.r = (byte)(skeletonR * slot.R * c.r * color.a);
color.g = (byte)(skeletonG * slot.g * c.g * color.a); color.g = (byte)(skeletonG * slot.G * c.g * color.a);
color.b = (byte)(skeletonB * slot.b * c.b * color.a); color.b = (byte)(skeletonB * slot.B * c.b * color.a);
if (slot.data.blendMode == BlendMode.Additive) { if (slot.Data.BlendMode == BlendMode.Additive) {
if (canvasGroupTintBlack) if (canvasGroupTintBlack)
tintBlackAlpha = 0; tintBlackAlpha = 0;
else else
@ -581,29 +581,29 @@ namespace Spine.Unity {
tintBlackAlpha = colorA; tintBlackAlpha = colorA;
} }
} else { } else {
color.a = (byte)(skeletonA * slot.a * c.a * 255); color.a = (byte)(skeletonA * slot.A * c.a * 255);
color.r = (byte)(skeletonR * slot.r * c.r * 255); color.r = (byte)(skeletonR * slot.R * c.r * 255);
color.g = (byte)(skeletonG * slot.g * c.g * 255); color.g = (byte)(skeletonG * slot.G * c.g * 255);
color.b = (byte)(skeletonB * slot.b * c.b * 255); color.b = (byte)(skeletonB * slot.B * c.b * 255);
} }
if (useClipping && clipper.IsClipping) { if (useClipping && clipper.IsClipping) {
clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs); clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs);
workingVerts = clipper.clippedVertices.Items; workingVerts = clipper.ClippedVertices.Items;
attachmentVertexCount = clipper.clippedVertices.Count >> 1; attachmentVertexCount = clipper.ClippedVertices.Count >> 1;
attachmentTriangleIndices = clipper.clippedTriangles.Items; attachmentTriangleIndices = clipper.ClippedTriangles.Items;
attachmentIndexCount = clipper.clippedTriangles.Count; attachmentIndexCount = clipper.ClippedTriangles.Count;
uvs = clipper.clippedUVs.Items; uvs = clipper.ClippedUVs.Items;
} }
// Actually add slot/attachment data into buffers. // Actually add slot/attachment data into buffers.
if (attachmentVertexCount != 0 && attachmentIndexCount != 0) { if (attachmentVertexCount != 0 && attachmentIndexCount != 0) {
if (tintBlack) { if (tintBlack) {
float r2 = slot.r2; float r2 = slot.R2;
float g2 = slot.g2; float g2 = slot.G2;
float b2 = slot.b2; float b2 = slot.B2;
if (pmaVertexColors) { if (pmaVertexColors) {
float alpha = skeletonA * slot.a * c.a; float alpha = skeletonA * slot.A * c.a;
r2 *= alpha; r2 *= alpha;
g2 *= alpha; g2 *= alpha;
b2 *= alpha; b2 *= alpha;
@ -742,8 +742,8 @@ namespace Spine.Unity {
for (int si = 0, n = instruction.submeshInstructions.Count; si < n; si++) { for (int si = 0, n = instruction.submeshInstructions.Count; si < n; si++) {
var submesh = instruction.submeshInstructions.Items[si]; var submesh = instruction.submeshInstructions.Items[si];
var skeleton = submesh.skeleton; var skeleton = submesh.skeleton;
var drawOrderItems = skeleton.drawOrder.Items; var drawOrderItems = skeleton.DrawOrder.Items;
float a = skeleton.a, r = skeleton.r, g = skeleton.g, b = skeleton.b; float a = skeleton.A, r = skeleton.R, g = skeleton.G, b = skeleton.B;
int endSlot = submesh.endSlot; int endSlot = submesh.endSlot;
int startSlot = submesh.startSlot; int startSlot = submesh.startSlot;
@ -771,22 +771,22 @@ namespace Spine.Unity {
for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) { for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) {
var slot = drawOrderItems[slotIndex]; var slot = drawOrderItems[slotIndex];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
var attachment = slot.attachment; var attachment = slot.Attachment;
rg.x = slot.r2; //r rg.x = slot.R2; //r
rg.y = slot.g2; //g rg.y = slot.G2; //g
b2.x = slot.b2; //b b2.x = slot.B2; //b
b2.y = 1.0f; b2.y = 1.0f;
var regionAttachment = attachment as RegionAttachment; var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
if (settings.pmaVertexColors) { if (settings.pmaVertexColors) {
float alpha = a * slot.a * regionAttachment.a; float alpha = a * slot.A * regionAttachment.A;
rg.x *= alpha; rg.x *= alpha;
rg.y *= alpha; rg.y *= alpha;
b2.x *= alpha; b2.x *= alpha;
b2.y = slot.data.blendMode == BlendMode.Additive ? 0 : alpha; b2.y = slot.Data.BlendMode == BlendMode.Additive ? 0 : alpha;
} }
uv2i[vi] = rg; uv2i[vi + 1] = rg; uv2i[vi + 2] = rg; uv2i[vi + 3] = rg; uv2i[vi] = rg; uv2i[vi + 1] = rg; uv2i[vi + 2] = rg; uv2i[vi + 3] = rg;
uv3i[vi] = b2; uv3i[vi + 1] = b2; uv3i[vi + 2] = b2; uv3i[vi + 3] = b2; uv3i[vi] = b2; uv3i[vi + 1] = b2; uv3i[vi + 2] = b2; uv3i[vi + 3] = b2;
@ -795,13 +795,13 @@ namespace Spine.Unity {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
if (settings.pmaVertexColors) { if (settings.pmaVertexColors) {
float alpha = a * slot.a * meshAttachment.a; float alpha = a * slot.A * meshAttachment.A;
rg.x *= alpha; rg.x *= alpha;
rg.y *= alpha; rg.y *= alpha;
b2.x *= alpha; b2.x *= alpha;
b2.y = slot.data.blendMode == BlendMode.Additive ? 0 : alpha; b2.y = slot.Data.BlendMode == BlendMode.Additive ? 0 : alpha;
} }
int meshVertexCount = meshAttachment.worldVerticesLength; int meshVertexCount = meshAttachment.WorldVerticesLength;
for (int iii = 0; iii < meshVertexCount; iii += 2) { for (int iii = 0; iii < meshVertexCount; iii += 2) {
uv2i[vi] = rg; uv2i[vi] = rg;
uv3i[vi] = b2; uv3i[vi] = b2;
@ -814,13 +814,13 @@ namespace Spine.Unity {
for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) { for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) {
var slot = drawOrderItems[slotIndex]; var slot = drawOrderItems[slotIndex];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
var attachment = slot.attachment; var attachment = slot.Attachment;
float z = slotIndex * settings.zSpacing; float z = slotIndex * settings.zSpacing;
var regionAttachment = attachment as RegionAttachment; var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
regionAttachment.ComputeWorldVertices(slot.bone, tempVerts, 0); regionAttachment.ComputeWorldVertices(slot.Bone, tempVerts, 0);
float x1 = tempVerts[RegionAttachment.BLX], y1 = tempVerts[RegionAttachment.BLY]; float x1 = tempVerts[RegionAttachment.BLX], y1 = tempVerts[RegionAttachment.BLY];
float x2 = tempVerts[RegionAttachment.ULX], y2 = tempVerts[RegionAttachment.ULY]; float x2 = tempVerts[RegionAttachment.ULX], y2 = tempVerts[RegionAttachment.ULY];
@ -832,21 +832,21 @@ namespace Spine.Unity {
vbi[vertexIndex + 3].x = x3; vbi[vertexIndex + 3].y = y3; vbi[vertexIndex + 3].z = z; vbi[vertexIndex + 3].x = x3; vbi[vertexIndex + 3].y = y3; vbi[vertexIndex + 3].z = z;
if (settings.pmaVertexColors) { if (settings.pmaVertexColors) {
color.a = (byte)(a * slot.a * regionAttachment.a * 255); color.a = (byte)(a * slot.A * regionAttachment.A * 255);
color.r = (byte)(r * slot.r * regionAttachment.r * color.a); color.r = (byte)(r * slot.R * regionAttachment.R * color.a);
color.g = (byte)(g * slot.g * regionAttachment.g * color.a); color.g = (byte)(g * slot.G * regionAttachment.G * color.a);
color.b = (byte)(b * slot.b * regionAttachment.b * color.a); color.b = (byte)(b * slot.B * regionAttachment.B * color.a);
if (slot.data.blendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0; if (slot.Data.BlendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0;
} else { } else {
color.a = (byte)(a * slot.a * regionAttachment.a * 255); color.a = (byte)(a * slot.A * regionAttachment.A * 255);
color.r = (byte)(r * slot.r * regionAttachment.r * 255); color.r = (byte)(r * slot.R * regionAttachment.R * 255);
color.g = (byte)(g * slot.g * regionAttachment.g * 255); color.g = (byte)(g * slot.G * regionAttachment.G * 255);
color.b = (byte)(b * slot.b * regionAttachment.b * 255); color.b = (byte)(b * slot.B * regionAttachment.B * 255);
} }
cbi[vertexIndex] = color; cbi[vertexIndex + 1] = color; cbi[vertexIndex + 2] = color; cbi[vertexIndex + 3] = color; cbi[vertexIndex] = color; cbi[vertexIndex + 1] = color; cbi[vertexIndex + 2] = color; cbi[vertexIndex + 3] = color;
float[] regionUVs = regionAttachment.uvs; float[] regionUVs = regionAttachment.UVs;
ubi[vertexIndex].x = regionUVs[RegionAttachment.BLX]; ubi[vertexIndex].y = regionUVs[RegionAttachment.BLY]; ubi[vertexIndex].x = regionUVs[RegionAttachment.BLX]; ubi[vertexIndex].y = regionUVs[RegionAttachment.BLY];
ubi[vertexIndex + 1].x = regionUVs[RegionAttachment.BRX]; ubi[vertexIndex + 1].y = regionUVs[RegionAttachment.BRY]; ubi[vertexIndex + 1].x = regionUVs[RegionAttachment.BRX]; ubi[vertexIndex + 1].y = regionUVs[RegionAttachment.BRY];
ubi[vertexIndex + 2].x = regionUVs[RegionAttachment.ULX]; ubi[vertexIndex + 2].y = regionUVs[RegionAttachment.ULY]; ubi[vertexIndex + 2].x = regionUVs[RegionAttachment.ULX]; ubi[vertexIndex + 2].y = regionUVs[RegionAttachment.ULY];
@ -874,24 +874,24 @@ namespace Spine.Unity {
} else { //if (settings.renderMeshes) { } else { //if (settings.renderMeshes) {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
int meshVertexCount = meshAttachment.worldVerticesLength; int meshVertexCount = meshAttachment.WorldVerticesLength;
if (tempVerts.Length < meshVertexCount) this.tempVerts = tempVerts = new float[meshVertexCount]; if (tempVerts.Length < meshVertexCount) this.tempVerts = tempVerts = new float[meshVertexCount];
meshAttachment.ComputeWorldVertices(slot, tempVerts); meshAttachment.ComputeWorldVertices(slot, tempVerts);
if (settings.pmaVertexColors) { if (settings.pmaVertexColors) {
color.a = (byte)(a * slot.a * meshAttachment.a * 255); color.a = (byte)(a * slot.A * meshAttachment.A * 255);
color.r = (byte)(r * slot.r * meshAttachment.r * color.a); color.r = (byte)(r * slot.R * meshAttachment.R * color.a);
color.g = (byte)(g * slot.g * meshAttachment.g * color.a); color.g = (byte)(g * slot.G * meshAttachment.G * color.a);
color.b = (byte)(b * slot.b * meshAttachment.b * color.a); color.b = (byte)(b * slot.B * meshAttachment.B * color.a);
if (slot.data.blendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0; if (slot.Data.BlendMode == BlendMode.Additive && !canvasGroupTintBlack) color.a = 0;
} else { } else {
color.a = (byte)(a * slot.a * meshAttachment.a * 255); color.a = (byte)(a * slot.A * meshAttachment.A * 255);
color.r = (byte)(r * slot.r * meshAttachment.r * 255); color.r = (byte)(r * slot.R * meshAttachment.R * 255);
color.g = (byte)(g * slot.g * meshAttachment.g * 255); color.g = (byte)(g * slot.G * meshAttachment.G * 255);
color.b = (byte)(b * slot.b * meshAttachment.b * 255); color.b = (byte)(b * slot.B * meshAttachment.B * 255);
} }
float[] attachmentUVs = meshAttachment.uvs; float[] attachmentUVs = meshAttachment.UVs;
// Potential first attachment bounds initialization. See conditions in RegionAttachment logic. // Potential first attachment bounds initialization. See conditions in RegionAttachment logic.
if (vertexIndex == 0) { if (vertexIndex == 0) {
@ -967,12 +967,12 @@ namespace Spine.Unity {
var tris = currentSubmeshBuffer.Items; var tris = currentSubmeshBuffer.Items;
int triangleIndex = 0; int triangleIndex = 0;
var skeleton = submeshInstruction.skeleton; var skeleton = submeshInstruction.skeleton;
var drawOrderItems = skeleton.drawOrder.Items; var drawOrderItems = skeleton.DrawOrder.Items;
for (int slotIndex = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; slotIndex < endSlot; slotIndex++) { for (int slotIndex = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; slotIndex < endSlot; slotIndex++) {
var slot = drawOrderItems[slotIndex]; var slot = drawOrderItems[slotIndex];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
var attachment = drawOrderItems[slotIndex].attachment; var attachment = drawOrderItems[slotIndex].Attachment;
if (attachment is RegionAttachment) { if (attachment is RegionAttachment) {
tris[triangleIndex] = attachmentFirstVertex; tris[triangleIndex] = attachmentFirstVertex;
tris[triangleIndex + 1] = attachmentFirstVertex + 2; tris[triangleIndex + 1] = attachmentFirstVertex + 2;
@ -986,10 +986,10 @@ namespace Spine.Unity {
} }
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
int[] attachmentTriangles = meshAttachment.triangles; int[] attachmentTriangles = meshAttachment.Triangles;
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
tris[triangleIndex] = attachmentFirstVertex + attachmentTriangles[ii]; tris[triangleIndex] = attachmentFirstVertex + attachmentTriangles[ii];
attachmentFirstVertex += meshAttachment.worldVerticesLength >> 1; // length/2; attachmentFirstVertex += meshAttachment.WorldVerticesLength >> 1; // length/2;
} }
} }
} }
@ -1294,7 +1294,7 @@ namespace Spine.Unity {
AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.BLX], uvs[RegionAttachment.BLY])); AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.BLX], uvs[RegionAttachment.BLY]));
AttachmentColors32.Clear(); AttachmentColors32.Clear();
Color32 c = (Color32)(new Color(regionAttachment.r, regionAttachment.g, regionAttachment.b, regionAttachment.a)); Color32 c = (Color32)(new Color(regionAttachment.R, regionAttachment.G, regionAttachment.B, regionAttachment.A));
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
AttachmentColors32.Add(c); AttachmentColors32.Add(c);
@ -1323,16 +1323,16 @@ namespace Spine.Unity {
AttachmentVerts.Clear(); AttachmentVerts.Clear();
if (meshAttachment.IsWeighted()) { if (meshAttachment.IsWeighted()) {
int count = meshAttachment.WorldVerticesLength; int count = meshAttachment.WorldVerticesLength;
int[] meshAttachmentBones = meshAttachment.bones; int[] meshAttachmentBones = meshAttachment.Bones;
int v = 0; int v = 0;
float[] vertices = meshAttachment.vertices; float[] vertices = meshAttachment.Vertices;
for (int w = 0, b = 0; w < count; w += 2) { for (int w = 0, b = 0; w < count; w += 2) {
float wx = 0, wy = 0; float wx = 0, wy = 0;
int n = meshAttachmentBones[v++]; int n = meshAttachmentBones[v++];
n += v; n += v;
for (; v < n; v++, b += 3) { for (; v < n; v++, b += 3) {
BoneMatrix bm = BoneMatrix.CalculateSetupWorld(skeletonData.bones.Items[meshAttachmentBones[v]]); BoneMatrix bm = BoneMatrix.CalculateSetupWorld(skeletonData.Bones.Items[meshAttachmentBones[v]]);
float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
wx += (vx * bm.a + vy * bm.b + bm.x) * weight; wx += (vx * bm.a + vy * bm.b + bm.x) * weight;
wy += (vx * bm.c + vy * bm.d + bm.y) * weight; wy += (vx * bm.c + vy * bm.d + bm.y) * weight;
@ -1350,9 +1350,9 @@ namespace Spine.Unity {
} }
} }
var uvs = meshAttachment.uvs; var uvs = meshAttachment.UVs;
Vector2 uv = default(Vector2); Vector2 uv = default(Vector2);
Color32 c = (Color32)(new Color(meshAttachment.r, meshAttachment.g, meshAttachment.b, meshAttachment.a)); Color32 c = (Color32)(new Color(meshAttachment.R, meshAttachment.G, meshAttachment.B, meshAttachment.A));
AttachmentUVs.Clear(); AttachmentUVs.Clear();
AttachmentColors32.Clear(); AttachmentColors32.Clear();
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
@ -1365,7 +1365,7 @@ namespace Spine.Unity {
} }
AttachmentIndices.Clear(); AttachmentIndices.Clear();
AttachmentIndices.AddRange(meshAttachment.triangles); AttachmentIndices.AddRange(meshAttachment.Triangles);
mesh.Clear(); mesh.Clear();
mesh.name = meshAttachment.Name; mesh.name = meshAttachment.Name;

View File

@ -92,11 +92,11 @@ namespace Spine.Unity {
attachments.Resize(attachmentCount); attachments.Resize(attachmentCount);
var attachmentsItems = attachments.Items; var attachmentsItems = attachments.Items;
var drawOrderItems = instructionsItems[0].skeleton.drawOrder.Items; var drawOrderItems = instructionsItems[0].skeleton.DrawOrder.Items;
for (int i = 0; i < attachmentCount; i++) { for (int i = 0; i < attachmentCount; i++) {
Slot slot = drawOrderItems[startSlot + i]; Slot slot = drawOrderItems[startSlot + i];
if (!slot.bone.active) continue; if (!slot.Bone.Active) continue;
attachmentsItems[i] = slot.attachment; attachmentsItems[i] = slot.Attachment;
} }
#endif #endif

View File

@ -55,15 +55,15 @@ namespace Spine.Unity {
var slotsItems = skeletonData.Slots.Items; var slotsItems = skeletonData.Slots.Items;
for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) { for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) {
var slot = slotsItems[slotIndex]; var slot = slotsItems[slotIndex];
if (slot.blendMode == BlendMode.Normal) continue; if (slot.BlendMode == BlendMode.Normal) continue;
if (!includeAdditiveSlots && slot.blendMode == BlendMode.Additive) continue; if (!includeAdditiveSlots && slot.BlendMode == BlendMode.Additive) continue;
entryBuffer.Clear(); entryBuffer.Clear();
foreach (var skin in skeletonData.Skins) foreach (var skin in skeletonData.Skins)
skin.GetAttachments(slotIndex, entryBuffer); skin.GetAttachments(slotIndex, entryBuffer);
Material templateMaterial = null; Material templateMaterial = null;
switch (slot.blendMode) { switch (slot.BlendMode) {
case BlendMode.Multiply: case BlendMode.Multiply:
templateMaterial = multiplyTemplate; templateMaterial = multiplyTemplate;
break; break;

View File

@ -497,12 +497,12 @@ namespace Spine.Unity.AttachmentTools {
var skinAttachments = o.Attachments; var skinAttachments = o.Attachments;
var newSkin = new Skin(newName); var newSkin = new Skin(newName);
newSkin.bones.AddRange(o.bones); newSkin.Bones.AddRange(o.Bones);
newSkin.constraints.AddRange(o.constraints); newSkin.Constraints.AddRange(o.Constraints);
inoutAttachments.Clear(); inoutAttachments.Clear();
foreach (var entry in o.Attachments) { foreach (var entry in o.Attachments) {
inoutAttachments.Add(entry.attachment); inoutAttachments.Add(entry.Attachment);
} }
GetRepackedAttachments(inoutAttachments, inoutAttachments, materialPropertySource, out outputMaterial, out outputTexture, GetRepackedAttachments(inoutAttachments, inoutAttachments, materialPropertySource, out outputMaterial, out outputTexture,
maxAtlasSize, padding, textureFormat, mipmaps, newName, clearCache, useOriginalNonrenderables, maxAtlasSize, padding, textureFormat, mipmaps, newName, clearCache, useOriginalNonrenderables,

View File

@ -69,7 +69,7 @@ namespace Spine.Unity.AttachmentTools {
if (useOriginalRegionScale) { if (useOriginalRegionScale) {
var regionAttachment = o as RegionAttachment; var regionAttachment = o as RegionAttachment;
if (regionAttachment != null) if (regionAttachment != null)
scale = regionAttachment.width / regionAttachment.regionOriginalWidth; scale = regionAttachment.Width / regionAttachment.RegionOriginalWidth;
} }
return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, scale); return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, scale);
} }
@ -88,8 +88,8 @@ namespace Spine.Unity.AttachmentTools {
RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy(); RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy();
newAttachment.SetRegion(atlasRegion, false); newAttachment.SetRegion(atlasRegion, false);
if (!useOriginalRegionSize) { if (!useOriginalRegionSize) {
newAttachment.width = atlasRegion.width * scale; newAttachment.Width = atlasRegion.width * scale;
newAttachment.height = atlasRegion.height * scale; newAttachment.Height = atlasRegion.height * scale;
} }
newAttachment.UpdateOffset(); newAttachment.UpdateOffset();
return newAttachment; return newAttachment;

View File

@ -53,12 +53,12 @@ namespace Spine.Unity.AttachmentTools {
// (AtlasAttachmentLoader.cs) // (AtlasAttachmentLoader.cs)
attachment.RendererObject = region; attachment.RendererObject = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees); attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees);
attachment.regionOffsetX = region.offsetX; attachment.RegionOffsetX = region.offsetX;
attachment.regionOffsetY = region.offsetY; attachment.RegionOffsetY = region.offsetY;
attachment.regionWidth = region.width; attachment.RegionWidth = region.width;
attachment.regionHeight = region.height; attachment.RegionHeight = region.height;
attachment.regionOriginalWidth = region.originalWidth; attachment.RegionOriginalWidth = region.originalWidth;
attachment.regionOriginalHeight = region.originalHeight; attachment.RegionOriginalHeight = region.originalHeight;
if (updateOffset) attachment.UpdateOffset(); if (updateOffset) attachment.UpdateOffset();
} }
@ -74,12 +74,12 @@ namespace Spine.Unity.AttachmentTools {
attachment.RegionU2 = region.u2; attachment.RegionU2 = region.u2;
attachment.RegionV2 = region.v2; attachment.RegionV2 = region.v2;
attachment.RegionDegrees = region.degrees; attachment.RegionDegrees = region.degrees;
attachment.regionOffsetX = region.offsetX; attachment.RegionOffsetX = region.offsetX;
attachment.regionOffsetY = region.offsetY; attachment.RegionOffsetY = region.offsetY;
attachment.regionWidth = region.width; attachment.RegionWidth = region.width;
attachment.regionHeight = region.height; attachment.RegionHeight = region.height;
attachment.regionOriginalWidth = region.originalWidth; attachment.RegionOriginalWidth = region.originalWidth;
attachment.regionOriginalHeight = region.originalHeight; attachment.RegionOriginalHeight = region.originalHeight;
if (updateUVs) attachment.UpdateUVs(); if (updateUVs) attachment.UpdateUVs();
} }
@ -130,26 +130,26 @@ namespace Spine.Unity.AttachmentTools {
attachment.RendererObject = region; attachment.RendererObject = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees); attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees);
attachment.regionOffsetX = region.offsetX; attachment.RegionOffsetX = region.offsetX;
attachment.regionOffsetY = region.offsetY; attachment.RegionOffsetY = region.offsetY;
attachment.regionWidth = region.width; attachment.RegionWidth = region.width;
attachment.regionHeight = region.height; attachment.RegionHeight = region.height;
attachment.regionOriginalWidth = region.originalWidth; attachment.RegionOriginalWidth = region.originalWidth;
attachment.regionOriginalHeight = region.originalHeight; attachment.RegionOriginalHeight = region.originalHeight;
attachment.Path = region.name; attachment.Path = region.name;
attachment.scaleX = 1; attachment.ScaleX = 1;
attachment.scaleY = 1; attachment.ScaleY = 1;
attachment.rotation = rotation; attachment.Rotation = rotation;
attachment.r = 1; attachment.R = 1;
attachment.g = 1; attachment.G = 1;
attachment.b = 1; attachment.B = 1;
attachment.a = 1; attachment.A = 1;
// pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation. // pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation.
attachment.width = attachment.regionOriginalWidth * scale; attachment.Width = attachment.RegionOriginalWidth * scale;
attachment.height = attachment.regionOriginalHeight * scale; attachment.Height = attachment.RegionOriginalHeight * scale;
attachment.SetColor(Color.white); attachment.SetColor(Color.white);
attachment.UpdateOffset(); attachment.UpdateOffset();
@ -158,31 +158,31 @@ namespace Spine.Unity.AttachmentTools {
/// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary> /// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
public static void SetScale (this RegionAttachment regionAttachment, Vector2 scale) { public static void SetScale (this RegionAttachment regionAttachment, Vector2 scale) {
regionAttachment.scaleX = scale.x; regionAttachment.ScaleX = scale.x;
regionAttachment.scaleY = scale.y; regionAttachment.ScaleY = scale.y;
} }
/// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary> /// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
public static void SetScale (this RegionAttachment regionAttachment, float x, float y) { public static void SetScale (this RegionAttachment regionAttachment, float x, float y) {
regionAttachment.scaleX = x; regionAttachment.ScaleX = x;
regionAttachment.scaleY = y; regionAttachment.ScaleY = y;
} }
/// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary> /// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
public static void SetPositionOffset (this RegionAttachment regionAttachment, Vector2 offset) { public static void SetPositionOffset (this RegionAttachment regionAttachment, Vector2 offset) {
regionAttachment.x = offset.x; regionAttachment.X = offset.x;
regionAttachment.y = offset.y; regionAttachment.Y = offset.y;
} }
/// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary> /// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
public static void SetPositionOffset (this RegionAttachment regionAttachment, float x, float y) { public static void SetPositionOffset (this RegionAttachment regionAttachment, float x, float y) {
regionAttachment.x = x; regionAttachment.X = x;
regionAttachment.y = y; regionAttachment.Y = y;
} }
/// <summary> Sets the rotation. Call regionAttachment.UpdateOffset to apply the change.</summary> /// <summary> Sets the rotation. Call regionAttachment.UpdateOffset to apply the change.</summary>
public static void SetRotation (this RegionAttachment regionAttachment, float rotation) { public static void SetRotation (this RegionAttachment regionAttachment, float rotation) {
regionAttachment.rotation = rotation; regionAttachment.Rotation = rotation;
} }
#endregion #endregion
} }

View File

@ -34,11 +34,11 @@ namespace Spine.Unity {
#region Colors #region Colors
const float ByteToFloat = 1f / 255f; const float ByteToFloat = 1f / 255f;
public static Color GetColor (this Skeleton s) { return new Color(s.r, s.g, s.b, s.a); } public static Color GetColor (this Skeleton s) { return new Color(s.R, s.G, s.B, s.A); }
public static Color GetColor (this RegionAttachment a) { return new Color(a.r, a.g, a.b, a.a); } public static Color GetColor (this RegionAttachment a) { return new Color(a.R, a.G, a.B, a.A); }
public static Color GetColor (this MeshAttachment a) { return new Color(a.r, a.g, a.b, a.a); } public static Color GetColor (this MeshAttachment a) { return new Color(a.R, a.G, a.B, a.A); }
public static Color GetColor (this Slot s) { return new Color(s.r, s.g, s.b, s.a); } public static Color GetColor (this Slot s) { return new Color(s.R, s.G, s.B, s.A); }
public static Color GetColorTintBlack (this Slot s) { return new Color(s.r2, s.g2, s.b2, 1f); } public static Color GetColorTintBlack (this Slot s) { return new Color(s.R2, s.G2, s.B2, 1f); }
public static void SetColor (this Skeleton skeleton, Color color) { public static void SetColor (this Skeleton skeleton, Color color) {
skeleton.A = color.a; skeleton.A = color.a;
@ -107,12 +107,12 @@ namespace Spine.Unity {
/// <summary>Gets the internal bone matrix as a Unity bonespace-to-skeletonspace transformation matrix.</summary> /// <summary>Gets the internal bone matrix as a Unity bonespace-to-skeletonspace transformation matrix.</summary>
public static Matrix4x4 GetMatrix4x4 (this Bone bone) { public static Matrix4x4 GetMatrix4x4 (this Bone bone) {
return new Matrix4x4 { return new Matrix4x4 {
m00 = bone.a, m00 = bone.A,
m01 = bone.b, m01 = bone.B,
m03 = bone.worldX, m03 = bone.WorldX,
m10 = bone.c, m10 = bone.C,
m11 = bone.d, m11 = bone.D,
m13 = bone.worldY, m13 = bone.WorldY,
m33 = 1 m33 = 1
}; };
} }
@ -133,12 +133,12 @@ namespace Spine.Unity {
/// <summary>Gets the bone's local X and Y as a Vector2.</summary> /// <summary>Gets the bone's local X and Y as a Vector2.</summary>
public static Vector2 GetLocalPosition (this Bone bone) { public static Vector2 GetLocalPosition (this Bone bone) {
return new Vector2(bone.x, bone.y); return new Vector2(bone.X, bone.Y);
} }
/// <summary>Gets the position of the bone in Skeleton-space.</summary> /// <summary>Gets the position of the bone in Skeleton-space.</summary>
public static Vector2 GetSkeletonSpacePosition (this Bone bone) { public static Vector2 GetSkeletonSpacePosition (this Bone bone) {
return new Vector2(bone.worldX, bone.worldY); return new Vector2(bone.WorldX, bone.WorldY);
} }
/// <summary>Gets a local offset from the bone and converts it into Skeleton-space.</summary> /// <summary>Gets a local offset from the bone and converts it into Skeleton-space.</summary>
@ -150,22 +150,22 @@ namespace Spine.Unity {
/// <summary>Gets the bone's Unity World position using its Spine GameObject Transform. UpdateWorldTransform needs to have been called for this to return the correct, updated value.</summary> /// <summary>Gets the bone's Unity World position using its Spine GameObject Transform. UpdateWorldTransform needs to have been called for this to return the correct, updated value.</summary>
public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform) { public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform) {
return spineGameObjectTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY)); return spineGameObjectTransform.TransformPoint(new Vector3(bone.WorldX, bone.WorldY));
} }
public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform, float positionScale) { public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform, float positionScale) {
return spineGameObjectTransform.TransformPoint(new Vector3(bone.worldX * positionScale, bone.worldY * positionScale)); return spineGameObjectTransform.TransformPoint(new Vector3(bone.WorldX * positionScale, bone.WorldY * positionScale));
} }
/// <summary>Gets a skeleton space UnityEngine.Quaternion representation of bone.WorldRotationX.</summary> /// <summary>Gets a skeleton space UnityEngine.Quaternion representation of bone.WorldRotationX.</summary>
public static Quaternion GetQuaternion (this Bone bone) { public static Quaternion GetQuaternion (this Bone bone) {
var halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f; var halfRotation = Mathf.Atan2(bone.C, bone.A) * 0.5f;
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation)); return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
} }
/// <summary>Gets a bone-local space UnityEngine.Quaternion representation of bone.rotation.</summary> /// <summary>Gets a bone-local space UnityEngine.Quaternion representation of bone.rotation.</summary>
public static Quaternion GetLocalQuaternion (this Bone bone) { public static Quaternion GetLocalQuaternion (this Bone bone) {
var halfRotation = bone.rotation * Mathf.Deg2Rad * 0.5f; var halfRotation = bone.Rotation * Mathf.Deg2Rad * 0.5f;
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation)); return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
} }
@ -176,7 +176,7 @@ namespace Spine.Unity {
/// <summary>Calculates a 2x2 Transformation Matrix that can convert a skeleton-space position to a bone-local position.</summary> /// <summary>Calculates a 2x2 Transformation Matrix that can convert a skeleton-space position to a bone-local position.</summary>
public static void GetWorldToLocalMatrix (this Bone bone, out float ia, out float ib, out float ic, out float id) { public static void GetWorldToLocalMatrix (this Bone bone, out float ia, out float ib, out float ic, out float id) {
float a = bone.a, b = bone.b, c = bone.c, d = bone.d; float a = bone.A, b = bone.B, c = bone.C, d = bone.D;
float invDet = 1 / (a * d - b * c); float invDet = 1 / (a * d - b * c);
ia = invDet * d; ia = invDet * d;
ib = invDet * -b; ib = invDet * -b;
@ -194,11 +194,11 @@ namespace Spine.Unity {
/// <summary>Sets the skeleton-space position of a bone.</summary> /// <summary>Sets the skeleton-space position of a bone.</summary>
/// <returns>The local position in its parent bone space, or in skeleton space if it is the root bone.</returns> /// <returns>The local position in its parent bone space, or in skeleton space if it is the root bone.</returns>
public static Vector2 SetPositionSkeletonSpace (this Bone bone, Vector2 skeletonSpacePosition) { public static Vector2 SetPositionSkeletonSpace (this Bone bone, Vector2 skeletonSpacePosition) {
if (bone.parent == null) { // root bone if (bone.Parent == null) { // root bone
bone.SetLocalPosition(skeletonSpacePosition); bone.SetLocalPosition(skeletonSpacePosition);
return skeletonSpacePosition; return skeletonSpacePosition;
} else { } else {
var parent = bone.parent; var parent = bone.Parent;
Vector2 parentLocal = parent.WorldToLocal(skeletonSpacePosition); Vector2 parentLocal = parent.WorldToLocal(skeletonSpacePosition);
bone.SetLocalPosition(parentLocal); bone.SetLocalPosition(parentLocal);
return parentLocal; return parentLocal;
@ -228,13 +228,13 @@ namespace Spine.Unity {
/// <param name="slot">Slot where the attachment belongs.</param> /// <param name="slot">Slot where the attachment belongs.</param>
/// <param name="buffer">Correctly-sized buffer. Use attachment's .WorldVerticesLength to get the correct size. If null, a new Vector2[] of the correct size will be allocated.</param> /// <param name="buffer">Correctly-sized buffer. Use attachment's .WorldVerticesLength to get the correct size. If null, a new Vector2[] of the correct size will be allocated.</param>
public static Vector2[] GetLocalVertices (this VertexAttachment va, Slot slot, Vector2[] buffer) { public static Vector2[] GetLocalVertices (this VertexAttachment va, Slot slot, Vector2[] buffer) {
int floatsCount = va.worldVerticesLength; int floatsCount = va.WorldVerticesLength;
int bufferTargetSize = floatsCount >> 1; int bufferTargetSize = floatsCount >> 1;
buffer = buffer ?? new Vector2[bufferTargetSize]; buffer = buffer ?? new Vector2[bufferTargetSize];
if (buffer.Length < bufferTargetSize) throw new System.ArgumentException(string.Format("Vector2 buffer too small. {0} requires an array of size {1}. Use the attachment's .WorldVerticesLength to get the correct size.", va.Name, floatsCount), "buffer"); if (buffer.Length < bufferTargetSize) throw new System.ArgumentException(string.Format("Vector2 buffer too small. {0} requires an array of size {1}. Use the attachment's .WorldVerticesLength to get the correct size.", va.Name, floatsCount), "buffer");
if (va.bones == null) { if (va.Bones == null) {
var localVerts = va.vertices; var localVerts = va.Vertices;
for (int i = 0; i < bufferTargetSize; i++) { for (int i = 0; i < bufferTargetSize; i++) {
int j = i * 2; int j = i * 2;
buffer[i] = new Vector2(localVerts[j], localVerts[j + 1]); buffer[i] = new Vector2(localVerts[j], localVerts[j + 1]);
@ -243,8 +243,8 @@ namespace Spine.Unity {
var floats = new float[floatsCount]; var floats = new float[floatsCount];
va.ComputeWorldVertices(slot, floats); va.ComputeWorldVertices(slot, floats);
Bone sb = slot.bone; Bone sb = slot.Bone;
float ia, ib, ic, id, bwx = sb.worldX, bwy = sb.worldY; float ia, ib, ic, id, bwx = sb.WorldX, bwy = sb.WorldY;
sb.GetWorldToLocalMatrix(out ia, out ib, out ic, out id); sb.GetWorldToLocalMatrix(out ia, out ib, out ic, out id);
for (int i = 0; i < bufferTargetSize; i++) { for (int i = 0; i < bufferTargetSize; i++) {
@ -262,7 +262,7 @@ namespace Spine.Unity {
/// <param name="slot">Slot where the attachment belongs.</param> /// <param name="slot">Slot where the attachment belongs.</param>
/// <param name="buffer">Correctly-sized buffer. Use attachment's .WorldVerticesLength to get the correct size. If null, a new Vector2[] of the correct size will be allocated.</param> /// <param name="buffer">Correctly-sized buffer. Use attachment's .WorldVerticesLength to get the correct size. If null, a new Vector2[] of the correct size will be allocated.</param>
public static Vector2[] GetWorldVertices (this VertexAttachment a, Slot slot, Vector2[] buffer) { public static Vector2[] GetWorldVertices (this VertexAttachment a, Slot slot, Vector2[] buffer) {
int worldVertsLength = a.worldVerticesLength; int worldVertsLength = a.WorldVerticesLength;
int bufferTargetSize = worldVertsLength >> 1; int bufferTargetSize = worldVertsLength >> 1;
buffer = buffer ?? new Vector2[bufferTargetSize]; buffer = buffer ?? new Vector2[bufferTargetSize];
if (buffer.Length < bufferTargetSize) throw new System.ArgumentException(string.Format("Vector2 buffer too small. {0} requires an array of size {1}. Use the attachment's .WorldVerticesLength to get the correct size.", a.Name, worldVertsLength), "buffer"); if (buffer.Length < bufferTargetSize) throw new System.ArgumentException(string.Format("Vector2 buffer too small. {0} requires an array of size {1}. Use the attachment's .WorldVerticesLength to get the correct size.", a.Name, worldVertsLength), "buffer");
@ -282,7 +282,7 @@ namespace Spine.Unity {
public static Vector3 GetWorldPosition (this PointAttachment attachment, Slot slot, Transform spineGameObjectTransform) { public static Vector3 GetWorldPosition (this PointAttachment attachment, Slot slot, Transform spineGameObjectTransform) {
Vector3 skeletonSpacePosition; Vector3 skeletonSpacePosition;
skeletonSpacePosition.z = 0; skeletonSpacePosition.z = 0;
attachment.ComputeWorldPosition(slot.bone, out skeletonSpacePosition.x, out skeletonSpacePosition.y); attachment.ComputeWorldPosition(slot.Bone, out skeletonSpacePosition.x, out skeletonSpacePosition.y);
return spineGameObjectTransform.TransformPoint(skeletonSpacePosition); return spineGameObjectTransform.TransformPoint(skeletonSpacePosition);
} }
@ -310,29 +310,29 @@ namespace Spine {
return default(BoneMatrix); return default(BoneMatrix);
// End condition: isRootBone // End condition: isRootBone
if (boneData.parent == null) if (boneData.Parent == null)
return GetInheritedInternal(boneData, default(BoneMatrix)); return GetInheritedInternal(boneData, default(BoneMatrix));
BoneMatrix result = CalculateSetupWorld(boneData.parent); BoneMatrix result = CalculateSetupWorld(boneData.Parent);
return GetInheritedInternal(boneData, result); return GetInheritedInternal(boneData, result);
} }
static BoneMatrix GetInheritedInternal (BoneData boneData, BoneMatrix parentMatrix) { static BoneMatrix GetInheritedInternal (BoneData boneData, BoneMatrix parentMatrix) {
var parent = boneData.parent; var parent = boneData.Parent;
if (parent == null) return new BoneMatrix(boneData); // isRootBone if (parent == null) return new BoneMatrix(boneData); // isRootBone
float pa = parentMatrix.a, pb = parentMatrix.b, pc = parentMatrix.c, pd = parentMatrix.d; float pa = parentMatrix.a, pb = parentMatrix.b, pc = parentMatrix.c, pd = parentMatrix.d;
BoneMatrix result = default(BoneMatrix); BoneMatrix result = default(BoneMatrix);
result.x = pa * boneData.x + pb * boneData.y + parentMatrix.x; result.x = pa * boneData.X + pb * boneData.Y + parentMatrix.x;
result.y = pc * boneData.x + pd * boneData.y + parentMatrix.y; result.y = pc * boneData.X + pd * boneData.Y + parentMatrix.y;
switch (boneData.transformMode) { switch (boneData.TransformMode) {
case TransformMode.Normal: { case TransformMode.Normal: {
float rotationY = boneData.rotation + 90 + boneData.shearY; float rotationY = boneData.Rotation + 90 + boneData.ShearY;
float la = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; float la = MathUtils.CosDeg(boneData.Rotation + boneData.ShearX) * boneData.ScaleX;
float lb = MathUtils.CosDeg(rotationY) * boneData.scaleY; float lb = MathUtils.CosDeg(rotationY) * boneData.ScaleY;
float lc = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; float lc = MathUtils.SinDeg(boneData.Rotation + boneData.ShearX) * boneData.ScaleX;
float ld = MathUtils.SinDeg(rotationY) * boneData.scaleY; float ld = MathUtils.SinDeg(rotationY) * boneData.ScaleY;
result.a = pa * la + pb * lc; result.a = pa * la + pb * lc;
result.b = pa * lb + pb * ld; result.b = pa * lb + pb * ld;
result.c = pc * la + pd * lc; result.c = pc * la + pd * lc;
@ -340,11 +340,11 @@ namespace Spine {
break; break;
} }
case TransformMode.OnlyTranslation: { case TransformMode.OnlyTranslation: {
float rotationY = boneData.rotation + 90 + boneData.shearY; float rotationY = boneData.Rotation + 90 + boneData.ShearY;
result.a = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; result.a = MathUtils.CosDeg(boneData.Rotation + boneData.ShearX) * boneData.ScaleX;
result.b = MathUtils.CosDeg(rotationY) * boneData.scaleY; result.b = MathUtils.CosDeg(rotationY) * boneData.ScaleY;
result.c = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; result.c = MathUtils.SinDeg(boneData.Rotation + boneData.ShearX) * boneData.ScaleX;
result.d = MathUtils.SinDeg(rotationY) * boneData.scaleY; result.d = MathUtils.SinDeg(rotationY) * boneData.ScaleY;
break; break;
} }
case TransformMode.NoRotationOrReflection: { case TransformMode.NoRotationOrReflection: {
@ -359,12 +359,12 @@ namespace Spine {
pc = 0; pc = 0;
prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg; prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg;
} }
float rx = boneData.rotation + boneData.shearX - prx; float rx = boneData.Rotation + boneData.ShearX - prx;
float ry = boneData.rotation + boneData.shearY - prx + 90; float ry = boneData.Rotation + boneData.ShearY - prx + 90;
float la = MathUtils.CosDeg(rx) * boneData.scaleX; float la = MathUtils.CosDeg(rx) * boneData.ScaleX;
float lb = MathUtils.CosDeg(ry) * boneData.scaleY; float lb = MathUtils.CosDeg(ry) * boneData.ScaleY;
float lc = MathUtils.SinDeg(rx) * boneData.scaleX; float lc = MathUtils.SinDeg(rx) * boneData.ScaleX;
float ld = MathUtils.SinDeg(ry) * boneData.scaleY; float ld = MathUtils.SinDeg(ry) * boneData.ScaleY;
result.a = pa * la - pb * lc; result.a = pa * la - pb * lc;
result.b = pa * lb - pb * ld; result.b = pa * lb - pb * ld;
result.c = pc * la + pd * lc; result.c = pc * la + pd * lc;
@ -373,7 +373,7 @@ namespace Spine {
} }
case TransformMode.NoScale: case TransformMode.NoScale:
case TransformMode.NoScaleOrReflection: { case TransformMode.NoScaleOrReflection: {
float cos = MathUtils.CosDeg(boneData.rotation), sin = MathUtils.SinDeg(boneData.rotation); float cos = MathUtils.CosDeg(boneData.Rotation), sin = MathUtils.SinDeg(boneData.Rotation);
float za = pa * cos + pb * sin; float za = pa * cos + pb * sin;
float zc = pc * cos + pd * sin; float zc = pc * cos + pd * sin;
float s = (float)Math.Sqrt(za * za + zc * zc); float s = (float)Math.Sqrt(za * za + zc * zc);
@ -385,11 +385,11 @@ namespace Spine {
float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za); float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
float zb = MathUtils.Cos(r) * s; float zb = MathUtils.Cos(r) * s;
float zd = MathUtils.Sin(r) * s; float zd = MathUtils.Sin(r) * s;
float la = MathUtils.CosDeg(boneData.shearX) * boneData.scaleX; float la = MathUtils.CosDeg(boneData.ShearX) * boneData.ScaleX;
float lb = MathUtils.CosDeg(90 + boneData.shearY) * boneData.scaleY; float lb = MathUtils.CosDeg(90 + boneData.ShearY) * boneData.ScaleY;
float lc = MathUtils.SinDeg(boneData.shearX) * boneData.scaleX; float lc = MathUtils.SinDeg(boneData.ShearX) * boneData.ScaleX;
float ld = MathUtils.SinDeg(90 + boneData.shearY) * boneData.scaleY; float ld = MathUtils.SinDeg(90 + boneData.ShearY) * boneData.ScaleY;
if (boneData.transformMode != TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) { if (boneData.TransformMode != TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) {
zb = -zb; zb = -zb;
zd = -zd; zd = -zd;
} }
@ -406,28 +406,28 @@ namespace Spine {
/// <summary>Constructor for a local bone matrix based on Setup Pose BoneData.</summary> /// <summary>Constructor for a local bone matrix based on Setup Pose BoneData.</summary>
public BoneMatrix (BoneData boneData) { public BoneMatrix (BoneData boneData) {
float rotationY = boneData.rotation + 90 + boneData.shearY; float rotationY = boneData.Rotation + 90 + boneData.ShearY;
float rotationX = boneData.rotation + boneData.shearX; float rotationX = boneData.Rotation + boneData.ShearX;
a = MathUtils.CosDeg(rotationX) * boneData.scaleX; a = MathUtils.CosDeg(rotationX) * boneData.ScaleX;
c = MathUtils.SinDeg(rotationX) * boneData.scaleX; c = MathUtils.SinDeg(rotationX) * boneData.ScaleX;
b = MathUtils.CosDeg(rotationY) * boneData.scaleY; b = MathUtils.CosDeg(rotationY) * boneData.ScaleY;
d = MathUtils.SinDeg(rotationY) * boneData.scaleY; d = MathUtils.SinDeg(rotationY) * boneData.ScaleY;
x = boneData.x; x = boneData.X;
y = boneData.y; y = boneData.Y;
} }
/// <summary>Constructor for a local bone matrix based on a bone instance's current pose.</summary> /// <summary>Constructor for a local bone matrix based on a bone instance's current pose.</summary>
public BoneMatrix (Bone bone) { public BoneMatrix (Bone bone) {
float rotationY = bone.rotation + 90 + bone.shearY; float rotationY = bone.Rotation + 90 + bone.ShearY;
float rotationX = bone.rotation + bone.shearX; float rotationX = bone.Rotation + bone.ShearX;
a = MathUtils.CosDeg(rotationX) * bone.scaleX; a = MathUtils.CosDeg(rotationX) * bone.ScaleX;
c = MathUtils.SinDeg(rotationX) * bone.scaleX; c = MathUtils.SinDeg(rotationX) * bone.ScaleX;
b = MathUtils.CosDeg(rotationY) * bone.scaleY; b = MathUtils.CosDeg(rotationY) * bone.ScaleY;
d = MathUtils.SinDeg(rotationY) * bone.scaleY; d = MathUtils.SinDeg(rotationY) * bone.ScaleY;
x = bone.x; x = bone.X;
y = bone.y; y = bone.Y;
} }
public BoneMatrix TransformMatrix (BoneMatrix local) { public BoneMatrix TransformMatrix (BoneMatrix local) {
@ -444,7 +444,7 @@ namespace Spine {
public static class SpineSkeletonExtensions { public static class SpineSkeletonExtensions {
public static bool IsWeighted (this VertexAttachment va) { public static bool IsWeighted (this VertexAttachment va) {
return va.bones != null && va.bones.Length > 0; return va.Bones != null && va.Bones.Length > 0;
} }
#region Transform Modes #region Transform Modes
@ -458,13 +458,5 @@ namespace Spine {
return ((int)mode & (1U << ScaleBit)) == 0; return ((int)mode & (1U << ScaleBit)) == 0;
} }
#endregion #endregion
// Note: This extension method is required by SpineAnimationStateMixerBehaviour,
// which is part of the timeline extension package. Thus the internal member variable
// nextTrackLast is not accessible. We favor providing this extension method
// over exposing nextTrackLast as public property, which would rather confuse users.
public static void AllowImmediateQueue (this TrackEntry trackEntry) {
if (trackEntry.nextTrackLast < 0) trackEntry.nextTrackLast = 0;
}
} }
} }

View File

@ -36,39 +36,12 @@ namespace Spine.Unity.AnimationTools {
/// <summary>Evaluates the resulting value of a TranslateTimeline at a given time. /// <summary>Evaluates the resulting value of a TranslateTimeline at a given time.
/// SkeletonData can be accessed from Skeleton.Data or from SkeletonDataAsset.GetSkeletonData. /// SkeletonData can be accessed from Skeleton.Data or from SkeletonDataAsset.GetSkeletonData.
/// If no SkeletonData is given, values are computed relative to setup pose instead of local-absolute.</summary> /// If no SkeletonData is given, values are returned as difference to setup pose
/// instead of absolute values.</summary>
public static Vector2 Evaluate (this TranslateTimeline timeline, float time, SkeletonData skeletonData = null) { public static Vector2 Evaluate (this TranslateTimeline timeline, float time, SkeletonData skeletonData = null) {
var frames = timeline.frames;
if (time < frames[0]) return Vector2.zero;
float x, y; float x, y;
int i = TranslateTimeline.Search(frames, time, TranslateTimeline.ENTRIES), curveType = (int)timeline.curves[i / TranslateTimeline.ENTRIES]; timeline.Evaluate(out x, out y, time, skeletonData);
switch (curveType) { return new Vector2(x, y);
case TranslateTimeline.LINEAR:
float before = frames[i];
x = frames[i + TranslateTimeline.VALUE1];
y = frames[i + TranslateTimeline.VALUE2];
float t = (time - before) / (frames[i + TranslateTimeline.ENTRIES] - before);
x += (frames[i + TranslateTimeline.ENTRIES + TranslateTimeline.VALUE1] - x) * t;
y += (frames[i + TranslateTimeline.ENTRIES + TranslateTimeline.VALUE2] - y) * t;
break;
case TranslateTimeline.STEPPED:
x = frames[i + TranslateTimeline.VALUE1];
y = frames[i + TranslateTimeline.VALUE2];
break;
default:
x = timeline.GetBezierValue(time, i, TranslateTimeline.VALUE1, curveType - TranslateTimeline.BEZIER);
y = timeline.GetBezierValue(time, i, TranslateTimeline.VALUE2, curveType + TranslateTimeline.BEZIER_SIZE - TranslateTimeline.BEZIER);
break;
}
Vector2 xy = new Vector2(x, y);
if (skeletonData == null) {
return xy;
} else {
var boneData = skeletonData.bones.Items[timeline.BoneIndex];
return xy + new Vector2(boneData.x, boneData.y);
}
} }
/// <summary>Gets the translate timeline for a given boneIndex. /// <summary>Gets the translate timeline for a given boneIndex.
@ -76,7 +49,7 @@ namespace Spine.Unity.AnimationTools {
/// The root bone is always boneIndex 0. /// The root bone is always boneIndex 0.
/// This will return null if a TranslateTimeline is not found.</summary> /// This will return null if a TranslateTimeline is not found.</summary>
public static TranslateTimeline FindTranslateTimelineForBone (this Animation a, int boneIndex) { public static TranslateTimeline FindTranslateTimelineForBone (this Animation a, int boneIndex) {
foreach (var timeline in a.timelines) { foreach (var timeline in a.Timelines) {
if (timeline.GetType().IsSubclassOf(typeof(TranslateTimeline))) if (timeline.GetType().IsSubclassOf(typeof(TranslateTimeline)))
continue; continue;

View File

@ -2,7 +2,7 @@
"name": "com.esotericsoftware.spine.spine-unity", "name": "com.esotericsoftware.spine.spine-unity",
"displayName": "spine-unity Runtime", "displayName": "spine-unity Runtime",
"description": "This plugin provides the spine-unity runtime core.", "description": "This plugin provides the spine-unity runtime core.",
"version": "3.9.0", "version": "4.0.0",
"unity": "2018.3", "unity": "2018.3",
"author": { "author": {
"name": "Esoteric Software", "name": "Esoteric Software",
@ -10,10 +10,23 @@
"url": "http://esotericsoftware.com/" "url": "http://esotericsoftware.com/"
}, },
"dependencies": { "dependencies": {
"com.esotericsoftware.spine.spine-csharp": "4.0.0"
},
"repository": {
"type": "git",
"url": "git@github.com:EsotericSoftware/spine-runtimes.git"
}, },
"keywords": [ "keywords": [
"spine", "spine",
"spine-unity", "spine-unity",
"core" "runtimes",
] "2d",
"skeletal",
"animation"
],
"license": "SEE LICENSE IN LICENSE",
"bugs": {
"url": "https://github.com/EsotericSoftware/spine-runtimes/issues"
},
"homepage": "https://github.com/EsotericSoftware/spine-runtimes#readme"
} }

View File

@ -2,6 +2,7 @@
"name": "spine-timeline", "name": "spine-timeline",
"references": [ "references": [
"spine-unity", "spine-unity",
"spine-csharp",
"Unity.Timeline" "Unity.Timeline"
], ],
"optionalUnityReferences": [], "optionalUnityReferences": [],

View File

@ -10,7 +10,8 @@
"url": "http://esotericsoftware.com/" "url": "http://esotericsoftware.com/"
}, },
"dependencies": { "dependencies": {
"com.unity.timeline": "1.2.10" "com.unity.timeline": "1.2.10",
"com.esotericsoftware.spine.spine-unity": "4.0.0"
}, },
"keywords": [ "keywords": [
"spine", "spine",