No, no. You're stating a fact we all know about what Mesh wants. The exception spells out what it's complaining about either way.
I'm not asking about some special modification I did to the code. I made none. The problem is that SkeletonComponent stops working correctly in the following condition:
(1) Use a setup pose that has all slots set to have no images.
(2) Switching the gameObject between enabled and disabled states at runtime.
This is arguably something likely to happen when using Spine for effects animations so I think it needs to be fixed.
I've described my current suspicion in the issue thread.
The exception is thrown towards the end of Update() here:
uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], 1 - regionUVs[RegionAttachment.Y2]);
uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], 1 - regionUVs[RegionAttachment.Y3]);
vertexIndex += 4;
}
mesh.vertices = vertices;
mesh.colors32 = colors;
mesh.uv = uvs;
if (newTriangles) mesh.triangles = triangles;
}
But my suspicion is that the reason why there's an array mismatch in the first place is somewhere at the beginning of Update() where in certain situations, it calls things like Clear and Initialize and where quadcount has the potential to be 0 (and, consequently, newTriangles to be false and therefore the arrays never allocated) with an imageless setup pose.
public virtual void Update () {
// Clear fields if missing information to render.
if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(false) == null) {
Clear();
return;
}
// Initialize fields.
if (skeleton == null || skeleton.Data != skeletonDataAsset.GetSkeletonData(false))
Initialize();
UpdateSkeleton();
// Count quads.
int quadCount = 0;
List<Slot> drawOrder = skeleton.DrawOrder;
for (int i = 0, n = drawOrder.Count; i < n; i++) {
Slot slot = drawOrder[i];
Attachment attachment = slot.Attachment;
if (attachment is RegionAttachment)
quadCount++;
}
// Ensure mesh data is the right size.
Vector3[] vertices = this.vertices;
int vertexCount = quadCount * 4;
bool newTriangles = vertexCount > vertices.Length;
if (newTriangles) {
// 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();
However, working through the problem, I also noticed it behaving differently when testing in Unity (with the play button) and testing it with a webplayer.
Turns out, OnDisabled() looks like this:
public virtual void OnDisable () {
if (Application.isEditor)
Clear();
}
And Clear() looks like this:
public virtual void Clear () {
GetComponent<MeshFilter>().mesh = null;
DestroyImmediate(mesh);
mesh = null;
renderer.sharedMaterial = null;
skeleton = null;
}
My assumption is that enabling and disabling GameObjects is a way to prevent objects from being rendered and being updated, while still having its data in tact (and therefore, preventing any unnecessary reallocation and rebuilding that comes from opting to use Instantiate and Destroy instead.) So calling Clear() during OnDisable() actually strikes me as odd. Commenting out the whole OnDisable method does seem to solve the problem though, and while I can guess at why that's the case, I might be missing something, or making incorrect assumptions.
You can imagine this is a number of issues here, and we need someone who knows Unity standards.
Do you want to continue this discussion elsewhere?