Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Is a .ForEach and ToComponentDataArrayAsync Guaranteed to have the same order of components?

Discussion in 'Entity Component System' started by adammpolak, Dec 24, 2020.

  1. adammpolak

    adammpolak

    Joined:
    Sep 9, 2018
    Posts:
    450
    -I took the sample trigger physics example from the github

    - altered the "collision entrance section" so that I grab the ghostOwnerComponent (networkId) and compare it to a NativeArray of PlayerScore networkIds

    - If they match, I ++ the player score.

    - I grab the PlayerScore with:

    var playerScores = m_PlayerScores.ToComponentDataArrayAsync<PlayerScore>(Allocator.TempJob, out playerScoreDep);


    - I update the values of the array with a .ForEach, here is the important part:

    Code (CSharp):
    1.                     //this is what happens when the bullet enters
    2.                     else if (triggerEvent.State == EventOverlapState.Enter)
    3.                     {
    4.  
    5.                         // //we find the bullets Owner
    6.                         var bulletsPlayerNetworkId = ghostOwner[e].NetworkId;
    7.                         int pointsToAdd = 0;
    8.                         if (EntityManager.HasComponent<AsteroidTag>(otherEntity))
    9.                         {
    10.                             pointsToAdd += 1;
    11.                         }
    12.                         for (int j = 0; j < playerScores.Length; j++)
    13.                         {
    14.                             //if the playerScore's owner is the same as the bullet's owner, add to the score
    15.                             if(playerScores[j].networkId == bulletsPlayerNetworkId)
    16.                             {
    17.                                 Debug.Log("points to add: " + pointsToAdd);
    18.                                 Debug.Log("Current score before addition: " + playerScores[j].currentScore);
    19.                                 var newPlayerScore = new PlayerScore{
    20.                                     networkId = playerScores[j].networkId,
    21.                                     playerName = playerScores[j].playerName,
    22.                                     currentScore = playerScores[j].currentScore + pointsToAdd,
    23.                                     highScore = 0
    24.                                     };
    25.                                 playerScores[j] = newPlayerScore;
    26.                                 Debug.Log("what seems to be the final result score: " + playerScores[j].currentScore);
    27.                             }
    28.                         }
    29. ...
    30. .Run();
    31.  
    I then have another .ForEach that runs on the actual PlayerScore entities and I update the components with the NativeArrayValues:

    Code (CSharp):
    1.         Entities
    2.         .ForEach((Entity Entity, int entityInQueryIndex, ref PlayerScore playerScore) =>
    3.         {
    4.             playerScore = playerScores[entityInQueryIndex];
    5.         }).Run();
    6.         playerScores.Dispose();
    7.         // highestScore.Dispose();
    8.         m_CommandBufferSystem.AddJobHandleForProducer(Dependency);
    Are these guarantees to have the same entities in the same index?
     
  2. Sarkahn

    Sarkahn

    Joined:
    Jan 9, 2013
    Posts:
    440
    As long as the query in the ForEach and the EntityQuery you call
    ToComponentDataArray
    /
    ToEntityArray
    from both have the exact same archetype they are guaranteed to align.
     
  3. adammpolak

    adammpolak

    Joined:
    Sep 9, 2018
    Posts:
    450
    That's great news! Both are just calling a "PlayerScore" component so all good. Thank you Sarkahn and Merry Christmas!