Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved IndexOutOfRangeException: Index 29 is out of range in DynamicBuffer of '29' Length.

Discussion in 'NetCode for ECS' started by optimise, Aug 23, 2021.

  1. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,113
    @CMarastoni Any idea why there's such error spamming?

    IndexOutOfRangeException: Index 29 is out of range in DynamicBuffer of '29' Length.
    Unity.Entities.DynamicBuffer`1[T].CheckBounds (System.Int32 index) (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/Iterators/DynamicBuffer.cs:143)
    Unity.Entities.DynamicBuffer`1[T].get_Item (System.Int32 index) (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/Iterators/DynamicBuffer.cs:184)
    Unity.NetCode.GhostUpdateSystem+UpdateJob.Execute (Unity.Entities.ArchetypeChunk chunk, System.Int32 chunkIndex, System.Int32 firstEntityIndex, Unity.Entities.DynamicComponentTypeHandle* ghostChunkComponentTypesPtr, System.Int32 ghostChunkComponentTypesLength) (at Library/PackageCache/com.unity.netcode@b1677fac31/Runtime/Snapshot/GhostUpdateSystem.cs:340)
    Unity.NetCode.GhostUpdateSystem+GhostUpdateJob128.Execute (Unity.Entities.ArchetypeChunk chunk, System.Int32 chunkIndex, System.Int32 firstEntityIndex) (at Library/PackageCache/com.unity.netcode@b1677fac31/Runtime/Snapshot/GhostUpdateSystem.cs:49)
    Unity.Entities.JobChunkExtensions+JobChunkProducer`1[T].ExecuteInternal (Unity.Entities.JobChunkExtensions+JobChunkWrapper`1[T]& jobWrapper, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/IJobChunk.cs:386)
    Unity.Entities.JobChunkExtensions+JobChunkProducer`1[T].Execute (Unity.Entities.JobChunkExtensions+JobChunkWrapper`1[T]& jobWrapper, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/IJobChunk.cs:353)
    Unity.Jobs.JobHandle:ScheduleBatchedJobsAndComplete(JobHandle&)
    Unity.Jobs.JobHandle:Complete()
    Unity.NetCode.GhostPredictionSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.netcode@b1677fac31/Runtime/Snapshot/GhostPredictionSystemGroup.cs:72)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystem.cs:114)
    Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:472)
    Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:417)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystem.cs:114)
    Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:472)
    Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:417)
    Unity.NetCode.ClientSimulationSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.netcode@b1677fac31/Runtime/ClientServerWorld/ClientSimulationSystemGroup.cs:90)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystem.cs:114)
    Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:472)
    Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:417)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystem.cs:114)
    Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:472)
    Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystemGroup.cs:417)
    Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ComponentSystem.cs:114)
    Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@d5c2cb538f/Unity.Entities/ScriptBehaviourUpdateOrder.cs:333)
     
  2. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    259
  3. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,113
    Ya. I already applied the fix but I still get this error spamming.
     
  4. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    mmm. I need to check if we added some changes/fixes in the GhostUpdateSystem in regards buffer (but I don't remember right now). Accessing that out of bound like that looks like we deserialised something incorrectly. Can I ask more info about the prefab setup? Is that buffer on a child entity?
     
  5. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,113
    Ya. The error seems like coming from child entity ghost. Netcode 0.7 seems like dun have that error anymore.
     
  6. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    NetCode 0.7? How do you know or tested that ? (we didn't release any 0.7 version).
     
  7. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,113
    o_O Previously it's secretly publish to packman. I guess now it has been taken down.
     
  8. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,113
    @CMarastoni Actually I think u should improve Netcode to make it to log clear error message when GhostUpdateSystem goes wrong. With the current error message I have no way to track the source of error. I only can keep guessing and trying until I fix the error.
     
    ChrisPie likes this.
  9. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    @CMarastoni Also getting this error. Seems like
    linkedEntityGroupAccessor
    returns a wrong
    linkedEntityGroup, from a totally different ghost entity. This doesn't happen immediately but after a few seconds of playing, so maybe something gets invalidated/shifted around.

    edit: For me this happens when a 1st level child of a ghost prefab has a component variant with
    SendDataForChildEntity = true. When I stop using that variant the error no longer happens. But this is an important feature for me so...
     
    Last edited: Sep 18, 2021
  10. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    Could you please give more details about it?
    Sounds like a bug we fixed internally some time ago, but I need more information to understand were it happen.
    So you should not use it..
     
  11. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    Need a little more info to understand what going on.
    Hierarchy, component/buffer types that are serialized, type of variant assigned.
    If you have a repro in some project I can take also a look
     
  12. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    @CMarastoni Player's prefab has Default Ghost Mode set to Predicted. It's a physics body (but I disabled physics on clients). That prefab has a child, whose rotation I need to be sent to clients, so I have a variant for rotation:
    Code (CSharp):
    1. [GhostComponentVariation(typeof(Rotation), "Rotation - Send child")]
    2. [GhostComponent(PrefabType = GhostPrefabType.All, OwnerPredictedSendType = GhostSendType.All, SendDataForChildEntity = true)]
    3. public struct RotationSendChild
    4. {
    5.     [GhostField(Quantization=1000, Smoothing=SmoothingAction.InterpolateAndExtrapolate, SubType=SubTypes.Rot_SendChild)] public quaternion Value;
    6. }
    The player prefab also has a Health and Inventory components defined as
    Code (CSharp):
    1. [GhostComponent(PrefabType = GhostPrefabType.AllPredicted, OwnerSendType = SendToOwnerType.SendToOwner)]
    I found just now that removing those 2 components from the prefab makes the error disappear (I think), do those attribute settings conflict with each other?
     
  13. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    I suspect he has something to do with the SendToOwner setting. We fixed a bug there not long time ago that was causing the entities being deserialised incorrectly.
    Just to verify that, could you please try to change the SendToOwner to its default?
     
  14. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    Nope, still same error without SendToOwner.
    edit: Narrowed it down to the Inventory GhostComponent. Just adding it to prefab causes the error, even though I commented out all the usages of that component in my systems. The component is the simplest component possible:
    Code (CSharp):
    1. [Serializable]
    2. [GenerateAuthoringComponent]
    3. [GhostComponent(PrefabType = GhostPrefabType.All)]
    4. public struct PlayerInventoryComponent : IComponentData
    5. {
    6.     [GhostField]
    7.     public int Ammo;
    8. }
     
    Last edited: Sep 20, 2021
  15. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    The problem is not the component itself, it is something in relation to child entities (and probably buffers to some extents). There were some issues in that sense (I also posted some fix in the forum).
    Could you give me the full set of components (variants included) that the prefab has?
     
  16. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    Not sure how to share it, as the list is huge. That's half of it, nothing interesting further down, it goes up to 27 children (yes I know it's a lot). Only a few of those are actually sent, adds up to around 11 bytes in snapshot. The only variant I have on that prefab is that child's rotation. No buffers other than single command buffer.
     

    Attached Files:

  17. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    If you mean the diff of GhostReceiveSystem you posted, it doesn't help.
    edit: Is there a way to work around it? Since we can't expect a new version release any time soon. I need a turret to be a child of a boat to inherit position and base rotation, but I can't send child's rotation to actually rotate the turret.

    edit2: I found a nasty workaround if anyone needs it. Instead of actually sending children's component, I added a "proxy" ghost component to the parent that stores child's data. Since that proxy is on the parent, it works ok. Then, on both server and clients, I copy the data from proxy component to actual rotation of the child. No errors in editor, standalone still crashes instantly tho, I think NRE at GhostUpdateSystem.cs:247
     
    Last edited: Sep 22, 2021
  18. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,113
    @CMarastoni :eek:Does Netcode 0.7 very buggy?
     
  19. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    It wasn't very buggy but in general NetCode had some bugs here and there (some from the past too) that we fixed. I saw already something similar but it was due to a mix of other things. Here you are using a variant for translation on a the child entity. Worth to check it out. I will to setup something similar.
     
  20. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    What patches (of the one I posted in the forum for both component sort order, buffers etc) have you applied?
     
  21. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
  22. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    Also, worth notice that you can achieve the same results without using a variant.
    To send the position and rotation of that turret children, you just need to set the SendToChild override in the prefab for that child.
    And since the problem was due to the variant, that may solve your issue. (I suppose)
     
  23. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    Yeah that should work. I used a variant because that was before I found a fix for component checkboxes being read-only. Even with that fix if I tick "Send for this child", leave the prefab, click the prefab again, it's no longer ticked. But the component is on top of the list, I'm not sure if it saves properly. Maybe that's expected upload_2021-9-22_18-19-32.png
     
    Last edited: Sep 22, 2021
  24. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    It is empty because the the client need to wait for the server to obtains the ghost collection prefab list and load also the game scene in order to process the prefabs.

    The buffer serialization fix is nice to have but it is not your bug.

    Here the issue is way more complex and it is a mix of authoring and conversion problems. The code that crash is this one
    Code (csharp):
    1.  
    2. linkedEntityGroup[GhostComponentIndex[typeData.FirstComponent + comp].EntityIndex]
    3.  
    The EntityIndex here is too big. The GhostComponentIndex.EntityIndex is assigned when the prefab is processed by both client and server and its value comes fro the ghost conversion.
    The ghost has 28 linked entities + 1 (himself) but EntityIndex was exactly that size. So or the EntityIndex was wrong or an entity has been unliked from the parent.

    The fix you added to the inspector is actually not correct in general and it only work if you have a 1:1 mapping in between gameobject and entity child. This it not always the case with the hybrid renderer (that usually create more child than gameobject). But since the inspector code is not crashing looks like you are in that case.

    I need to reproduce the bug in order to help here. Can't you share the project code or something similar that have the same crash?
    Also, does the bug only happen in the build or also in the editor? (that also is important). There was an issue with component sorting that can affect that as well.
     
  25. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    That UI has a lot of bug so plenty possible. Let me double check
     
  26. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    I tried with NetCode 0.7 and it work for me if I enable both. You should check both toggles (one enable the override the other one set the value)
     
  27. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    Well 0.7 is not publicly available. When I revert the fix you're saying is wrong, I get Transform child out of bounds error. With the fix in place, those 2 toggles don't save, here's the prefab diff after checking them: upload_2021-9-22_20-11-35.png
    I can upload the project tommorow. Where should I upload it? It's around 400 MB and I'd prefer it wasn't public, currently my repo is private.
     
  28. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    I tried to repro with a simpler project and some big entity hierarchy (up to 32 children), setting some variants, some with the flag. But I never got a crash so far in the Editor. I will try a build.
    Meanwhile I fixed the logic for the GhostAuthoringComponent so that at least it works as expected (I will post a fix that later).
     
    ChrisPie and Occuros like this.
  29. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    Yeah the editor won't crash, at most you'll get an exception in the UpdateJob every frame after ~20 seconds of playtime.
     
  30. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    882
    Some update in regard that issue:

    First: to fix the SendForChildren option not correclty saved: change the the code in the GhostAuthoringComponent.cs with the following snippet:
    Code (csharp):
    1.  
    2. [SerializeField]private GameObject[] RefGameObjects;
    3. [SerializeField]private string[] ComponentNames;
    4. [SerializeField]private OverrideValue[] PrefabTypeOverrides;
    5. [SerializeField]private OverrideValue[] SendTypeOverrides;
    6. [SerializeField]private OverrideValue[] VariantOverrides;
    7. [SerializeField]private OverrideValue[] SendForChildrenOverrides; <--- this is new
    8.  
    9. //Custom serialization hook for the overrides.
    10. public void OnBeforeSerialize()
    11. {
    12.     var t1 = new List<OverrideValue>(ComponentOverrides.Count);
    13.     var t2 = new List<OverrideValue>(ComponentOverrides.Count);
    14.     var t3 = new List<OverrideValue>(ComponentOverrides.Count);
    15.     var t4 = new List<OverrideValue>(ComponentOverrides.Count);
    16.     RefGameObjects = new GameObject[ComponentOverrides.Count];
    17.     ComponentNames = new string[ComponentOverrides.Count];
    18.     int index = 0;
    19.     foreach (var m in ComponentOverrides)
    20.     {
    21.         RefGameObjects[index] = m.gameObject;
    22.         ComponentNames[index] = m.fullTypeName;
    23.         if (m.PrefabType != ComponentOverride.UseDefaultValue)
    24.             t1.Add(new OverrideValue(index, (ulong)m.PrefabType));
    25.         if (m.OwnerPredictedSendType != ComponentOverride.UseDefaultValue)
    26.             t2.Add( new OverrideValue(index, (ulong)m.OwnerPredictedSendType));
    27.         if(m.ComponentVariant != 0)
    28.             t3.Add(new OverrideValue(index, m.ComponentVariant));
    29.         if(m.SendToChild != 0)
    30.             t4.Add(new OverrideValue(index, (ulong)m.SendToChild));
    31.         ++index;
    32.     }
    33.     PrefabTypeOverrides = t1.ToArray();
    34.     SendTypeOverrides = t2.ToArray();
    35.     VariantOverrides = t3.ToArray();
    36.     SendForChildrenOverrides = t4.ToArray();
    37. }
    38.  
    39. public void OnAfterDeserialize()
    40. {
    41.     if (RefGameObjects == null)
    42.         return;
    43.  
    44.     int count = RefGameObjects.Length;
    45.     ComponentOverrides.Clear();
    46.     ComponentOverrides.Capacity = RefGameObjects.Length;
    47.  
    48.     for (int i = 0; i < count; ++i)
    49.     {
    50.         var refGameObject = RefGameObjects[i];
    51.         var typeFullName = ComponentNames[i];
    52.         ComponentOverrides.Add(new ComponentOverride
    53.         {
    54.             gameObject = refGameObject,
    55.             fullTypeName = typeFullName,
    56.         });
    57.     }
    58.  
    59.     if (PrefabTypeOverrides != null)
    60.     {
    61.         foreach (var p in PrefabTypeOverrides)
    62.         {
    63.             ComponentOverrides[p.OverrideIndex].PrefabType = (int)p.Value;
    64.         }
    65.     }
    66.  
    67.     if (SendTypeOverrides != null)
    68.     {
    69.         foreach (var p in SendTypeOverrides)
    70.         {
    71.             ComponentOverrides[p.OverrideIndex].OwnerPredictedSendType = (int)p.Value;
    72.         }
    73.     }
    74.  
    75.     if (VariantOverrides != null)
    76.     {
    77.         foreach (var p in VariantOverrides)
    78.         {
    79.             ComponentOverrides[p.OverrideIndex].ComponentVariant = p.Value;
    80.         }
    81.     }
    82.  
    83.     if (SendForChildrenOverrides != null)
    84.     {
    85.         foreach (var p in SendForChildrenOverrides)
    86.             ComponentOverrides[p.OverrideIndex].SendToChild = (int)p.Value;
    87.     }
    88. }
    89.  
    For the GhostUpdateSystem problem, without going into the specific user systems name etc, the problem is/was due to the fact the both client and server were spawning ghosts during the simulation, but without using predicted spawning.
    Because of that, on the client:
    - the instantiate entity will be never reconciled and its ghost id is invalid (0)
    - the instantiate entity ghost component will have ghostType = 0 (the default) that is not correct!
    - the spawn tick will be 0 (that is also incorrect).
    The major issue in the GhostUpdateSystem was due to the fact being GhostComponent.ghostType == 0 an incorrect prefab type was used to update the entity (the real prefab type was different). The type 0 was expecting a prefab with 28 children, but the updating entity only had 1 children. Therefore, when it was trying to access the children number 8 that was completely out of bound.

    Indeed we can make the GhostUpdateSystem more robust to this can of situation (I already filled a task for that). But changing this system to be server only the problem should be fixed.
     
  31. ChrisPie

    ChrisPie

    Joined:
    Mar 5, 2015
    Posts:
    31
    Yep. That fixes it. Thanks a lot.
     
    CMarastoni likes this.