This commit is contained in:
JA
2026-06-27 03:37:48 +08:00
parent 7969e2e35d
commit 5fa163e77d
284 changed files with 4761 additions and 21836 deletions

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 33c080d1c093a2c45b6c72c17a557067
folderAsset: yes
timeCreated: 1563304704
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,156 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
/// <summary>>An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
/// <see cref="Slot.Deform"/>.</summary>
public abstract class VertexAttachment : Attachment {
static int nextID = 0;
static readonly Object nextIdLock = new Object();
internal readonly int id;
internal int[] bones;
internal float[] vertices;
internal int worldVerticesLength;
internal VertexAttachment deformAttachment;
/// <summary>Gets a unique ID for this attachment.</summary>
public int Id { get { return id; } }
public int[] Bones { get { return bones; } set { bones = value; } }
public float[] Vertices { get { return vertices; } set { vertices = value; } }
public int WorldVerticesLength { get { return worldVerticesLength; } set { worldVerticesLength = value; } }
///<summary>Deform keys for the deform attachment are also applied to this attachment.
/// May be null if no deform keys should be applied.</summary>
public VertexAttachment DeformAttachment { get { return deformAttachment; } set { deformAttachment = value; } }
public VertexAttachment (string name)
: base(name) {
deformAttachment = this;
lock (VertexAttachment.nextIdLock) {
id = (VertexAttachment.nextID++ & 65535) << 11;
}
}
public void ComputeWorldVertices (Slot slot, float[] worldVertices) {
ComputeWorldVertices(slot, 0, worldVerticesLength, worldVertices, 0);
}
/// <summary>
/// Transforms the attachment's local <see cref="Vertices"/> to world coordinates. If the slot's <see cref="Slot.Deform"/> is
/// not empty, it is used to deform the vertices.
/// <para />
/// See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
/// Runtimes Guide.
/// </summary>
/// <param name="start">The index of the first <see cref="Vertices"/> value to transform. Each vertex has 2 values, x and y.</param>
/// <param name="count">The number of world vertex values to output. Must be less than or equal to <see cref="WorldVerticesLength"/> - start.</param>
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to <paramref name="offset"/> + <paramref name="count"/>.</param>
/// <param name="offset">The <paramref name="worldVertices"/> index to begin writing values.</param>
/// <param name="stride">The number of <paramref name="worldVertices"/> entries between the value pairs written.</param>
public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) {
count = offset + (count >> 1) * stride;
Skeleton skeleton = slot.bone.skeleton;
var deformArray = slot.deform;
float[] vertices = this.vertices;
int[] bones = this.bones;
if (bones == null) {
if (deformArray.Count > 0) vertices = deformArray.Items;
Bone bone = slot.bone;
float x = bone.worldX, y = bone.worldY;
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
for (int vv = start, w = offset; w < count; vv += 2, w += stride) {
float vx = vertices[vv], vy = vertices[vv + 1];
worldVertices[w] = vx * a + vy * b + x;
worldVertices[w + 1] = vx * c + vy * d + y;
}
return;
}
int v = 0, skip = 0;
for (int i = 0; i < start; i += 2) {
int n = bones[v];
v += n + 1;
skip += n;
}
var skeletonBones = skeleton.bones.Items;
if (deformArray.Count == 0) {
for (int w = offset, b = skip * 3; w < count; w += stride) {
float wx = 0, wy = 0;
int n = bones[v++];
n += v;
for (; v < n; v++, b += 3) {
Bone bone = skeletonBones[bones[v]];
float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
}
worldVertices[w] = wx;
worldVertices[w + 1] = wy;
}
} else {
float[] deform = deformArray.Items;
for (int w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {
float wx = 0, wy = 0;
int n = bones[v++];
n += v;
for (; v < n; v++, b += 3, f += 2) {
Bone bone = skeletonBones[bones[v]];
float vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
}
worldVertices[w] = wx;
worldVertices[w + 1] = wy;
}
}
}
///<summary>Does not copy id (generated) or name (set on construction).</summary>
internal void CopyTo (VertexAttachment attachment) {
if (bones != null) {
attachment.bones = new int[bones.Length];
Array.Copy(bones, 0, attachment.bones, 0, bones.Length);
}
else
attachment.bones = null;
if (vertices != null) {
attachment.vertices = new float[vertices.Length];
Array.Copy(vertices, 0, attachment.vertices, 0, vertices.Length);
}
else
attachment.vertices = null;
attachment.worldVerticesLength = worldVerticesLength;
attachment.deformAttachment = deformAttachment;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 8b40cfb462a8b774891e1604e5360d32
timeCreated: 1466772712
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,313 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
/// <summary>
/// <para>
/// Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained
/// bones to match that of the target bone.</para>
/// <para>
/// See <a href="http://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide.</para>
/// </summary>
public class TransformConstraint : IUpdatable {
internal TransformConstraintData data;
internal ExposedList<Bone> bones;
internal Bone target;
internal float rotateMix, translateMix, scaleMix, shearMix;
internal bool active;
public TransformConstraint (TransformConstraintData data, Skeleton skeleton) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
this.data = data;
rotateMix = data.rotateMix;
translateMix = data.translateMix;
scaleMix = data.scaleMix;
shearMix = data.shearMix;
bones = new ExposedList<Bone>();
foreach (BoneData boneData in data.bones)
bones.Add (skeleton.FindBone(boneData.name));
target = skeleton.FindBone(data.target.name);
}
/// <summary>Copy constructor.</summary>
public TransformConstraint (TransformConstraint constraint, Skeleton skeleton) {
if (constraint == null) throw new ArgumentNullException("constraint cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
data = constraint.data;
bones = new ExposedList<Bone>(constraint.Bones.Count);
foreach (Bone bone in constraint.Bones)
bones.Add(skeleton.Bones.Items[bone.data.index]);
target = skeleton.Bones.Items[constraint.target.data.index];
rotateMix = constraint.rotateMix;
translateMix = constraint.translateMix;
scaleMix = constraint.scaleMix;
shearMix = constraint.shearMix;
}
/// <summary>Applies the constraint to the constrained bones.</summary>
public void Apply () {
Update();
}
public void Update () {
if (data.local) {
if (data.relative)
ApplyRelativeLocal();
else
ApplyAbsoluteLocal();
} else {
if (data.relative)
ApplyRelativeWorld();
else
ApplyAbsoluteWorld();
}
}
void ApplyAbsoluteWorld () {
float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
Bone target = this.target;
float ta = target.a, tb = target.b, tc = target.c, td = target.d;
float degRadReflect = ta * td - tb * tc > 0 ? MathUtils.DegRad : -MathUtils.DegRad;
float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect;
var bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) {
Bone bone = bones.Items[i];
bool modified = false;
if (rotateMix != 0) {
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
float r = MathUtils.Atan2(tc, ta) - MathUtils.Atan2(c, a) + offsetRotation;
if (r > MathUtils.PI)
r -= MathUtils.PI2;
else if (r < -MathUtils.PI) r += MathUtils.PI2;
r *= rotateMix;
float cos = MathUtils.Cos(r), sin = MathUtils.Sin(r);
bone.a = cos * a - sin * c;
bone.b = cos * b - sin * d;
bone.c = sin * a + cos * c;
bone.d = sin * b + cos * d;
modified = true;
}
if (translateMix != 0) {
float tx, ty; //Vector2 temp = this.temp;
target.LocalToWorld(data.offsetX, data.offsetY, out tx, out ty); //target.localToWorld(temp.set(data.offsetX, data.offsetY));
bone.worldX += (tx - bone.worldX) * translateMix;
bone.worldY += (ty - bone.worldY) * translateMix;
modified = true;
}
if (scaleMix > 0) {
float s = (float)Math.Sqrt(bone.a * bone.a + bone.c * bone.c);
if (s != 0) s = (s + ((float)Math.Sqrt(ta * ta + tc * tc) - s + data.offsetScaleX) * scaleMix) / s;
bone.a *= s;
bone.c *= s;
s = (float)Math.Sqrt(bone.b * bone.b + bone.d * bone.d);
if (s != 0) s = (s + ((float)Math.Sqrt(tb * tb + td * td) - s + data.offsetScaleY) * scaleMix) / s;
bone.b *= s;
bone.d *= s;
modified = true;
}
if (shearMix > 0) {
float b = bone.b, d = bone.d;
float by = MathUtils.Atan2(d, b);
float r = MathUtils.Atan2(td, tb) - MathUtils.Atan2(tc, ta) - (by - MathUtils.Atan2(bone.c, bone.a));
if (r > MathUtils.PI)
r -= MathUtils.PI2;
else if (r < -MathUtils.PI) r += MathUtils.PI2;
r = by + (r + offsetShearY) * shearMix;
float s = (float)Math.Sqrt(b * b + d * d);
bone.b = MathUtils.Cos(r) * s;
bone.d = MathUtils.Sin(r) * s;
modified = true;
}
if (modified) bone.appliedValid = false;
}
}
void ApplyRelativeWorld () {
float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
Bone target = this.target;
float ta = target.a, tb = target.b, tc = target.c, td = target.d;
float degRadReflect = ta * td - tb * tc > 0 ? MathUtils.DegRad : -MathUtils.DegRad;
float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect;
var bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) {
Bone bone = bones.Items[i];
bool modified = false;
if (rotateMix != 0) {
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
float r = MathUtils.Atan2(tc, ta) + offsetRotation;
if (r > MathUtils.PI)
r -= MathUtils.PI2;
else if (r < -MathUtils.PI) r += MathUtils.PI2;
r *= rotateMix;
float cos = MathUtils.Cos(r), sin = MathUtils.Sin(r);
bone.a = cos * a - sin * c;
bone.b = cos * b - sin * d;
bone.c = sin * a + cos * c;
bone.d = sin * b + cos * d;
modified = true;
}
if (translateMix != 0) {
float tx, ty; //Vector2 temp = this.temp;
target.LocalToWorld(data.offsetX, data.offsetY, out tx, out ty); //target.localToWorld(temp.set(data.offsetX, data.offsetY));
bone.worldX += tx * translateMix;
bone.worldY += ty * translateMix;
modified = true;
}
if (scaleMix > 0) {
float s = ((float)Math.Sqrt(ta * ta + tc * tc) - 1 + data.offsetScaleX) * scaleMix + 1;
bone.a *= s;
bone.c *= s;
s = ((float)Math.Sqrt(tb * tb + td * td) - 1 + data.offsetScaleY) * scaleMix + 1;
bone.b *= s;
bone.d *= s;
modified = true;
}
if (shearMix > 0) {
float r = MathUtils.Atan2(td, tb) - MathUtils.Atan2(tc, ta);
if (r > MathUtils.PI)
r -= MathUtils.PI2;
else if (r < -MathUtils.PI) r += MathUtils.PI2;
float b = bone.b, d = bone.d;
r = MathUtils.Atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix;
float s = (float)Math.Sqrt(b * b + d * d);
bone.b = MathUtils.Cos(r) * s;
bone.d = MathUtils.Sin(r) * s;
modified = true;
}
if (modified) bone.appliedValid = false;
}
}
void ApplyAbsoluteLocal () {
float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
Bone target = this.target;
if (!target.appliedValid) target.UpdateAppliedTransform();
var bonesItems = this.bones.Items;
for (int i = 0, n = this.bones.Count; i < n; i++) {
Bone bone = bonesItems[i];
if (!bone.appliedValid) bone.UpdateAppliedTransform();
float rotation = bone.arotation;
if (rotateMix != 0) {
float r = target.arotation - rotation + data.offsetRotation;
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
rotation += r * rotateMix;
}
float x = bone.ax, y = bone.ay;
if (translateMix != 0) {
x += (target.ax - x + data.offsetX) * translateMix;
y += (target.ay - y + data.offsetY) * translateMix;
}
float scaleX = bone.ascaleX, scaleY = bone.ascaleY;
if (scaleMix != 0) {
if (scaleX != 0) scaleX = (scaleX + (target.ascaleX - scaleX + data.offsetScaleX) * scaleMix) / scaleX;
if (scaleY != 0) scaleY = (scaleY + (target.ascaleY - scaleY + data.offsetScaleY) * scaleMix) / scaleY;
}
float shearY = bone.ashearY;
if (shearMix != 0) {
float r = target.ashearY - shearY + data.offsetShearY;
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
shearY += r * shearMix;
}
bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
}
}
void ApplyRelativeLocal () {
float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
Bone target = this.target;
if (!target.appliedValid) target.UpdateAppliedTransform();
var bonesItems = this.bones.Items;
for (int i = 0, n = this.bones.Count; i < n; i++) {
Bone bone = bonesItems[i];
if (!bone.appliedValid) bone.UpdateAppliedTransform();
float rotation = bone.arotation;
if (rotateMix != 0) rotation += (target.arotation + data.offsetRotation) * rotateMix;
float x = bone.ax, y = bone.ay;
if (translateMix != 0) {
x += (target.ax + data.offsetX) * translateMix;
y += (target.ay + data.offsetY) * translateMix;
}
float scaleX = bone.ascaleX, scaleY = bone.ascaleY;
if (scaleMix != 0) {
scaleX *= ((target.ascaleX - 1 + data.offsetScaleX) * scaleMix) + 1;
scaleY *= ((target.ascaleY - 1 + data.offsetScaleY) * scaleMix) + 1;
}
float shearY = bone.ashearY;
if (shearMix != 0) shearY += (target.ashearY + data.offsetShearY) * shearMix;
bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
}
}
/// <summary>The bones that will be modified by this transform constraint.</summary>
public ExposedList<Bone> Bones { get { return bones; } }
/// <summary>The target bone whose world transform will be copied to the constrained bones.</summary>
public Bone Target { get { return target; } set { target = value; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained rotations.</summary>
public float RotateMix { get { return rotateMix; } set { rotateMix = value; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained translations.</summary>
public float TranslateMix { get { return translateMix; } set { translateMix = value; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained scales.</summary>
public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained scales.</summary>
public float ShearMix { get { return shearMix; } set { shearMix = value; } }
public bool Active { get { return active; } }
/// <summary>The transform constraint's setup pose data.</summary>
public TransformConstraintData Data { get { return data; } }
override public string ToString () {
return data.name;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 2e30316a9733f8a4b8b6c362c06dfa11
timeCreated: 1456265153
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,60 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
public class TransformConstraintData : ConstraintData {
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
internal BoneData target;
internal float rotateMix, translateMix, scaleMix, shearMix;
internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
internal bool relative, local;
public ExposedList<BoneData> Bones { get { return bones; } }
public BoneData Target { get { return target; } set { target = value; } }
public float RotateMix { get { return rotateMix; } set { rotateMix = value; } }
public float TranslateMix { get { return translateMix; } set { translateMix = value; } }
public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } }
public float ShearMix { get { return shearMix; } set { shearMix = value; } }
public float OffsetRotation { get { return offsetRotation; } set { offsetRotation = value; } }
public float OffsetX { get { return offsetX; } set { offsetX = value; } }
public float OffsetY { get { return offsetY; } set { offsetY = value; } }
public float OffsetScaleX { get { return offsetScaleX; } set { offsetScaleX = value; } }
public float OffsetScaleY { get { return offsetScaleY; } set { offsetScaleY = value; } }
public float OffsetShearY { get { return offsetShearY; } set { offsetShearY = value; } }
public bool Relative { get { return relative; } set { relative = value; } }
public bool Local { get { return local; } set { local = value; } }
public TransformConstraintData (string name) : base(name) {
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: b7edeecc9bd7dd44faabf24f29b119a0
timeCreated: 1456265155
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,277 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
public class Triangulator {
private readonly ExposedList<ExposedList<float>> convexPolygons = new ExposedList<ExposedList<float>>();
private readonly ExposedList<ExposedList<int>> convexPolygonsIndices = new ExposedList<ExposedList<int>>();
private readonly ExposedList<int> indicesArray = new ExposedList<int>();
private readonly ExposedList<bool> isConcaveArray = new ExposedList<bool>();
private readonly ExposedList<int> triangles = new ExposedList<int>();
private readonly Pool<ExposedList<float>> polygonPool = new Pool<ExposedList<float>>();
private readonly Pool<ExposedList<int>> polygonIndicesPool = new Pool<ExposedList<int>>();
public ExposedList<int> Triangulate (ExposedList<float> verticesArray) {
var vertices = verticesArray.Items;
int vertexCount = verticesArray.Count >> 1;
var indicesArray = this.indicesArray;
indicesArray.Clear();
int[] indices = indicesArray.Resize(vertexCount).Items;
for (int i = 0; i < vertexCount; i++)
indices[i] = i;
var isConcaveArray = this.isConcaveArray;
bool[] isConcave = isConcaveArray.Resize(vertexCount).Items;
for (int i = 0, n = vertexCount; i < n; ++i)
isConcave[i] = IsConcave(i, vertexCount, vertices, indices);
var triangles = this.triangles;
triangles.Clear();
triangles.EnsureCapacity(Math.Max(0, vertexCount - 2) << 2);
while (vertexCount > 3) {
// Find ear tip.
int previous = vertexCount - 1, i = 0, next = 1;
// outer:
while (true) {
if (!isConcave[i]) {
int p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
float p1x = vertices[p1], p1y = vertices[p1 + 1];
float p2x = vertices[p2], p2y = vertices[p2 + 1];
float p3x = vertices[p3], p3y = vertices[p3 + 1];
for (int ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
if (!isConcave[ii]) continue;
int v = indices[ii] << 1;
float vx = vertices[v], vy = vertices[v + 1];
if (PositiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
if (PositiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
if (PositiveArea(p2x, p2y, p3x, p3y, vx, vy)) goto break_outer; // break outer;
}
}
}
break;
}
break_outer:
if (next == 0) {
do {
if (!isConcave[i]) break;
i--;
} while (i > 0);
break;
}
previous = i;
i = next;
next = (next + 1) % vertexCount;
}
// Cut ear tip.
triangles.Add(indices[(vertexCount + i - 1) % vertexCount]);
triangles.Add(indices[i]);
triangles.Add(indices[(i + 1) % vertexCount]);
indicesArray.RemoveAt(i);
isConcaveArray.RemoveAt(i);
vertexCount--;
int previousIndex = (vertexCount + i - 1) % vertexCount;
int nextIndex = i == vertexCount ? 0 : i;
isConcave[previousIndex] = IsConcave(previousIndex, vertexCount, vertices, indices);
isConcave[nextIndex] = IsConcave(nextIndex, vertexCount, vertices, indices);
}
if (vertexCount == 3) {
triangles.Add(indices[2]);
triangles.Add(indices[0]);
triangles.Add(indices[1]);
}
return triangles;
}
public ExposedList<ExposedList<float>> Decompose (ExposedList<float> verticesArray, ExposedList<int> triangles) {
var vertices = verticesArray.Items;
var convexPolygons = this.convexPolygons;
for (int i = 0, n = convexPolygons.Count; i < n; i++) {
polygonPool.Free(convexPolygons.Items[i]);
}
convexPolygons.Clear();
var convexPolygonsIndices = this.convexPolygonsIndices;
for (int i = 0, n = convexPolygonsIndices.Count; i < n; i++) {
polygonIndicesPool.Free(convexPolygonsIndices.Items[i]);
}
convexPolygonsIndices.Clear();
var polygonIndices = polygonIndicesPool.Obtain();
polygonIndices.Clear();
var polygon = polygonPool.Obtain();
polygon.Clear();
// Merge subsequent triangles if they form a triangle fan.
int fanBaseIndex = -1, lastWinding = 0;
int[] trianglesItems = triangles.Items;
for (int i = 0, n = triangles.Count; i < n; i += 3) {
int t1 = trianglesItems[i] << 1, t2 = trianglesItems[i + 1] << 1, t3 = trianglesItems[i + 2] << 1;
float x1 = vertices[t1], y1 = vertices[t1 + 1];
float x2 = vertices[t2], y2 = vertices[t2 + 1];
float x3 = vertices[t3], y3 = vertices[t3 + 1];
// If the base of the last triangle is the same as this triangle, check if they form a convex polygon (triangle fan).
var merged = false;
if (fanBaseIndex == t1) {
int o = polygon.Count - 4;
float[] p = polygon.Items;
int winding1 = Winding(p[o], p[o + 1], p[o + 2], p[o + 3], x3, y3);
int winding2 = Winding(x3, y3, p[0], p[1], p[2], p[3]);
if (winding1 == lastWinding && winding2 == lastWinding) {
polygon.Add(x3);
polygon.Add(y3);
polygonIndices.Add(t3);
merged = true;
}
}
// Otherwise make this triangle the new base.
if (!merged) {
if (polygon.Count > 0) {
convexPolygons.Add(polygon);
convexPolygonsIndices.Add(polygonIndices);
} else {
polygonPool.Free(polygon);
polygonIndicesPool.Free(polygonIndices);
}
polygon = polygonPool.Obtain();
polygon.Clear();
polygon.Add(x1);
polygon.Add(y1);
polygon.Add(x2);
polygon.Add(y2);
polygon.Add(x3);
polygon.Add(y3);
polygonIndices = polygonIndicesPool.Obtain();
polygonIndices.Clear();
polygonIndices.Add(t1);
polygonIndices.Add(t2);
polygonIndices.Add(t3);
lastWinding = Winding(x1, y1, x2, y2, x3, y3);
fanBaseIndex = t1;
}
}
if (polygon.Count > 0) {
convexPolygons.Add(polygon);
convexPolygonsIndices.Add(polygonIndices);
}
// Go through the list of polygons and try to merge the remaining triangles with the found triangle fans.
for (int i = 0, n = convexPolygons.Count; i < n; i++) {
polygonIndices = convexPolygonsIndices.Items[i];
if (polygonIndices.Count == 0) continue;
int firstIndex = polygonIndices.Items[0];
int lastIndex = polygonIndices.Items[polygonIndices.Count - 1];
polygon = convexPolygons.Items[i];
int o = polygon.Count - 4;
float[] p = polygon.Items;
float prevPrevX = p[o], prevPrevY = p[o + 1];
float prevX = p[o + 2], prevY = p[o + 3];
float firstX = p[0], firstY = p[1];
float secondX = p[2], secondY = p[3];
int winding = Winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
for (int ii = 0; ii < n; ii++) {
if (ii == i) continue;
var otherIndices = convexPolygonsIndices.Items[ii];
if (otherIndices.Count != 3) continue;
int otherFirstIndex = otherIndices.Items[0];
int otherSecondIndex = otherIndices.Items[1];
int otherLastIndex = otherIndices.Items[2];
var otherPoly = convexPolygons.Items[ii];
float x3 = otherPoly.Items[otherPoly.Count - 2], y3 = otherPoly.Items[otherPoly.Count - 1];
if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) continue;
int winding1 = Winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
int winding2 = Winding(x3, y3, firstX, firstY, secondX, secondY);
if (winding1 == winding && winding2 == winding) {
otherPoly.Clear();
otherIndices.Clear();
polygon.Add(x3);
polygon.Add(y3);
polygonIndices.Add(otherLastIndex);
prevPrevX = prevX;
prevPrevY = prevY;
prevX = x3;
prevY = y3;
ii = 0;
}
}
}
// Remove empty polygons that resulted from the merge step above.
for (int i = convexPolygons.Count - 1; i >= 0; i--) {
polygon = convexPolygons.Items[i];
if (polygon.Count == 0) {
convexPolygons.RemoveAt(i);
polygonPool.Free(polygon);
polygonIndices = convexPolygonsIndices.Items[i];
convexPolygonsIndices.RemoveAt(i);
polygonIndicesPool.Free(polygonIndices);
}
}
return convexPolygons;
}
static private bool IsConcave (int index, int vertexCount, float[] vertices, int[] indices) {
int previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
int current = indices[index] << 1;
int next = indices[(index + 1) % vertexCount] << 1;
return !PositiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next],
vertices[next + 1]);
}
static private bool PositiveArea (float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) {
return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
}
static private int Winding (float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) {
float px = p2x - p1x, py = p2y - p1y;
return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 90a8832a1f3c5f846b8773dc0e1c3238
timeCreated: 1493126637
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: e70d3026a0242e5418232b2015be29f7
folderAsset: yes
timeCreated: 1456509301
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: bc59776133d26dc469c8ba66bdc647e4
folderAsset: yes
timeCreated: 1492387122
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 52627c17e6dd4bf4dad4bdfc490ce823
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,91 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
namespace Spine.Unity.AnimationTools {
public static class TimelineExtensions {
/// <summary>Evaluates the resulting value of a TranslateTimeline at a given time.
/// 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>
public static Vector2 Evaluate (this TranslateTimeline timeline, float time, SkeletonData skeletonData = null) {
const int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
const int X = 1, Y = 2;
var frames = timeline.frames;
if (time < frames[0]) return Vector2.zero;
float x, y;
if (time >= frames[frames.Length - TranslateTimeline.ENTRIES]) { // Time is after last frame.
x = frames[frames.Length + PREV_X];
y = frames[frames.Length + PREV_Y];
}
else {
// Interpolate between the previous frame and the current frame.
int frame = Animation.BinarySearch(frames, time, TranslateTimeline.ENTRIES);
x = frames[frame + PREV_X];
y = frames[frame + PREV_Y];
float frameTime = frames[frame];
float percent = timeline.GetCurvePercent(frame / TranslateTimeline.ENTRIES - 1,
1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
x += (frames[frame + X] - x) * percent;
y += (frames[frame + Y] - y) * percent;
}
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.
/// You can get the boneIndex using SkeletonData.FindBoneIndex.
/// The root bone is always boneIndex 0.
/// This will return null if a TranslateTimeline is not found.</summary>
public static TranslateTimeline FindTranslateTimelineForBone (this Animation a, int boneIndex) {
foreach (var timeline in a.timelines) {
if (timeline.GetType().IsSubclassOf(typeof(TranslateTimeline)))
continue;
var translateTimeline = timeline as TranslateTimeline;
if (translateTimeline != null && translateTimeline.boneIndex == boneIndex)
return translateTimeline;
}
return null;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 07807fefbff25484ba41b1d16911fb0e
timeCreated: 1591974498
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,108 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections;
using System;
namespace Spine.Unity {
/// <summary>
/// Use this as a condition-blocking yield instruction for Unity Coroutines.
/// The routine will pause until the AnimationState.TrackEntry fires any of the
/// configured events.
/// <p/>
/// See the <see cref="http://esotericsoftware.com/spine-unity-events">Spine Unity Events documentation page</see>
/// and <see cref="http://esotericsoftware.com/spine-api-reference#AnimationStateListener"/>
/// for more information on when track events will be triggered.</summary>
public class WaitForSpineAnimation : IEnumerator {
[Flags]
public enum AnimationEventTypes
{
Start = 1,
Interrupt = 2,
End = 4,
Dispose = 8,
Complete = 16
}
bool m_WasFired = false;
public WaitForSpineAnimation (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) {
SafeSubscribe(trackEntry, eventsToWaitFor);
}
#region Reuse
/// <summary>
/// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure.
/// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete.</summary>
public WaitForSpineAnimation NowWaitFor (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) {
SafeSubscribe(trackEntry, eventsToWaitFor);
return this;
}
#endregion
#region IEnumerator
bool IEnumerator.MoveNext () {
if (m_WasFired) {
((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse
return false;
}
return true;
}
void IEnumerator.Reset () { m_WasFired = false; }
object IEnumerator.Current { get { return null; } }
#endregion
protected void SafeSubscribe (Spine.TrackEntry trackEntry, AnimationEventTypes eventsToWaitFor) {
if (trackEntry == null) {
// Break immediately if trackEntry is null.
Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately.");
m_WasFired = true;
}
else {
if ((eventsToWaitFor & AnimationEventTypes.Start) != 0)
trackEntry.Start += HandleComplete;
if ((eventsToWaitFor & AnimationEventTypes.Interrupt) != 0)
trackEntry.Interrupt += HandleComplete;
if ((eventsToWaitFor & AnimationEventTypes.End) != 0)
trackEntry.End += HandleComplete;
if ((eventsToWaitFor & AnimationEventTypes.Dispose) != 0)
trackEntry.Dispose += HandleComplete;
if ((eventsToWaitFor & AnimationEventTypes.Complete) != 0)
trackEntry.Complete += HandleComplete;
}
}
void HandleComplete (TrackEntry trackEntry) {
m_WasFired = true;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: d9be5adcaf0003849a1d181173c19635
timeCreated: 1566289729
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,62 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections;
using Spine;
namespace Spine.Unity {
/// <summary>
/// Use this as a condition-blocking yield instruction for Unity Coroutines.
/// The routine will pause until the AnimationState.TrackEntry fires its Complete event.
/// It can be configured to trigger on the End event as well to cover interruption.
/// <p/>
/// See the <see cref="http://esotericsoftware.com/spine-unity-events">Spine Unity Events documentation page</see>
/// and <see cref="http://esotericsoftware.com/spine-api-reference#AnimationStateListener"/>
/// for more information on when track events will be triggered.</summary>
public class WaitForSpineAnimationComplete : WaitForSpineAnimation, IEnumerator {
public WaitForSpineAnimationComplete (Spine.TrackEntry trackEntry, bool includeEndEvent = false) :
base(trackEntry,
includeEndEvent ? (AnimationEventTypes.Complete | AnimationEventTypes.End) : AnimationEventTypes.Complete)
{
}
#region Reuse
/// <summary>
/// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure.
/// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete.</summary>
public WaitForSpineAnimationComplete NowWaitFor (Spine.TrackEntry trackEntry, bool includeEndEvent = false) {
SafeSubscribe(trackEntry,
includeEndEvent ? (AnimationEventTypes.Complete | AnimationEventTypes.End) : AnimationEventTypes.Complete);
return this;
}
#endregion
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: a807dd9fb79db3545b6c2859a2bbfc0b
timeCreated: 1449704018
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,59 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections;
using Spine;
namespace Spine.Unity {
/// <summary>
/// Use this as a condition-blocking yield instruction for Unity Coroutines.
/// The routine will pause until the AnimationState.TrackEntry fires its End event.
/// <p/>
/// See the <see cref="http://esotericsoftware.com/spine-unity-events">Spine Unity Events documentation page</see>
/// and <see cref="http://esotericsoftware.com/spine-api-reference#AnimationStateListener"/>
/// for more information on when track events will be triggered.</summary>
public class WaitForSpineAnimationEnd : WaitForSpineAnimation, IEnumerator {
public WaitForSpineAnimationEnd (Spine.TrackEntry trackEntry) :
base(trackEntry, AnimationEventTypes.End)
{
}
#region Reuse
/// <summary>
/// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure.
/// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete.</summary>
public WaitForSpineAnimationEnd NowWaitFor (Spine.TrackEntry trackEntry) {
SafeSubscribe(trackEntry, AnimationEventTypes.End);
return this;
}
#endregion
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 3c5a5fe930d1ab24da154d76b24c2747
timeCreated: 1566288961
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,159 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections;
using Spine;
namespace Spine.Unity {
/// <summary>
/// Use this as a condition-blocking yield instruction for Unity Coroutines.
/// The routine will pause until the AnimationState fires an event matching the given event name or EventData reference.</summary>
public class WaitForSpineEvent : IEnumerator {
Spine.EventData m_TargetEvent;
string m_EventName;
Spine.AnimationState m_AnimationState;
bool m_WasFired = false;
bool m_unsubscribeAfterFiring = false;
#region Constructors
void Subscribe (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribe) {
if (state == null) {
Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately.");
m_WasFired = true;
return;
} else if (eventDataReference == null) {
Debug.LogWarning("eventDataReference argument was null. Coroutine will continue immediately.");
m_WasFired = true;
return;
}
m_AnimationState = state;
m_TargetEvent = eventDataReference;
state.Event += HandleAnimationStateEvent;
m_unsubscribeAfterFiring = unsubscribe;
}
void SubscribeByName (Spine.AnimationState state, string eventName, bool unsubscribe) {
if (state == null) {
Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately.");
m_WasFired = true;
return;
} else if (string.IsNullOrEmpty(eventName)) {
Debug.LogWarning("eventName argument was null. Coroutine will continue immediately.");
m_WasFired = true;
return;
}
m_AnimationState = state;
m_EventName = eventName;
state.Event += HandleAnimationStateEventByName;
m_unsubscribeAfterFiring = unsubscribe;
}
public WaitForSpineEvent (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) {
Subscribe(state, eventDataReference, unsubscribeAfterFiring);
}
public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) {
// If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine.
Subscribe(skeletonAnimation.state, eventDataReference, unsubscribeAfterFiring);
}
public WaitForSpineEvent (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) {
SubscribeByName(state, eventName, unsubscribeAfterFiring);
}
public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, string eventName, bool unsubscribeAfterFiring = true) {
// If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine.
SubscribeByName(skeletonAnimation.state, eventName, unsubscribeAfterFiring);
}
#endregion
#region Event Handlers
void HandleAnimationStateEventByName (Spine.TrackEntry trackEntry, Spine.Event e) {
m_WasFired |= (e.Data.Name == m_EventName); // Check event name string match.
if (m_WasFired && m_unsubscribeAfterFiring)
m_AnimationState.Event -= HandleAnimationStateEventByName; // Unsubscribe after correct event fires.
}
void HandleAnimationStateEvent (Spine.TrackEntry trackEntry, Spine.Event e) {
m_WasFired |= (e.Data == m_TargetEvent); // Check event data reference match.
if (m_WasFired && m_unsubscribeAfterFiring)
m_AnimationState.Event -= HandleAnimationStateEvent; // Usubscribe after correct event fires.
}
#endregion
#region Reuse
/// <summary>
/// By default, WaitForSpineEvent will unsubscribe from the event immediately after it fires a correct matching event.
/// If you want to reuse this WaitForSpineEvent instance on the same event, you can set this to false.</summary>
public bool WillUnsubscribeAfterFiring { get { return m_unsubscribeAfterFiring; } set { m_unsubscribeAfterFiring = value; } }
public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) {
((IEnumerator)this).Reset();
Clear(state);
Subscribe(state, eventDataReference, unsubscribeAfterFiring);
return this;
}
public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) {
((IEnumerator)this).Reset();
Clear(state);
SubscribeByName(state, eventName, unsubscribeAfterFiring);
return this;
}
void Clear (Spine.AnimationState state) {
state.Event -= HandleAnimationStateEvent;
state.Event -= HandleAnimationStateEventByName;
}
#endregion
#region IEnumerator
bool IEnumerator.MoveNext () {
if (m_WasFired) {
((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse
return false;
}
return true;
}
void IEnumerator.Reset () { m_WasFired = false; }
object IEnumerator.Current { get { return null; } }
#endregion
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: fc166d883db083e469872998172f2d38
timeCreated: 1449701857
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,85 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using System.Collections;
using Spine;
namespace Spine.Unity {
/// <summary>
/// Use this as a condition-blocking yield instruction for Unity Coroutines.
/// The routine will pause until the AnimationState.TrackEntry fires its End event.</summary>
public class WaitForSpineTrackEntryEnd : IEnumerator {
bool m_WasFired = false;
public WaitForSpineTrackEntryEnd (Spine.TrackEntry trackEntry) {
SafeSubscribe(trackEntry);
}
void HandleEnd (TrackEntry trackEntry) {
m_WasFired = true;
}
void SafeSubscribe (Spine.TrackEntry trackEntry) {
if (trackEntry == null) {
// Break immediately if trackEntry is null.
Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately.");
m_WasFired = true;
} else {
trackEntry.End += HandleEnd;
}
}
#region Reuse
/// <summary>
/// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure.
/// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationEnd.</summary>
public WaitForSpineTrackEntryEnd NowWaitFor (Spine.TrackEntry trackEntry) {
SafeSubscribe(trackEntry);
return this;
}
#endregion
#region IEnumerator
bool IEnumerator.MoveNext () {
if (m_WasFired) {
((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse
return false;
}
return true;
}
void IEnumerator.Reset () { m_WasFired = false; }
object IEnumerator.Current { get { return null; } }
#endregion
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 8036c6c2897d2764db92f632d2aef568
timeCreated: 1480672707
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,2 +0,0 @@
This Spine-Unity runtime works with data exported from Spine Editor version: 3.8.xx
Package version: spine-unity-3.8-2021-11-10.unitypackage

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 80c06a67282e71043a4b1fad3e0c5654
timeCreated: 1485965987
licenseType: Free
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant: