Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it

Discussion in 'Entity Component System' started by FastTurtle222, Apr 3, 2018.

  1. FastTurtle222

    FastTurtle222

    Joined:
    Dec 24, 2017
    Posts:
    28
    Not sure what I am doing wrong here, I am attempting to change the mesh that my MeshRenderer Component is using, it will work for a few frames then my console gets spammed with the above error.

    line that is causing the error
    mesh = entityManager.GetSharedComponentData<MeshRenderComponent>(m_Data.animator.entity);

    full script

    Code (csharp):
    1.  
    2. public struct Data
    3. {
    4.     public int Length;
    5.     public ComponentDataArray<AnimatorComponent> animator;
    6.     [ReadOnly] public SharedComponentDataArray<MeshRenderComponent> renderer;
    7.  
    8. }
    9. [Inject] private Data m_Data;
    10.  
    11. protected override void OnUpdate()
    12. {
    13.         for(int i = 0; i < m_Data.Length; i++)
    14.         {
    15.             mesh = entityManager.GetSharedComponentData<MeshRenderComponent>(m_Data.animator[i].entity);
    16.             mesh.mesh = idleMesh[CurrentFrame];
    17.             entityManager.SetSharedComponentData(m_Data.animator[i].entity, mesh);          
    18.         }
    19.        currentFrame = (currentFrame >=100) ?  0 : currentFrame = currentFrame += 1;
    20. }
    21.  
    here is how I am spawning the entity

    Code (csharp):
    1.  
    2.         actors = new NativeArray<Entity>(100, Allocator.Persistent);
    3.         Entity[] characters = new Entity[actors.Length];
    4.         var entityManager = World.Active.GetOrCreateManager<EntityManager>();
    5.         var protoType = entityManager.Instantiate(umaPrefab);
    6.         entityManager.AddComponentData(protoType, new Position { Value = new float3(0, 0, 0) });
    7.         entityManager.AddComponentData(protoType, new Rotation { Value = new quaternion(-90, 0, 180, 0) });
    8.         entityManager.AddComponentData(protoType, new TransformMatrix());
    9.         entityManager.AddComponentData(protoType, new AnimatorComponent { });
    10.         renderer = umaPrefab.transform.Find("UMARenderer").GetComponent<SkinnedMeshRenderer>();
    11.         entityManager.AddSharedComponentData(protoType, new MeshRenderComponent { mesh = renderer.sharedMesh, material = renderer.sharedMaterial});
    12.      
    13.         entityManager.Instantiate(protoType, actors);
    14.         entityManager.DestroyEntity(protoType);
    15.         actors.CopyTo(characters);
    16.  
    17.         for (int i = 0; i < characters.Length; ++i)
    18.         {
    19.             entityManager.SetComponentData(characters[i], new Position { Value = new float3(1 * i, 0, 1 * (i/10)) });
    20.             entityManager.SetComponentData(characters[i], new Rotation { Value = new quaternion(0, 0, 0, 0) });
    21.             entityManager.SetComponentData(characters[i], new AnimatorComponent { entity = characters[i] });
    22.          
    23.                  
    24.         }
    25.     void OnDestroy()
    26.     {
    27.         actors.Dispose();
    28.     }
    29.  
     
    Last edited: Apr 3, 2018
  2. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    When you change entities via the entitiymanager directly, it invalidates the entity array, this causes the error.

    Is your first script is a ComponentSystem? If yes, try to using PostUpdateCommands instead of entityManager. Also try to inject your mesh into Data if possible. GetSharedComponentData isn't very fast.
     
  3. Caiuse

    Caiuse

    Joined:
    Jan 6, 2010
    Posts:
    30
    If you use the MeshInstanceSystem.cs inside the Entity Component package as an guide they store a cached array of SharedComponents (MeshInstanceRenderer). You could do this to get the shared component then pass it into the job. I think the method is EntityManger.GetAllUniqueSharedComponentData()
     
  4. FastTurtle222

    FastTurtle222

    Joined:
    Dec 24, 2017
    Posts:
    28
    This worked thank you very much for pointing me in the right direction.
     
  5. Orimay

    Orimay

    Joined:
    Nov 16, 2012
    Posts:
    304
    I am having the same issue, but not sure how to create an entity from within MonoBehaviour within OnWillRenderObject method without an EntityManager
     
  6. xenonsin

    xenonsin

    Joined:
    Dec 12, 2013
    Posts:
    20
    Same issue as Kender.. Is there a way to create entities in MonoBehaviours post update?
     
  7. FastTurtle222

    FastTurtle222

    Joined:
    Dec 24, 2017
    Posts:
    28
    I do not think there is a way by default, you could try adding a static method to that entities system then call it from monobehavior.
     
  8. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    Code (CSharp):
    1. World.Active.GetOrCreateManager<EntityManager>().CreateEntity(...)
     
  9. FastTurtle222

    FastTurtle222

    Joined:
    Dec 24, 2017
    Posts:
    28
    That will invalidate the entity array. He needs to create them via post update commands.
     
  10. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    that matters only if you are inside a system.
    he said MonoBehaviour, that's outside ECS so there is nothing to invalidate.

    if you are already inside a system, you just use PostUpdateCommands (or a barrier system if you are in a JobComponentSystem)
     
  11. madks13

    madks13

    Joined:
    May 8, 2016
    Posts:
    173
    Hello, so i had a similar problem. I changed the SetSharedComponent to PostUpdateCommands, but not instead of having errors, the components don't seem to update. I'm trying to set textures via MeshInstanceRenderer.