From 9ae48c2aac7beae57717eeaccf0fb99a567674c8 Mon Sep 17 00:00:00 2001 From: ZimM Date: Thu, 26 Feb 2015 05:00:44 +0200 Subject: [PATCH] replaced List with ExposedList to avoid indexer overhead --- spine-csharp/src/Animation.cs | 25 +- .../src/Attachments/SkinnedMeshAttachment.cs | 6 +- spine-csharp/src/Bone.cs | 4 +- spine-csharp/src/ExposedList.cs | 667 ++++++++++++++++++ spine-csharp/src/ExposedList.cs.meta | 8 + spine-csharp/src/IkConstraint.cs | 12 +- spine-csharp/src/Skeleton.cs | 112 +-- spine-csharp/src/SkeletonBounds.cs | 38 +- spine-csharp/src/Skin.cs | 2 +- .../spine-unity/Editor/SkeletonBaker.cs | 50 +- .../Editor/SkeletonDataAssetInspector.cs | 2 +- .../Assets/spine-unity/SkeletonRenderer.cs | 10 +- .../Editor/SkeletonUtilityBoneInspector.cs | 4 +- .../Editor/SkeletonUtilityInspector.cs | 2 +- .../SkeletonUtility/SkeletonUtility.cs | 10 +- 15 files changed, 816 insertions(+), 136 deletions(-) create mode 100644 spine-csharp/src/ExposedList.cs create mode 100644 spine-csharp/src/ExposedList.cs.meta diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index 672126e43..a31b12c10 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -233,7 +233,7 @@ namespace Spine { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. - Bone bone = skeleton.bones[boneIndex]; + Bone bone = skeleton.bones.Items[boneIndex]; float amount; @@ -296,7 +296,7 @@ namespace Spine { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. - Bone bone = skeleton.bones[boneIndex]; + Bone bone = skeleton.bones.Items[boneIndex]; if (time >= frames[frames.Length - 3]) { // Time is after last frame. bone.x += (bone.data.x + frames[frames.Length - 2] - bone.x) * alpha; @@ -326,7 +326,7 @@ namespace Spine { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. - Bone bone = skeleton.bones[boneIndex]; + Bone bone = skeleton.bones.Items[boneIndex]; if (time >= frames[frames.Length - 3]) { // Time is after last frame. bone.scaleX += (bone.data.scaleX * frames[frames.Length - 2] - bone.scaleX) * alpha; bone.scaleY += (bone.data.scaleY * frames[frames.Length - 1] - bone.scaleY) * alpha; @@ -402,7 +402,7 @@ namespace Spine { b = prevFrameB + (frames[frameIndex + FRAME_B] - prevFrameB) * percent; a = prevFrameA + (frames[frameIndex + FRAME_A] - prevFrameA) * percent; } - Slot slot = skeleton.slots[slotIndex]; + Slot slot = skeleton.slots.Items[slotIndex]; if (alpha < 1) { slot.r += (r - slot.r) * alpha; slot.g += (g - slot.g) * alpha; @@ -450,7 +450,7 @@ namespace Spine { if (frames[frameIndex] < lastTime) return; String attachmentName = attachmentNames[frameIndex]; - skeleton.slots[slotIndex].Attachment = + skeleton.slots.Items[slotIndex].Attachment = attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName); } } @@ -533,15 +533,16 @@ namespace Spine { else frameIndex = Animation.binarySearch(frames, time) - 1; - List drawOrder = skeleton.drawOrder; - List slots = skeleton.slots; + ExposedList drawOrder = skeleton.drawOrder; + ExposedList slots = skeleton.slots; int[] drawOrderToSetupIndex = drawOrders[frameIndex]; if (drawOrderToSetupIndex == null) { drawOrder.Clear(); - drawOrder.AddRange(slots); + for (int i = 0, n = slots.Count; i < n; i++) + drawOrder.Add(slots.Items[i]); } else { for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) - drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + drawOrder.Items[i] = slots.Items[drawOrderToSetupIndex[i]]; } } } @@ -570,7 +571,7 @@ namespace Spine { } override public void Apply (Skeleton skeleton, float lastTime, float time, List firedEvents, float alpha) { - Slot slot = skeleton.slots[slotIndex]; + Slot slot = skeleton.slots.Items[slotIndex]; if (slot.attachment != attachment) return; float[] frames = this.frames; @@ -652,7 +653,7 @@ namespace Spine { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. - IkConstraint ikConstraint = skeleton.ikConstraints[ikConstraintIndex]; + IkConstraint ikConstraint = skeleton.ikConstraints.Items[ikConstraintIndex]; if (time >= frames[frames.Length - 3]) { // Time is after last frame. ikConstraint.mix += (frames[frames.Length - 2] - ikConstraint.mix) * alpha; @@ -703,7 +704,7 @@ namespace Spine { int frameIndex = (time >= frames[frames.Length - 2] ? frames.Length : Animation.binarySearch(frames, time, 2)) - 2; if (frames[frameIndex] < lastTime) return; - SetFlip(skeleton.bones[boneIndex], frames[frameIndex + 1] != 0); + SetFlip(skeleton.bones.Items[boneIndex], frames[frameIndex + 1] != 0); } virtual protected void SetFlip (Bone bone, bool flip) { diff --git a/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs b/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs index fc7de7e00..1ef38d72c 100644 --- a/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs +++ b/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs @@ -95,7 +95,7 @@ namespace Spine { public void ComputeWorldVertices (Slot slot, float[] worldVertices) { Skeleton skeleton = slot.bone.skeleton; - List skeletonBones = skeleton.bones; + ExposedList skeletonBones = skeleton.bones; float x = skeleton.x, y = skeleton.y; float[] weights = this.weights; int[] bones = this.bones; @@ -104,7 +104,7 @@ namespace Spine { float wx = 0, wy = 0; int nn = bones[v++] + v; for (; v < nn; v++, b += 3) { - Bone bone = skeletonBones[bones[v]]; + Bone bone = skeletonBones.Items[bones[v]]; float vx = weights[b], vy = weights[b + 1], weight = weights[b + 2]; wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight; wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight; @@ -118,7 +118,7 @@ namespace Spine { float wx = 0, wy = 0; int nn = bones[v++] + v; for (; v < nn; v++, b += 3, f += 2) { - Bone bone = skeletonBones[bones[v]]; + Bone bone = skeletonBones.Items[bones[v]]; float vx = weights[b] + ffd[f], vy = weights[b + 1] + ffd[f + 1], weight = weights[b + 2]; wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight; wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight; diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs index 86546b2cd..9199697f8 100644 --- a/spine-csharp/src/Bone.cs +++ b/spine-csharp/src/Bone.cs @@ -38,7 +38,7 @@ namespace Spine { internal BoneData data; internal Skeleton skeleton; internal Bone parent; - internal List children = new List(); + internal ExposedList children = new ExposedList(); internal float x, y, rotation, rotationIK, scaleX, scaleY; internal bool flipX, flipY; internal float m00, m01, m10, m11; @@ -48,7 +48,7 @@ namespace Spine { public BoneData Data { get { return data; } } public Skeleton Skeleton { get { return skeleton; } } public Bone Parent { get { return parent; } } - public List Children { get { return children; } } + public ExposedList Children { get { return children; } } public float X { get { return x; } set { x = value; } } public float Y { get { return y; } set { y = value; } } /// The forward kinetics rotation. diff --git a/spine-csharp/src/ExposedList.cs b/spine-csharp/src/ExposedList.cs new file mode 100644 index 000000000..7d4469bf6 --- /dev/null +++ b/spine-csharp/src/ExposedList.cs @@ -0,0 +1,667 @@ +using System; +using System.Collections.Generic; + +namespace Spine { + /// + /// Represents a strongly typed list of objects that can be accessed by index. Provides methods to search and manipulate lists. + /// + /// The type of elements in the list. + public class ExposedList : IEnumerable { + private const int _defaultCapacity = 4; + private static readonly T[] _emptyArray = new T[0]; + public T[] Items; + + private int _size; + + /// + /// Initializes a new instance of the class that is empty and has the default initial capacity. + /// + public ExposedList() { + Items = _emptyArray; + } + + /// + /// Initializes a new instance of the class that is empty and has the specified initial capacity. + /// + /// The number of elements that the new list can initially store. + /// + /// is less than 0. + /// + public ExposedList(int capacity) { + if (capacity < 0) { + throw new ArgumentOutOfRangeException("capacity"); + } + Items = new T[capacity]; + } + + /// + /// Gets or sets the total number of elements the internal data structure can hold without resizing. + /// + /// + /// The number of elements that the can contain before resizing is required. + /// + /// + /// is set to a value that is less than + /// + /// . + /// + /// There is not enough memory available on the system. + public int Capacity { + get { + return Items.Length; + } + set { + if (value == Items.Length) { + return; + } + if (value < _size) { + throw new ArgumentOutOfRangeException("value"); + } + if (value > 0) { + var objArray = new T[value]; + if (_size > 0) { + Array.Copy(Items, 0, objArray, 0, _size); + } + Items = objArray; + } else { + Items = _emptyArray; + } + } + } + + /// + /// Gets the number of elements actually contained in the . + /// + /// + /// The number of elements actually contained in the . + /// + public int Count { + get { + return _size; + } + } + + /// + /// Adds an object to the end of the . + /// + /// + /// The object to be added to the end of the . The value can be null for reference types. + /// + public void Add(T item) { + if (_size == Items.Length) { + EnsureCapacity(_size + 1); + } + Items[_size++] = item; + } + + /// + /// Removes all elements from the . + /// + public void Clear() { + if (_size > 0) { + Array.Clear(Items, 0, _size); + _size = 0; + } + } + + /// + /// Determines whether an element is in the . + /// + /// + /// true if is found in the ; otherwise, false. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + public bool Contains(T item) { + if (item == null) { + for (int index = 0; index < _size; ++index) { + if (Items[index] == null) { + return true; + } + } + return false; + } else { + EqualityComparer @default = EqualityComparer.Default; + for (int index = 0; index < _size; ++index) { + if (@default.Equals(Items[index], item)) { + return true; + } + } + return false; + } + } + + /// + /// Copies the entire to a compatible one-dimensional array, starting at the specified index of the target array. + /// + /// + /// The one-dimensional that is the destination of the elements copied from + /// + /// . The must have zero-based indexing. + /// + /// + /// The zero-based index in at which copying begins. + /// + /// + /// is null. + /// + /// + /// is less than 0. + /// + /// + /// The number of elements in the source is greater than the available space from + /// + /// to the end of the destination . + /// + public void CopyTo(T[] array, int arrayIndex) { + Array.Copy(Items, 0, array, arrayIndex, _size); + } + + /// + /// Searches for the specified object and returns the zero-based index of the first occurrence within the entire + /// + /// . + /// + /// + /// The zero-based index of the first occurrence of within the entire + /// + /// , if found; otherwise, –1. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + public int IndexOf(T item) { + return Array.IndexOf(Items, item, 0, _size); + } + + /// + /// Inserts an element into the at the specified index. + /// + /// + /// The zero-based index at which should be inserted. + /// + /// The object to insert. The value can be null for reference types. + /// + /// is less than 0.-or- is greater than + /// + /// . + /// + public void Insert(int index, T item) { + if ((uint) index > (uint) _size) { + throw new ArgumentOutOfRangeException("index"); + } + if (_size == Items.Length) { + EnsureCapacity(_size + 1); + } + if (index < _size) { + Array.Copy(Items, index, Items, index + 1, _size - index); + } + Items[index] = item; + ++_size; + } + + /// + /// Removes the first occurrence of a specific object from the . + /// + /// + /// true if is successfully removed; otherwise, false. This method also returns false if + /// + /// was not found in the . + /// + /// + /// The object to remove from the . The value can be null for reference types. + /// + public bool Remove(T item) { + int index = IndexOf(item); + if (index < 0) { + return false; + } + RemoveAt(index); + return true; + } + + /// + /// Removes the element at the specified index of the . + /// + /// The zero-based index of the element to remove. + /// + /// is less than 0.-or- is equal to or greater than + /// + /// . + /// + public void RemoveAt(int index) { + if ((uint) index >= (uint) _size) { + throw new ArgumentOutOfRangeException(); + } + --_size; + if (index < _size) { + Array.Copy(Items, index + 1, Items, index, _size - index); + } + Items[_size] = default (T); + } + + /// + /// Copies the entire to a compatible one-dimensional array, starting at the beginning of the target array. + /// + /// + /// The one-dimensional that is the destination of the elements copied from + /// + /// . The must have zero-based indexing. + /// + /// + /// is null. + /// + /// + /// The number of elements in the source is greater than the number of elements that the destination + /// + /// can contain. + /// + public void CopyTo(T[] array) { + CopyTo(array, 0); + } + + /// + /// Copies a range of elements from the to a compatible one-dimensional array, starting at the specified index of the target array. + /// + /// + /// The zero-based index in the source at which copying begins. + /// + /// + /// The one-dimensional that is the destination of the elements copied from + /// + /// . The must have zero-based indexing. + /// + /// + /// The zero-based index in at which copying begins. + /// + /// The number of elements to copy. + /// + /// is null. + /// + /// + /// is less than 0.-or- is less than 0.-or- + /// + /// is less than 0. + /// + /// + /// is equal to or greater than the of the source + /// + /// .-or-The number of elements from to the end of the source + /// + /// is greater than the available space from + /// + /// to the end of the destination . + /// + public void CopyTo(int index, T[] array, int arrayIndex, int count) { + if (_size - index < count) { + throw new ArgumentException("Invalid length"); + } + Array.Copy(Items, index, array, arrayIndex, count); + } + + private void EnsureCapacity(int min) { + if (Items.Length >= min) { + return; + } + int num = Items.Length == 0 ? 4 : Items.Length * 2; + if (num < min) { + num = min; + } + Capacity = num; + } + + /// + /// Creates a shallow copy of a range of elements in the source . + /// + /// + /// A shallow copy of a range of elements in the source . + /// + /// + /// The zero-based index at which the range starts. + /// + /// The number of elements in the range. + /// + /// is less than 0.-or- is less than 0. + /// + /// + /// and do not denote a valid range of elements in the + /// + /// . + /// + public ExposedList GetRange(int index, int count) { + if (index < 0 || count < 0) { + throw new ArgumentOutOfRangeException("index || count"); + } + if (_size - index < count) { + throw new ArgumentException("Invalid length"); + } + var list = new ExposedList(count); + Array.Copy(Items, index, list.Items, 0, count); + list._size = count; + return list; + } + + /// + /// Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the + /// + /// that extends from the specified index to the last element. + /// + /// + /// The zero-based index of the first occurrence of within the range of elements in the + /// + /// that extends from to the last element, if found; otherwise, –1. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + /// The zero-based starting index of the search. 0 (zero) is valid in an empty list. + /// + /// is outside the range of valid indexes for the + /// + /// . + /// + public int IndexOf(T item, int index) { + if (index > _size) { + throw new ArgumentOutOfRangeException("index"); + } + return Array.IndexOf(Items, item, index, _size - index); + } + + /// + /// Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the + /// + /// that starts at the specified index and contains the specified number of elements. + /// + /// + /// The zero-based index of the first occurrence of within the range of elements in the + /// + /// that starts at and contains + /// + /// number of elements, if found; otherwise, –1. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + /// The zero-based starting index of the search. 0 (zero) is valid in an empty list. + /// The number of elements in the section to search. + /// + /// is outside the range of valid indexes for the + /// + /// .-or- is less than 0.-or- + /// + /// and do not specify a valid section in the + /// + /// . + /// + public int IndexOf(T item, int index, int count) { + if (index > _size) { + throw new ArgumentOutOfRangeException("index"); + } + if (count < 0 || index > _size - count) { + throw new ArgumentOutOfRangeException("count"); + } + return Array.IndexOf(Items, item, index, count); + } + + /// + /// Searches for the specified object and returns the zero-based index of the last occurrence within the entire + /// + /// . + /// + /// + /// The zero-based index of the last occurrence of within the entire the + /// + /// , if found; otherwise, –1. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + public int LastIndexOf(T item) { + return LastIndexOf(item, _size - 1, _size); + } + + /// + /// Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the + /// + /// that extends from the first element to the specified index. + /// + /// + /// The zero-based index of the last occurrence of within the range of elements in the + /// + /// that extends from the first element to , if found; otherwise, –1. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + /// The zero-based starting index of the backward search. + /// + /// is outside the range of valid indexes for the + /// + /// . + /// + public int LastIndexOf(T item, int index) { + if (index >= _size) { + throw new ArgumentOutOfRangeException("index"); + } + return LastIndexOf(item, index, index + 1); + } + + /// + /// Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the + /// + /// that contains the specified number of elements and ends at the specified index. + /// + /// + /// The zero-based index of the last occurrence of within the range of elements in the + /// + /// that contains number of elements and ends at + /// + /// , if found; otherwise, –1. + /// + /// + /// The object to locate in the . The value can be null for reference types. + /// + /// The zero-based starting index of the backward search. + /// The number of elements in the section to search. + /// + /// is outside the range of valid indexes for the + /// + /// .-or- is less than 0.-or- + /// + /// and do not specify a valid section in the + /// + /// . + /// + public int LastIndexOf(T item, int index, int count) { + if (_size == 0) { + return -1; + } + if (index < 0 || count < 0) { + throw new ArgumentOutOfRangeException("index || count"); + } + if (index >= _size || count > index + 1) { + throw new ArgumentOutOfRangeException("size || count"); + } + return Array.LastIndexOf(Items, item, index, count); + } + + /// + /// Removes a range of elements from the . + /// + /// The zero-based starting index of the range of elements to remove. + /// The number of elements to remove. + /// + /// is less than 0.-or- is less than 0. + /// + /// + /// and do not denote a valid range of elements in the + /// + /// . + /// + public void RemoveRange(int index, int count) { + if (index < 0 || count < 0) { + throw new ArgumentOutOfRangeException("index || count"); + } + if (_size - index < count) { + throw new ArgumentException("Invalid length"); + } + if (count <= 0) { + return; + } + _size -= count; + if (index < _size) { + Array.Copy(Items, index + count, Items, index, _size - index); + } + Array.Clear(Items, _size, count); + } + + //public void Sort(Comparison comparison) + //{ + // if (comparison == null) + // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); + // if (this._size <= 0) + // return; + // Array.Sort(this._items, 0, this._size, (IComparer) new Array.FunctorComparer(comparison)); + //} + /// + /// Sorts the elements in the entire using the specified + /// + /// . + /// + /// + /// The to use when comparing elements. + /// + /// + /// is null. + /// + /// + /// The implementation of caused an error during the sort. For example, + /// + /// might not return 0 when comparing an item with itself. + /// + /// + /// Copies the elements of the to a new array. + /// + /// + /// An array containing copies of the elements of the . + /// + public T[] ToArray() { + var objArray = new T[_size]; + Array.Copy(Items, 0, objArray, 0, _size); + return objArray; + } + + // Returns an enumerator for this list with the given + // permission for removal of elements. If modifications made to the list + // while an enumeration is in progress, the MoveNext and + // GetObject methods of the enumerator will throw an exception. + // + public Enumerator GetEnumerator() { + return new Enumerator(this); + } + + /// + IEnumerator IEnumerable.GetEnumerator() { + return new Enumerator(this); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + return new Enumerator(this); + } + + [Serializable()] + public struct Enumerator : IEnumerator, System.Collections.IEnumerator + { + private readonly ExposedList _list; + private int _index; + private T _current; + + internal Enumerator(ExposedList list) { + _list = list; + _index = 0; + _current = default(T); + } + + public void Dispose() { + } + + public bool MoveNext() { + ExposedList localList = _list; + + if (((uint)_index < (uint)localList._size)) { + _current = localList.Items[_index]; + _index++; + return true; + } + return MoveNextRare(); + } + + private bool MoveNextRare() + { + _index = _list._size + 1; + _current = default(T); + return false; + } + + public T Current { + get { + return _current; + } + } + + Object System.Collections.IEnumerator.Current { + get { + if( _index == 0 || _index == _list._size + 1) + throw new InvalidOperationException(); + return Current; + } + } + + void System.Collections.IEnumerator.Reset() { + _index = 0; + _current = default(T); + } + + } + } +} \ No newline at end of file diff --git a/spine-csharp/src/ExposedList.cs.meta b/spine-csharp/src/ExposedList.cs.meta new file mode 100644 index 000000000..e12f21463 --- /dev/null +++ b/spine-csharp/src/ExposedList.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 540cf6a03c85e284e83831880e3f25a8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-csharp/src/IkConstraint.cs b/spine-csharp/src/IkConstraint.cs index a2816e796..a49e5d40e 100644 --- a/spine-csharp/src/IkConstraint.cs +++ b/spine-csharp/src/IkConstraint.cs @@ -36,13 +36,13 @@ namespace Spine { private const float radDeg = 180 / (float)Math.PI; internal IkConstraintData data; - internal List bones = new List(); + internal ExposedList bones = new ExposedList(); internal Bone target; internal int bendDirection; internal float mix; public IkConstraintData Data { get { return data; } } - public List Bones { get { return bones; } } + public ExposedList Bones { get { return bones; } } public Bone Target { get { return target; } set { target = value; } } public int BendDirection { get { return bendDirection; } set { bendDirection = value; } } public float Mix { get { return mix; } set { mix = value; } } @@ -54,7 +54,7 @@ namespace Spine { mix = data.mix; bendDirection = data.bendDirection; - bones = new List(data.bones.Count); + bones = new ExposedList(data.bones.Count); foreach (BoneData boneData in data.bones) bones.Add(skeleton.FindBone(boneData.name)); target = skeleton.FindBone(data.target.name); @@ -62,13 +62,13 @@ namespace Spine { public void apply () { Bone target = this.target; - List bones = this.bones; + ExposedList bones = this.bones; switch (bones.Count) { case 1: - apply(bones[0], target.worldX, target.worldY, mix); + apply(bones.Items[0], target.worldX, target.worldY, mix); break; case 2: - apply(bones[0], bones[1], target.worldX, target.worldY, bendDirection, mix); + apply(bones.Items[0], bones.Items[1], target.worldX, target.worldY, bendDirection, mix); break; } } diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index 0e032dba5..56f1c421b 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -34,11 +34,11 @@ using System.Collections.Generic; namespace Spine { public class Skeleton { internal SkeletonData data; - internal List bones; - internal List slots; - internal List drawOrder; - internal List ikConstraints; - private List> boneCache = new List>(); + internal ExposedList bones; + internal ExposedList slots; + internal ExposedList drawOrder; + internal ExposedList ikConstraints; + private ExposedList> boneCache = new ExposedList>(); internal Skin skin; internal float r = 1, g = 1, b = 1, a = 1; internal float time; @@ -46,10 +46,10 @@ namespace Spine { internal float x, y; public SkeletonData Data { get { return data; } } - public List Bones { get { return bones; } } - public List Slots { get { return slots; } } - public List DrawOrder { get { return drawOrder; } } - public List IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } } + public ExposedList Bones { get { return bones; } } + public ExposedList Slots { get { return slots; } } + public ExposedList DrawOrder { get { return drawOrder; } } + public ExposedList IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } } public Skin Skin { get { return skin; } set { skin = value; } } public float R { get { return r; } set { r = value; } } public float G { get { return g; } set { g = value; } } @@ -63,7 +63,7 @@ namespace Spine { public Bone RootBone { get { - return bones.Count == 0 ? null : bones[0]; + return bones.Count == 0 ? null : bones.Items[0]; } } @@ -71,24 +71,24 @@ namespace Spine { if (data == null) throw new ArgumentNullException("data cannot be null."); this.data = data; - bones = new List(data.bones.Count); + bones = new ExposedList(data.bones.Count); foreach (BoneData boneData in data.bones) { - Bone parent = boneData.parent == null ? null : bones[data.bones.IndexOf(boneData.parent)]; + Bone parent = boneData.parent == null ? null : bones.Items[data.bones.IndexOf(boneData.parent)]; Bone bone = new Bone(boneData, this, parent); if (parent != null) parent.children.Add(bone); bones.Add(bone); } - slots = new List(data.slots.Count); - drawOrder = new List(data.slots.Count); + slots = new ExposedList(data.slots.Count); + drawOrder = new ExposedList(data.slots.Count); foreach (SlotData slotData in data.slots) { - Bone bone = bones[data.bones.IndexOf(slotData.boneData)]; + Bone bone = bones.Items[data.bones.IndexOf(slotData.boneData)]; Slot slot = new Slot(slotData, bone); slots.Add(slot); drawOrder.Add(slot); } - ikConstraints = new List(data.ikConstraints.Count); + ikConstraints = new ExposedList(data.ikConstraints.Count); foreach (IkConstraintData ikConstraintData in data.ikConstraints) ikConstraints.Add(new IkConstraint(ikConstraintData, this)); @@ -98,31 +98,31 @@ namespace Spine { /// Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or /// removed. public void UpdateCache () { - List> boneCache = this.boneCache; - List ikConstraints = this.ikConstraints; + ExposedList> boneCache = this.boneCache; + ExposedList ikConstraints = this.ikConstraints; int ikConstraintsCount = ikConstraints.Count; int arrayCount = ikConstraintsCount + 1; if (boneCache.Count > arrayCount) boneCache.RemoveRange(arrayCount, boneCache.Count - arrayCount); for (int i = 0, n = boneCache.Count; i < n; i++) - boneCache[i].Clear(); + boneCache.Items[i].Clear(); while (boneCache.Count < arrayCount) - boneCache.Add(new List()); + boneCache.Add(new ExposedList()); - List nonIkBones = boneCache[0]; + ExposedList nonIkBones = boneCache.Items[0]; for (int i = 0, n = bones.Count; i < n; i++) { - Bone bone = bones[i]; + Bone bone = bones.Items[i]; Bone current = bone; do { for (int ii = 0; ii < ikConstraintsCount; ii++) { - IkConstraint ikConstraint = ikConstraints[ii]; - Bone parent = ikConstraint.bones[0]; - Bone child = ikConstraint.bones[ikConstraint.bones.Count - 1]; + IkConstraint ikConstraint = ikConstraints.Items[ii]; + Bone parent = ikConstraint.bones.Items[0]; + Bone child = ikConstraint.bones.Items[ikConstraint.bones.Count - 1]; while (true) { if (current == child) { - boneCache[ii].Add(bone); - boneCache[ii + 1].Add(bone); + boneCache.Items[ii].Add(bone); + boneCache.Items[ii + 1].Add(bone); goto outer; } if (child == parent) break; @@ -138,20 +138,20 @@ namespace Spine { /// Updates the world transform for each bone and applies IK constraints. public void UpdateWorldTransform () { - List bones = this.bones; + ExposedList bones = this.bones; for (int ii = 0, nn = bones.Count; ii < nn; ii++) { - Bone bone = bones[ii]; + Bone bone = bones.Items[ii]; bone.rotationIK = bone.rotation; } - List> boneCache = this.boneCache; - List ikConstraints = this.ikConstraints; + ExposedList> boneCache = this.boneCache; + ExposedList ikConstraints = this.ikConstraints; int i = 0, last = boneCache.Count - 1; while (true) { - List updateBones = boneCache[i]; + ExposedList updateBones = boneCache.Items[i]; for (int ii = 0, nn = updateBones.Count; ii < nn; ii++) - updateBones[ii].UpdateWorldTransform(); + updateBones.Items[ii].UpdateWorldTransform(); if (i == last) break; - ikConstraints[i].apply(); + ikConstraints.Items[i].apply(); i++; } } @@ -163,32 +163,34 @@ namespace Spine { } public void SetBonesToSetupPose () { - List bones = this.bones; + ExposedList bones = this.bones; for (int i = 0, n = bones.Count; i < n; i++) - bones[i].SetToSetupPose(); + bones.Items[i].SetToSetupPose(); - List ikConstraints = this.ikConstraints; + ExposedList ikConstraints = this.ikConstraints; for (int i = 0, n = ikConstraints.Count; i < n; i++) { - IkConstraint ikConstraint = ikConstraints[i]; + IkConstraint ikConstraint = ikConstraints.Items[i]; ikConstraint.bendDirection = ikConstraint.data.bendDirection; ikConstraint.mix = ikConstraint.data.mix; } } public void SetSlotsToSetupPose () { - List slots = this.slots; + ExposedList slots = this.slots; drawOrder.Clear(); - drawOrder.AddRange(slots); + for (int i = 0, n = slots.Count; i < n; i++) + drawOrder.Add(slots.Items[i]); + for (int i = 0, n = slots.Count; i < n; i++) - slots[i].SetToSetupPose(i); + slots.Items[i].SetToSetupPose(i); } /// May be null. public Bone FindBone (String boneName) { if (boneName == null) throw new ArgumentNullException("boneName cannot be null."); - List bones = this.bones; + ExposedList bones = this.bones; for (int i = 0, n = bones.Count; i < n; i++) { - Bone bone = bones[i]; + Bone bone = bones.Items[i]; if (bone.data.name == boneName) return bone; } return null; @@ -197,18 +199,18 @@ namespace Spine { /// -1 if the bone was not found. public int FindBoneIndex (String boneName) { if (boneName == null) throw new ArgumentNullException("boneName cannot be null."); - List bones = this.bones; + ExposedList bones = this.bones; for (int i = 0, n = bones.Count; i < n; i++) - if (bones[i].data.name == boneName) return i; + if (bones.Items[i].data.name == boneName) return i; return -1; } /// May be null. public Slot FindSlot (String slotName) { if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); - List slots = this.slots; + ExposedList slots = this.slots; for (int i = 0, n = slots.Count; i < n; i++) { - Slot slot = slots[i]; + Slot slot = slots.Items[i]; if (slot.data.name == slotName) return slot; } return null; @@ -217,9 +219,9 @@ namespace Spine { /// -1 if the bone was not found. public int FindSlotIndex (String slotName) { if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); - List slots = this.slots; + ExposedList slots = this.slots; for (int i = 0, n = slots.Count; i < n; i++) - if (slots[i].data.name.Equals(slotName)) return i; + if (slots.Items[i].data.name.Equals(slotName)) return i; return -1; } @@ -239,9 +241,9 @@ namespace Spine { if (skin != null) newSkin.AttachAll(this, skin); else { - List slots = this.slots; + ExposedList slots = this.slots; for (int i = 0, n = slots.Count; i < n; i++) { - Slot slot = slots[i]; + Slot slot = slots.Items[i]; String name = slot.data.attachmentName; if (name != null) { Attachment attachment = newSkin.GetAttachment(i, name); @@ -272,9 +274,9 @@ namespace Spine { /// May be null. public void SetAttachment (String slotName, String attachmentName) { if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); - List slots = this.slots; + ExposedList slots = this.slots; for (int i = 0, n = slots.Count; i < n; i++) { - Slot slot = slots[i]; + Slot slot = slots.Items[i]; if (slot.data.name == slotName) { Attachment attachment = null; if (attachmentName != null) { @@ -291,9 +293,9 @@ namespace Spine { /** @return May be null. */ public IkConstraint FindIkConstraint (String ikConstraintName) { if (ikConstraintName == null) throw new ArgumentNullException("ikConstraintName cannot be null."); - List ikConstraints = this.ikConstraints; + ExposedList ikConstraints = this.ikConstraints; for (int i = 0, n = ikConstraints.Count; i < n; i++) { - IkConstraint ikConstraint = ikConstraints[i]; + IkConstraint ikConstraint = ikConstraints.Items[i]; if (ikConstraint.data.name == ikConstraintName) return ikConstraint; } return null; diff --git a/spine-csharp/src/SkeletonBounds.cs b/spine-csharp/src/SkeletonBounds.cs index 4c546d76c..0c1a146f2 100644 --- a/spine-csharp/src/SkeletonBounds.cs +++ b/spine-csharp/src/SkeletonBounds.cs @@ -33,11 +33,11 @@ using System.Collections.Generic; namespace Spine { public class SkeletonBounds { - private List polygonPool = new List(); + private ExposedList polygonPool = new ExposedList(); private float minX, minY, maxX, maxY; - public List BoundingBoxes { get; private set; } - public List Polygons { get; private set; } + public ExposedList BoundingBoxes { get; private set; } + public ExposedList Polygons { get; private set; } public float MinX { get { return minX; } set { minX = value; } } public float MinY { get { return minY; } set { minY = value; } } public float MaxX { get { return maxX; } set { maxX = value; } } @@ -46,23 +46,23 @@ namespace Spine { public float Height { get { return maxY - minY; } } public SkeletonBounds () { - BoundingBoxes = new List(); - Polygons = new List(); + BoundingBoxes = new ExposedList(); + Polygons = new ExposedList(); } public void Update (Skeleton skeleton, bool updateAabb) { - List boundingBoxes = BoundingBoxes; - List polygons = Polygons; - List slots = skeleton.slots; + ExposedList boundingBoxes = BoundingBoxes; + ExposedList polygons = Polygons; + ExposedList slots = skeleton.slots; int slotCount = slots.Count; boundingBoxes.Clear(); - foreach (Polygon polygon in polygons) - polygonPool.Add(polygon); + for (int i = 0, n = polygons.Count; i < n; i++) + polygonPool.Add(polygons.Items[n]); polygons.Clear(); for (int i = 0; i < slotCount; i++) { - Slot slot = slots[i]; + Slot slot = slots.Items[i]; BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment; if (boundingBox == null) continue; boundingBoxes.Add(boundingBox); @@ -70,7 +70,7 @@ namespace Spine { Polygon polygon = null; int poolCount = polygonPool.Count; if (poolCount > 0) { - polygon = polygonPool[poolCount - 1]; + polygon = polygonPool.Items[poolCount - 1]; polygonPool.RemoveAt(poolCount - 1); } else polygon = new Polygon(); @@ -87,9 +87,9 @@ namespace Spine { private void aabbCompute () { float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; - List polygons = Polygons; + ExposedList polygons = Polygons; for (int i = 0, n = polygons.Count; i < n; i++) { - Polygon polygon = polygons[i]; + Polygon polygon = polygons.Items[i]; float[] vertices = polygon.Vertices; for (int ii = 0, nn = polygon.Count; ii < nn; ii += 2) { float x = vertices[ii]; @@ -159,18 +159,18 @@ namespace Spine { /// Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more /// efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. public BoundingBoxAttachment ContainsPoint (float x, float y) { - List polygons = Polygons; + ExposedList polygons = Polygons; for (int i = 0, n = polygons.Count; i < n; i++) - if (ContainsPoint(polygons[i], x, y)) return BoundingBoxes[i]; + if (ContainsPoint(polygons.Items[i], x, y)) return BoundingBoxes.Items[i]; return null; } /// Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually /// more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. public BoundingBoxAttachment IntersectsSegment (float x1, float y1, float x2, float y2) { - List polygons = Polygons; + ExposedList polygons = Polygons; for (int i = 0, n = polygons.Count; i < n; i++) - if (IntersectsSegment(polygons[i], x1, y1, x2, y2)) return BoundingBoxes[i]; + if (IntersectsSegment(polygons.Items[i], x1, y1, x2, y2)) return BoundingBoxes.Items[i]; return null; } @@ -200,7 +200,7 @@ namespace Spine { public Polygon getPolygon (BoundingBoxAttachment attachment) { int index = BoundingBoxes.IndexOf(attachment); - return index == -1 ? null : Polygons[index]; + return index == -1 ? null : Polygons.Items[index]; } } diff --git a/spine-csharp/src/Skin.cs b/spine-csharp/src/Skin.cs index e8e68d3dc..7b4c57b15 100644 --- a/spine-csharp/src/Skin.cs +++ b/spine-csharp/src/Skin.cs @@ -77,7 +77,7 @@ namespace Spine { internal void AttachAll (Skeleton skeleton, Skin oldSkin) { foreach (KeyValuePair, Attachment> entry in oldSkin.attachments) { int slotIndex = entry.Key.Key; - Slot slot = skeleton.slots[slotIndex]; + Slot slot = skeleton.slots.Items[slotIndex]; if (slot.attachment == entry.Value) { Attachment attachment = GetAttachment(slotIndex, entry.Key.Value); if (attachment != null) slot.Attachment = attachment; diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs index 74fcc2899..4fa1a0161 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs @@ -640,7 +640,7 @@ public static class SkeletonBaker { skeleton.UpdateWorldTransform(); float[] floatVerts = new float[attachment.UVs.Length]; - attachment.ComputeWorldVertices(skeleton.Slots[slotIndex], floatVerts); + attachment.ComputeWorldVertices(skeleton.Slots.Items[slotIndex], floatVerts); Vector2[] uvs = ExtractUV(attachment.UVs); Vector3[] verts = ExtractVerts(floatVerts); @@ -807,26 +807,26 @@ public static class SkeletonBaker { List ignoreRotateTimelineIndexes = new List(); - if (bakeIK) { - foreach (IkConstraint i in skeleton.IkConstraints) { - foreach (Bone b in i.Bones) { - int index = skeleton.FindBoneIndex(b.Data.Name); - ignoreRotateTimelineIndexes.Add(index); - BakeBone(b, animation, clip); - } - } - } + //if (bakeIK) { + // foreach (IkConstraint i in skeleton.IkConstraints) { + // foreach (Bone b in i.Bones) { + // int index = skeleton.FindBoneIndex(b.Data.Name); + // ignoreRotateTimelineIndexes.Add(index); + // BakeBone(b, animation, clip); + // } + // } + //} - foreach (Bone b in skeleton.Bones) { - if (b.Data.InheritRotation == false) { - int index = skeleton.FindBoneIndex(b.Data.Name); + //foreach (Bone b in skeleton.Bones) { + // if (b.Data.InheritRotation == false) { + // int index = skeleton.FindBoneIndex(b.Data.Name); - if (ignoreRotateTimelineIndexes.Contains(index) == false) { - ignoreRotateTimelineIndexes.Add(index); - BakeBone(b, animation, clip); - } - } - } + // if (ignoreRotateTimelineIndexes.Contains(index) == false) { + // ignoreRotateTimelineIndexes.Add(index); + // BakeBone(b, animation, clip); + // } + // } + //} foreach (Timeline t in timelines) { skeleton.SetToSetupPose(); @@ -911,8 +911,8 @@ public static class SkeletonBaker { static void ParseAttachmentTimeline (Skeleton skeleton, AttachmentTimeline timeline, Dictionary> slotLookup, AnimationClip clip) { var attachmentNames = slotLookup[timeline.SlotIndex]; - string bonePath = GetPath(skeleton.Slots[timeline.SlotIndex].Bone.Data); - string slotPath = bonePath + "/" + skeleton.Slots[timeline.SlotIndex].Data.Name; + string bonePath = GetPath(skeleton.Slots.Items[timeline.SlotIndex].Bone.Data); + string slotPath = bonePath + "/" + skeleton.Slots.Items[timeline.SlotIndex].Data.Name; Dictionary curveTable = new Dictionary(); @@ -923,7 +923,7 @@ public static class SkeletonBaker { float[] frames = timeline.Frames; if (frames[0] != 0) { - string startingName = skeleton.Slots[timeline.SlotIndex].Data.AttachmentName; + string startingName = skeleton.Slots.Items[timeline.SlotIndex].Data.AttachmentName; foreach (var pair in curveTable) { if (startingName == "" || startingName == null) { pair.Value.AddKey(new Keyframe(0, 0, float.PositiveInfinity, float.PositiveInfinity)); @@ -1062,7 +1062,7 @@ public static class SkeletonBaker { static void ParseTranslateTimeline (Skeleton skeleton, TranslateTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; - var bone = skeleton.Bones[timeline.BoneIndex]; + var bone = skeleton.Bones.Items[timeline.BoneIndex]; AnimationCurve xCurve = new AnimationCurve(); AnimationCurve yCurve = new AnimationCurve(); @@ -1208,7 +1208,7 @@ public static class SkeletonBaker { static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; - var bone = skeleton.Bones[timeline.BoneIndex]; + var bone = skeleton.Bones.Items[timeline.BoneIndex]; AnimationCurve xCurve = new AnimationCurve(); AnimationCurve yCurve = new AnimationCurve(); @@ -1341,7 +1341,7 @@ public static class SkeletonBaker { static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; - var bone = skeleton.Bones[timeline.BoneIndex]; + var bone = skeleton.Bones.Items[timeline.BoneIndex]; AnimationCurve curve = new AnimationCurve(); diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs index 83bbef004..81d2c37a0 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs @@ -357,7 +357,7 @@ public class SkeletonDataAssetInspector : Editor { } for (int i = m_skeletonAnimation.skeleton.Slots.Count - 1; i >= 0; i--) { - Slot slot = m_skeletonAnimation.skeleton.Slots[i]; + Slot slot = m_skeletonAnimation.skeleton.Slots.Items[i]; EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, SpineEditorUtilities.Icons.slot)); if (showAttachments) { diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index 48b2c745e..450e7b50b 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs @@ -173,11 +173,11 @@ public class SkeletonRenderer : MonoBehaviour { int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0; Material lastMaterial = null; submeshMaterials.Clear(); - List drawOrder = skeleton.DrawOrder; + ExposedList drawOrder = skeleton.DrawOrder; int drawOrderCount = drawOrder.Count; bool renderMeshes = this.renderMeshes; for (int i = 0; i < drawOrderCount; i++) { - Slot slot = drawOrder[i]; + Slot slot = drawOrder.Items[i]; Attachment attachment = slot.attachment; object rendererObject; @@ -254,7 +254,7 @@ public class SkeletonRenderer : MonoBehaviour { float zSpacing = this.zSpacing; float a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b; for (int i = 0; i < drawOrderCount; i++) { - Slot slot = drawOrder[i]; + Slot slot = drawOrder.Items[i]; Attachment attachment = slot.attachment; if (attachment is RegionAttachment) { RegionAttachment regionAttachment = (RegionAttachment)attachment; @@ -413,9 +413,9 @@ public class SkeletonRenderer : MonoBehaviour { } // Store triangles. - List drawOrder = skeleton.DrawOrder; + ExposedList drawOrder = skeleton.DrawOrder; for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) { - Slot slot = drawOrder[i]; + Slot slot = drawOrder.Items[i]; Attachment attachment = slot.attachment; Bone bone = slot.bone; bool flip = frontFacing && ((bone.WorldFlipX != bone.WorldFlipY) != (Mathf.Sign(bone.WorldScaleX) != Mathf.Sign(bone.WorldScaleY))); diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs index f8d6d7340..52f3f71b3 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs @@ -190,14 +190,14 @@ public class SkeletonUtilityBoneInspector : Editor { } } - void BoneSelectorContextMenu (string current, List bones, string topValue, GenericMenu.MenuFunction2 callback) { + void BoneSelectorContextMenu (string current, ExposedList bones, string topValue, GenericMenu.MenuFunction2 callback) { GenericMenu menu = new GenericMenu(); if (topValue != "") menu.AddItem(new GUIContent(topValue), current == topValue, callback, null); for (int i = 0; i < bones.Count; i++) { - menu.AddItem(new GUIContent(bones[i].Data.Name), bones[i].Data.Name == current, callback, bones[i]); + menu.AddItem(new GUIContent(bones.Items[i].Data.Name), bones.Items[i].Data.Name == current, callback, bones.Items[i]); } menu.ShowAsContext(); diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs index 4c6d02d09..e955bbd71 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs @@ -160,7 +160,7 @@ public class SkeletonUtilityInspector : Editor { List attachments = new List(); skin.FindAttachmentsForSlot(i, attachments); - attachmentTable.Add(skeleton.Slots[i], attachments); + attachmentTable.Add(skeleton.Slots.Items[i], attachments); } } diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs index 519c0e313..37e84e884 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs @@ -170,9 +170,9 @@ public class SkeletonUtility : MonoBehaviour { if (boneRoot != null) { List constraintTargetNames = new List(); - foreach (IkConstraint c in skeletonRenderer.skeleton.IkConstraints) { - constraintTargetNames.Add(c.Target.Data.Name); - } + ExposedList ikConstraints = skeletonRenderer.skeleton.IkConstraints; + for (int i = 0, n = ikConstraints.Count; i < n; i++) + constraintTargetNames.Add(ikConstraints.Items[n].Target.Data.Name); foreach (var b in utilityBones) { if (b.bone == null) { @@ -289,7 +289,9 @@ public class SkeletonUtility : MonoBehaviour { public GameObject SpawnBoneRecursively (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) { GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca); - foreach (Bone child in bone.Children) { + ExposedList childrenBones = bone.Children; + for (int i = 0, n = childrenBones.Count; i < n; i++) { + Bone child = childrenBones.Items[i]; SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca); }