Search Unity

Memory leak with Entity Query

Discussion in 'Entity Component System' started by Deleted User, Aug 12, 2019.

  1. Deleted User

    Deleted User

    Guest

    This is my code that spawns a player in random spawn points when SpawnPlayerEvent raises:
    Code (CSharp):
    1.     public class PlayerSpawningSystem : ComponentSystem
    2.     {
    3.         private Random random;
    4.         private EntityQuery spawnPlayerEventQuery;
    5.         private EntityQuery spawnDataQuery;
    6.  
    7.         protected override void OnCreate()
    8.         {
    9.             random = new Random();
    10.             spawnPlayerEventQuery = GetEntityQuery(typeof(SpawnPlayerEvent));
    11.             spawnDataQuery = GetEntityQuery(typeof(PlayerPrefab), typeof(PlayerSpawnPosition));
    12.         }
    13.  
    14.         protected override void OnUpdate()
    15.         {
    16.             int eventCount = spawnPlayerEventQuery.CalculateEntityCount();
    17.            
    18.             if (eventCount == 0)
    19.                 return;
    20.            
    21.             Entity spawnDataEntity = spawnDataQuery.GetSingletonEntity();
    22.             Entity playerPrefab = EntityManager.GetComponentData<PlayerPrefab>(spawnDataEntity).Value;
    23.             DynamicBuffer<PlayerSpawnPosition> spawnPoints = EntityManager.GetBuffer<PlayerSpawnPosition>(spawnDataEntity);
    24.  
    25.             for (int i = 0; i < eventCount; i++)
    26.             {
    27.                 Entity spawnedPlayer = EntityManager.Instantiate(playerPrefab);
    28.  
    29.                 int randomIndex = random.NextInt(0, spawnPoints.Length);
    30.                 float3 spawnPoint = spawnPoints[randomIndex];
    31.                 EntityManager.SetComponentData(spawnedPlayer, new Translation { Value = spawnPoint });
    32.             }
    33.         }
    34.     }
    Unity prints errors about memory leak. What am I doing wrong?
    Also am I using dynamic buffers right?
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Looks fine to me, sure it's from this system?
     
  3. Deleted User

    Deleted User

    Guest

    I have 3 systems. I had disabled other 2 systems with an early return statement.
    I restarted unity and it seems that issue was solved. I don't know what happened.
    Now I'm getting
    InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it

    on the line
    int randomIndex = random.NextInt(0, spawnPoints.Length);

    Do you know why it's happening?
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Oh.

    Try replace EntityManager with PostUpdateCommands.

    (You'll have to restart unity any time you get spammed with deallocation warnings they won't go away.)
     
    cj-currie and (deleted member) like this.
  5. Deleted User

    Deleted User

    Guest

    Thank you. It solved the problem.

    For future visitors:
    When you instantiate a new entity, all previous data is invalidated. So when I instantiate player on line
    Entity spawnedPlayer = EntityManager.Instantiate(playerPrefab);

    the dynamic buffer gets deallocated.

    I needed to replace

    Code (CSharp):
    1. Entity spawnedPlayer = EntityManager.Instantiate(playerPrefab);
    and
    Code (CSharp):
    1.  EntityManager.SetComponentData(spawnedPlayer, new Translation { Value = spawnPoint });

    with

    Code (CSharp):
    1. Entity spawnedPlayer = PostUpdateCommands.Instantiate(playerPrefab);
    and
    Code (CSharp):
    1. PostUpdateCommands.SetComponent(spawnedPlayer, new Translation { Value = spawnPoint });
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    It's not just instantiate. You should consider that all EntityManager methods that modify entities will invalidate everything.
     
    siggigg likes this.
  7. cj-currie

    cj-currie

    Joined:
    Nov 27, 2008
    Posts:
    337
    Oh man, I didn't know about having to restart Unity...I was banging my head against a wall trying to figure out my memory leaks >.< Thanks Tertle, you are a legend on this forum!