diff --git a/spine-lua/Animation.lua b/spine-lua/Animation.lua index 9f33f3144..205427150 100644 --- a/spine-lua/Animation.lua +++ b/spine-lua/Animation.lua @@ -413,9 +413,16 @@ function Animation.AttachmentTimeline.new () end local attachmentName = self.attachmentNames[frameIndex] - local attachment - if attachmentName then attachment = skeleton:getAttachment(self.slotName, attachmentName) end - skeleton:findSlot(self.slotName):setAttachment(attachment) + local slot = skeleton.slotsByName[self.slotName] + if attachmentName then + if not slot.attachment then + slot:setAttachment(skeleton:getAttachment(self.slotName, attachmentName)) + elseif slot.attachment.name ~= attachmentName then + slot:setAttachment(skeleton:getAttachment(self.slotName, attachmentName)) + end + else + slot:setAttachment(nil) + end end return self diff --git a/spine-lua/Skeleton.lua b/spine-lua/Skeleton.lua index 2626de810..b19ad86c9 100644 --- a/spine-lua/Skeleton.lua +++ b/spine-lua/Skeleton.lua @@ -35,6 +35,7 @@ function Skeleton.new (skeletonData) data = skeletonData, bones = {}, slots = {}, + slotsByName = {}, drawOrder = {} } @@ -73,13 +74,10 @@ function Skeleton.new (skeletonData) return nil end - function self:findSlot (slotName) - if not slotName then error("slotName cannot be nil.", 2) end - for i,slot in ipairs(self.slots) do - if slot.data.name == slotName then return slot end - end - return nil - end + function self:findSlot (slotName) + if not slotName then error("slotName cannot be nil.", 2) end + return slotsByName[slotName] + end function self:setSkin (skinName) local newSkin @@ -106,7 +104,7 @@ function Skeleton.new (skeletonData) function self:getAttachment (slotName, attachmentName) if not slotName then error("slotName cannot be nil.", 2) end if not attachmentName then error("attachmentName cannot be nil.", 2) end - local slotIndex = self.data:findSlotIndex(slotName) + local slotIndex = skeletonData.slotNameIndices[slotName] if slotIndex == -1 then error("Slot not found: " .. slotName, 2) end if self.skin then local attachment = self.skin:getAttachment(slotIndex, attachmentName) @@ -147,6 +145,7 @@ function Skeleton.new (skeletonData) local bone = self.bones[spine.utils.indexOf(skeletonData.bones, slotData.boneData)] local slot = Slot.new(slotData, self, bone) table.insert(self.slots, slot) + self.slotsByName[slot.data.name] = slot table.insert(self.drawOrder, slot) end diff --git a/spine-lua/SkeletonData.lua b/spine-lua/SkeletonData.lua index db776b153..531f9613e 100644 --- a/spine-lua/SkeletonData.lua +++ b/spine-lua/SkeletonData.lua @@ -28,6 +28,7 @@ function SkeletonData.new () local self = { bones = {}, slots = {}, + slotNameIndices = {}, skins = {}, animations = {} } @@ -58,10 +59,7 @@ function SkeletonData.new () function self:findSlotIndex (slotName) if not slotName then error("slotName cannot be nil.", 2) end - for i,slot in ipairs(self.slots) do - if slot.name == slotName then return i end - end - return -1 + return slotNameIndices[slotName] or -1 end function self:findSkin (skinName) diff --git a/spine-lua/SkeletonJson.lua b/spine-lua/SkeletonJson.lua index a837ceb13..0125d5833 100644 --- a/spine-lua/SkeletonJson.lua +++ b/spine-lua/SkeletonJson.lua @@ -29,7 +29,6 @@ local SlotData = require "spine-lua.SlotData" local Skin = require "spine-lua.Skin" local AttachmentLoader = require "spine-lua.AttachmentLoader" local Animation = require "spine-lua.Animation" - local TIMELINE_SCALE = "scale" local TIMELINE_ROTATE = "rotate" local TIMELINE_TRANSLATE = "translate" @@ -102,8 +101,9 @@ function SkeletonJson.new (attachmentLoader) end slotData.attachmentName = slotMap["attachment"] - - table.insert(skeletonData.slots, slotData) + table.insert(skeletonData.slots, slotData) + skeletonData.slotNameIndices[slotData.name] = #skeletonData.slots + end end @@ -113,7 +113,7 @@ function SkeletonJson.new (attachmentLoader) for skinName,skinMap in pairs(map) do local skin = Skin.new(skinName) for slotName,slotMap in pairs(skinMap) do - local slotIndex = skeletonData:findSlotIndex(slotName) + local slotIndex = skeletonData.slotNameIndices[slotName] for attachmentName,attachmentMap in pairs(slotMap) do local attachment = readAttachment(attachmentName, attachmentMap, self.scale) if attachment then @@ -213,7 +213,7 @@ function SkeletonJson.new (attachmentLoader) local slotsMap = map["slots"] if slotsMap then for slotName,timelineMap in pairs(slotsMap) do - local slotIndex = skeletonData:findSlotIndex(slotName) + local slotIndex = skeletonData.slotNameIndices[slotName] for timelineName,values in pairs(timelineMap) do if timelineName == TIMELINE_COLOR then diff --git a/spine-unity/Assets/Plugins/Spine/SkeletonComponent.cs b/spine-unity/Assets/Plugins/Spine/SkeletonComponent.cs index 143d0541d..46d904a33 100644 --- a/spine-unity/Assets/Plugins/Spine/SkeletonComponent.cs +++ b/spine-unity/Assets/Plugins/Spine/SkeletonComponent.cs @@ -36,8 +36,9 @@ public class SkeletonComponent : MonoBehaviour { public String initialSkinName; public float timeScale = 1; private Mesh mesh; + private int lastVertexCount; private Vector3[] vertices; - private Color[] colors; + private Color32[] colors; private Vector2[] uvs; private int[] triangles; private float[] vertexPositions = new float[8]; @@ -99,11 +100,13 @@ public class SkeletonComponent : MonoBehaviour { // Ensure mesh data is the right size. Vector3[] vertices = this.vertices; - bool newTriangles = quadCount > vertices.Length / 4; + int vertexCount = quadCount * 4; + bool newTriangles = vertexCount > vertices.Length; if (newTriangles) { - this.vertices = vertices = new Vector3[quadCount * 4]; - colors = new Color[quadCount * 4]; - uvs = new Vector2[quadCount * 4]; + // Not enough vertices, increase size. + this.vertices = vertices = new Vector3[vertexCount]; + colors = new Color32[vertexCount]; + uvs = new Vector2[vertexCount]; triangles = new int[quadCount * 6]; mesh.Clear(); @@ -118,15 +121,17 @@ public class SkeletonComponent : MonoBehaviour { triangles[index + 5] = vertex + 1; } } else { + // Too many vertices, zero the extra. Vector3 zero = new Vector3(0, 0, 0); - for (int i = quadCount * 4, n = vertices.Length; i < n; i++) + for (int i = vertexCount, n = lastVertexCount; i < n; i++) vertices[i] = zero; } + lastVertexCount = vertexCount; // Setup mesh. float[] vertexPositions = this.vertexPositions; int vertexIndex = 0; - Color color = new Color(); + Color32 color = new Color32(); for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; RegionAttachment regionAttachment = slot.Attachment as RegionAttachment; @@ -139,10 +144,10 @@ public class SkeletonComponent : MonoBehaviour { vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0); vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0); - color.a = skeleton.A * slot.A; - color.r = skeleton.R * slot.R * color.a; - color.g = skeleton.G * slot.G * color.a; - color.b = skeleton.B * slot.B * color.a; + color.a = (byte)(skeleton.A * slot.A * 255); + color.r = (byte)(skeleton.R * slot.R * color.a); + color.g = (byte)(skeleton.G * slot.G * color.a); + color.b = (byte)(skeleton.B * slot.B * color.a); colors[vertexIndex] = color; colors[vertexIndex + 1] = color; colors[vertexIndex + 2] = color; @@ -157,7 +162,7 @@ public class SkeletonComponent : MonoBehaviour { vertexIndex += 4; } mesh.vertices = vertices; - mesh.colors = colors; + mesh.colors32 = colors; mesh.uv = uvs; if (newTriangles) mesh.triangles = triangles; }