• RuntimesBugs
  • Index was outside the bounds of the array in MeshGenerator

Hi @Harald and thanks for getting back to me.

I just updated to the latest version spine-unity-4.1-2023-04-06.unitypackage - the error still occurs.

The commit you mentioned changes an Editor only file and doesn't affect Mesh Generation at all and unfortunately won't have an impact on our issue.

Thanks for your help

Related Discussions
...

@jeremie-tmx Thanks for getting back to us. Sorry to hear that the issue persists. Looking at the commit made it rather obvious that this was not affecting mesh generation, I must have confused it with another commit.

Knowing that you already tried to create a simple reproduction project, could you perhaps create a stripped down version of your larger project, where this issue still occurs? Or could you perhaps log which combination of set skins / attachments and animations leads to the issue and then set these same skins and animations to reproduce the issue?

If there is a bug that reads past the end of vbi, it's likely happening more often than you see because vertexBuffer.Items length can be greater than vertexBuffer.Count. To ensure you see it every time it happens, temporarily modify Mesh Generator to call vertexBuffer.TrimExcess() before any reading from vertexBuffer.

I see MeshGenerator TrimExcess but I don't see anywhere it is called.

@Harald, we have ExposedList TrimExcess but CurveTimeline Shrink. The horror! 🫣

Hi @Harald, unfortunately it is really hard to narrow this down on a project of this scale. It does not seem to affect a specific animation / skin either, it's just a super weird issue, hard to reproduce, but still manages to trigger on thousands of our players with no real idea of what the implications are for them.

@Nate Agreed, the exception happens as it overflows but there's probably cases where the vbi array isn't being completely filled.
I tried to call vertexBuffer.TrimExcess() before a few vertexBuffer readings in the BuildMeshWithArrays method but I am now getting constant errors

Mesh.uv is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array
Mesh.colors is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array.

    jeremie-tmx I tried to call vertexBuffer.TrimExcess() before a few vertexBuffer readings in the BuildMeshWithArrays method but I am now getting constant errors

    Mesh.uv is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array
    Mesh.colors is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array.

    @jeremie-tmx Thanks for trying out trimming the arrays. The error message you receive comes from trimming only the vertexBuffer (which is only the position buffer, Unity's nomenclature unfortunately uses Vector3 Mesh.vertices as position array instead of an interleaved { position, uv, color, .. } buffer). You would need to trim the uvBuffer and colorBuffer arrays accordingly as well.

    We are having a look at the issue, if you should find any insights resultimg from with trimming the arrays, we are of course very happy to hear them. 🙂

      Harald Okay makes sense
      I used the TrimExcess() method instead which seems to trim pretty much everything
      I added it before any read of vertexBuffer / uvBuffer / colorBuffer (BuildMeshWithArrays, ScaleVertexData, AddAttachmentTintBlack,FillVertexData, FillLateVertexData, EnsureVertexCapacity)

      Still hitting these whenever we play animations though

      Mesh.vertices is too small. The supplied vertex array has less vertices than are referenced by the triangles array.
      UnityEngine.Mesh:set_vertices (UnityEngine.Vector3[])
      Spine.Unity.MeshGenerator:FillVertexData (UnityEngine.Mesh) (at Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs:1084)
      Spine.Unity.SkeletonRenderer:LateUpdateMesh () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs:538)
      Spine.Unity.SkeletonRenderer:LateUpdate () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs:455)
      Spine.Unity.SkeletonAnimation:LateUpdate () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs:274)
      
      Mesh.uv is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array.
      UnityEngine.Mesh:set_uv (UnityEngine.Vector2[])
      Spine.Unity.MeshGenerator:FillVertexData (UnityEngine.Mesh) (at Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs:1085)
      Spine.Unity.SkeletonRenderer:LateUpdateMesh () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs:538)
      Spine.Unity.SkeletonRenderer:LateUpdate () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs:455)
      Spine.Unity.SkeletonAnimation:LateUpdate () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs:274)
      
      Mesh.colors is out of bounds. The supplied array needs to be the same size as the Mesh.vertices array.
      UnityEngine.Mesh:set_colors32 (UnityEngine.Color32[])
      Spine.Unity.MeshGenerator:FillVertexData (UnityEngine.Mesh) (at Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs:1086)
      Spine.Unity.SkeletonRenderer:LateUpdateMesh () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs:538)
      Spine.Unity.SkeletonRenderer:LateUpdate () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs:455)
      Spine.Unity.SkeletonAnimation:LateUpdate () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs:274)

      Thanks for the support

        jeremie-tmx Thanks for your efforts. We have found a potential (and likely) cause where the vertex buffer can have the wrong size: If after SkeletonGraphic.LateUpdate() (where render-instructions are updated) another script modifies any attachments (by setting e.g. skeletonGraphic.Skeleton.SetAttachment() or Skeleton.SetSkin()), and the canvas update CanvasUpdateRegistry.PerformUpdate triggers a SkeletonGraphic.Rebuild(), there is one missing call to update the render-instructions after the modified attachments.

        So after a script modifies the skeleton from LateUpdate(), a call to skeletonGraphic.UpdateMesh() (actually only skeletonGraphic.PrepareInstructionsAndRenderers()) would fix this missing call. We're working on a proper clean bugfix, we hope to have one ready by tomorrow.

        Hi @Harald and thanks for your response. I am glad that you found something, especially since it does seem like our issue seems to be related to a weird chain of events related to a LateUpdate context.

        Didn't have a chance to try your fix in detail yet, if you have a fixed version by that time I will download it and try otherwise I will have a deeper look ASAP. Thanks again 🙂

        @jeremie-tmx We have just released a bugfix for the above issue on both 4.1 and 4.2-beta branches.

        Details: Now an automatic additional update (PrepareInstructionsAndRenderers) is performed when skeletonGraphic.Skeleton is accessed after SkeletonGraphic (which may potentially change active attachments at slots).

        New spine-unity unitypackages are available for download here as usual:
        https://esotericsoftware.com/spine-unity-download
        Please let us know if the above update resolves the issue on your end as well. Thanks for reporting!

        This issue has been tracked under this issue ticket:
        EsotericSoftware/spine-runtimes2275

        6 days later

        @Harald Thanks for the update
        Unfortunately the issue remains using spine-unity-4.1-2023-04-13.unitypackage

        IndexOutOfRangeException: Index was outside the bounds of the array.
        Spine.Unity.MeshGenerator.BuildMeshWithArrays (Spine.Unity.SkeletonRendererInstruction instruction, System.Boolean updateTriangles) (at Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs:841)
        Spine.Unity.SkeletonGraphic.UpdateMeshSingleCanvasRenderer (Spine.Unity.SkeletonRendererInstruction currentInstructions) (at Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs:775)
        Spine.Unity.SkeletonGraphic.UpdateMeshToInstructions () (at Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs:732)
        Spine.Unity.SkeletonGraphic.Rebuild (UnityEngine.UI.CanvasUpdate update) (at Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs:314)
        UnityEngine.UI.CanvasUpdateRegistry.PerformUpdate () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/CanvasUpdateRegistry.cs:215)
        UnityEngine.Canvas:SendWillRenderCanvases() (at /Users/bokken/build/output/unity/unity/Modules/UI/ScriptBindings/UICanvas.bindings.cs:96)

        At some point I will give it another go to sandbox this scenario. In the meantime if you have any other lead as to what might be happening I'd be happy to hear them.

        Thanks again for your support!

        @jeremie-tmx Oh dear, very sorry to hear that your issue still persists!

        Could you perhaps have a look at whether somewhere in your script code in LateUpdate() (or in any other event method hook which is issued after LateUpdate()) you are perhaps directly accessing and modifying parts of the skeleton, like changing attachments at cached slots, and the like? This would unfortunately bypass the logic that detects any modification to the skeleton which only monitors the skeletonGraphic.Skeleton getter property.

          a year later

          Harald
          Hi, I have had my eyes on this post for a while now, but noticed someone else posted about this error log here (https://esotericsoftware.com/forum/d/25724-fatal-exception-indexoutofrangeexception), so I'm following up here to say that I've been encountering a similar issue too.

          I am not quite sure where the bug is coming from, but I can give some details:

          • It only happens in builds (not in Editor)
          • On our end, it only happens when we first load up our environment (a town). Every town has a bunch of NPCs (30+) using SkeletonAnimation, and a couple of menus that each have one or more character SPINEs (SkeletonGraphic), but the error only pops up for four NPCs when loading up one specific town (initializing all SPINEs). I can't figure out which ones are throwing the error (at least based from the log).
          • The game doesn't crash or break as a result, and from what I've seen, the NPCs look fine.
          • However, these four errors pop up every time during play and messes with our error tracking.

          Some thoughts from me:

          • Could this be as easy as going through all of the NPCs in the town, resetting the SPINE (whatever default assets/materials are set already), building, and testing it again?
          • Based on the stack trace, the LateUpdate() from Unity's ScrollRect is triggering this error, but only four times... so there has to be some kind of mismatch or issue with timing.
          • Again, it's only in one town, and because this is a SkeletonGraphic issue, I assume that there's a menu in the town that is causing an issue when first initiated... I'll keep taking a look and will keep you updated, but please let me know if there's anything else I can do to find out the issue for this (and why it seemingly only happens in builds!)

          Here's the full stack trace ⤵️

          Uploading Crash Report
          IndexOutOfRangeException: Index was outside the bounds of the array.
            at Spine.Unity.MeshGenerator.BuildMeshWithArrays (Spine.Unity.SkeletonRendererInstruction instruction, System.Boolean updateTriangles) [0x00bb8] in <6dd7f65da0cb495b8b298cec8c065fc6>:0 
            at Spine.Unity.SkeletonGraphic.UpdateMeshSingleCanvasRenderer (Spine.Unity.SkeletonRendererInstruction currentInstructions) [0x0006a] in <6dd7f65da0cb495b8b298cec8c065fc6>:0 
            at Spine.Unity.SkeletonGraphic.UpdateMeshToInstructions () [0x00040] in <6dd7f65da0cb495b8b298cec8c065fc6>:0 
            at Spine.Unity.SkeletonGraphic.Rebuild (UnityEngine.UI.CanvasUpdate update) [0x00035] in <6dd7f65da0cb495b8b298cec8c065fc6>:0 
            at UnityEngine.UI.CanvasUpdateRegistry.PerformUpdate () [0x0015b] in <8feb70aa6437467687fee8eb58d4b3e7>:0 
          UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
          UnityEngine.DebugLogHandler:LogException(Exception, Object)
          Sentry.Unity.Integrations.UnityLogHandlerIntegration:LogException(Exception, Object)
          UnityEngine.Logger:LogException(Exception, Object)
          UnityEngine.Debug:LogException(Exception, Object)
          UnityEngine.UI.CanvasUpdateRegistry:PerformUpdate()
          UnityEngine.Canvas:SendWillRenderCanvases()
          UnityEngine.Canvas:ForceUpdateCanvases()
          UnityEngine.UI.ScrollRect:EnsureLayoutHasRebuilt()
          UnityEngine.UI.ScrollRect:LateUpdate()

          Regards,
          Julian

            @JulianRice Sorry to hear you're facing this issue as well, thanks for your detailed writeup. Unfortunately the stack trace where the exception happens is already known, the question is which call modifies the skeleton's state before SkeletonGraphic.Rebuild is called. As mentioned above in previous postings, if user code modifies visible attachments after SkeletonGraphic.LateUpdate() but before SkeletonGraphic.Rebuild(), things could go out of sync. However, we've already added an automatic check when accessing SkeletonGraphic.Skeleton between these calls and trigger a second update automatically to re-sync SkeletonGraphic to the modification. Modifying the skeleton through a cached Skeleton skeleton = SkeletonGraphic.Skeleton however would bypass this safety check and explain the exception. Are you performing any modification of active skins or visible attachments from LateUpdate() in your scripts? If so, could you please share your exact code? If you're uncertain, you could perhaps add breakpoints in Skeleton.SetSkin and Slot.Attachment.set, or if that's not catching anything: add Debug.Log statements in said methods to see if any SetSkin or Attachment.set call at runtime lies between LateUpdate and Rebuild.

            JulianRice Could this be as easy as going through all of the NPCs in the town, resetting the SPINE (whatever default assets/materials are set already), building, and testing it again?

            I'm not sure if I understood this sentence correctly. If you mean that you could create a minimal Unity project by reducing the number of skeletons until only the problematic skeleton is left which still causes the issue in the built executable: that would be great! If you could provide us with such a minimal reproduction project, please send it to contact@esotericsoftware.com, briefly mentioning this forum thread URL so that we know the context. Then we can have a look at what's going wrong.

            JulianRice Based on the stack trace, the LateUpdate() from Unity's ScrollRect is triggering this error, but only four times... so there has to be some kind of mismatch or issue with timing.

            The issue occurs only when more attachment vertices are required (and written to) than are available. When things get out of sync the first time, an out-of-bounds exception will be raised, but when activating the same or a similar skin later, the vertex buffers likely have already been enlarged to sufficient size to cover the new skin, even if it's a different set of attachments now.

            JulianRice I'll keep taking a look and will keep you updated, but please let me know if there's anything else I can do to find out the issue for this (and why it seemingly only happens in builds!)

            Thanks very much for your offer! We are currently performing some more investigations on our side, but would be very happy if you could see if you could perhaps create a minimal reproduction project as described above, of check whether any calls that change the skin or attachments happen.

            @JulianRice @jeremie-tmx We have just pushed a commit to both 4.1 and 4.2-beta branches which should fix the issue. New unitypackages are available for download here as usual:
            https://esotericsoftware.com/spine-unity-download

            Details: The commit reverts the structural change of distributing the UpdateMesh procedure into LateUpdate and Rebuild which introduced the possibility for modifying the skeleton attachment state at the wrong time.

            Issue ticket URL for later reference:
            EsotericSoftware/spine-runtimes2487