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

Bug Issue with GhostType definition of the Netcode sample PredictedSpawning

Discussion in 'NetCode for ECS' started by FaithlessOne, Apr 8, 2023.

  1. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    257
    While implementing the PredictedSpawning feature in at test project to learn and gain experiences using ECS netcode I looked into the Netcode sample "PredictedSpawning":
    There I found a small issue in the struct "ClassificationSystem" regarding the "GhostCollectionPrefab" which contains all the ghost prefabs. The prefab supplied by the "GrenadeSpawner" authoring could not find a match in the stated collection. Therefore the line 14 of the OnUpdate-call got never executed which can be identified setting a breakpoint there which is never reached while playing the scene in the editor:
    Code (CSharp):
    1.  
    2.         [BurstCompile]
    3.         public void OnUpdate(ref SystemState state)
    4.         {
    5.             if (m_GhostType == 0)
    6.             {
    7.                 // Lookup the grenade prefab entity in the ghost prefab list, from there we can find the ghost type for this prefab
    8.                 var prefabEntity = SystemAPI.GetSingleton<GrenadeSpawner>().Grenade;
    9.                 var collectionEntity = SystemAPI.GetSingletonEntity<GhostCollection>();
    10.                 var ghostPrefabTypes = state.EntityManager.GetBuffer<GhostCollectionPrefab>(collectionEntity);
    11.                 for (int i = 0; i < ghostPrefabTypes.Length; ++i)
    12.                 {
    13.                     if (ghostPrefabTypes[i].GhostPrefab == prefabEntity)
    14.                         m_GhostType = ghostPrefabTypes[i].GhostType.GetHashCode();
    15.                 }
    16.             }
    17.             m_SnapshotDataLookupHelper.Update(ref state);
    18.             m_PredictedGhostSpawnLookup.Update(ref state);
    19.             m_GrenadeDataLookup.Update(ref state);
    20.             var ghostCollection = SystemAPI.GetSingletonEntity<GhostCollection>();
    21.             var classificationJob = new ClassificationJob
    22.             {
    23.                 ghostMap = SystemAPI.GetSingleton<SpawnedGhostEntityMap>().Value,
    24.                 snapshotDataLookupHelper = m_SnapshotDataLookupHelper,
    25.                 ghostCollectionSingleton = ghostCollection,
    26.                 spawnListEntity = SystemAPI.GetSingletonEntity<PredictedGhostSpawnList>(),
    27.                 PredictedSpawnListLookup = m_PredictedGhostSpawnLookup,
    28.                 grenadeDataLookup = m_GrenadeDataLookup,
    29.                 ghostType = m_GhostType
    30.             };
    31.             state.Dependency = classificationJob.Schedule(state.Dependency);
    32.         }
    The code in the stuct "ClassificationJob" which depends on the "GhostType" may not work properly then. I only wanted to report the issue. The sample still works despite the issue. I tested with Unity 2022.2.14 and used the samples provided for version 1.0.0-pre.65 of ECS.
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    774
    Thanks for reporting. Indeed is not correct, since the prefab that is registered with the GhostCollection is not the one in the spawner.

    The ghostType is used only for avoiding a classification issue with predicted players. So it does not cause problem for the local player in general.
    But indeed this should be fixed! Thanks!
     
    FaithlessOne likes this.
  3. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    257
    @CMarastoni
    So, the samples have been updated with release of Unity 2022.3, so I checked the PredictedSpawn sample again. Line 14 of my intial post is indeed executed now, so the m_ghostType is set and provided to the classification job. But lets have a look at the Execute method of the ClassificationJob:
    Code (CSharp):
    1.             public void Execute(DynamicBuffer<GhostSpawnBuffer> ghosts, DynamicBuffer<SnapshotDataBuffer> data)
    2.             {
    3.                 var predictedSpawnList = PredictedSpawnListLookup[spawnListEntity];
    4.                 var snapshotDataLookup = snapshotDataLookupHelper.CreateSnapshotBufferLookup();
    5.                 for (int i = 0; i < ghosts.Length; ++i)
    6.                 {
    7.                     var newGhostSpawn = ghosts[i];
    8.                     if (newGhostSpawn.SpawnType != GhostSpawnBuffer.Type.Predicted || newGhostSpawn.HasClassifiedPredictedSpawn || newGhostSpawn.PredictedSpawnEntity != Entity.Null)
    9.                         continue;
    10.  
    11.                     // Mark all the grenade spawns as classified even if not our own predicted spawns
    12.                     // otherwise spawns from other players might be picked up by the default classification system when
    13.                     // it runs when we happen to have a predicted spawn in the predictedSpawnList not yet classified here
    14.                     if (newGhostSpawn.GhostType == ghostType)
    15.                         newGhostSpawn.HasClassifiedPredictedSpawn = true;
    16.  
    17.                     // Find new ghost spawns (from ghost snapshot) which match the predict spawned ghost type handled by
    18.                     // this classification system. Match the spawn ID data from the new spawn (by lookup it up in
    19.                     // snapshot data) with the spawn IDs of ghosts in the predicted spawn list. When matched we replace
    20.                     // the ghost entity of that new spawn with our predict spawned entity (so the spawn will not result
    21.                     // in a new instantiation).
    22.                     for (int j = 0; j < predictedSpawnList.Length; ++j)
    23.                     {
    24.                         if (newGhostSpawn.GhostType == predictedSpawnList[j].ghostType)
    25.                         {
    26.                             if (snapshotDataLookup.TryGetComponentDataFromSnapshotHistory(newGhostSpawn.GhostType, data, out GrenadeData grenadeData, i))
    27.                             {
    28.                                 var spawnIdFromList = grenadeDataLookup[predictedSpawnList[j].entity].SpawnId;
    29.                                 if (grenadeData.SpawnId == spawnIdFromList)
    30.                                 {
    31.                                     newGhostSpawn.PredictedSpawnEntity = predictedSpawnList[j].entity;
    32.                                     predictedSpawnList[j] = predictedSpawnList[predictedSpawnList.Length - 1];
    33.                                     predictedSpawnList.RemoveAt(predictedSpawnList.Length - 1);
    34.                                     break;
    35.                                 }
    36.                             }
    37.                         }
    38.                     }
    39.                     ghosts[i] = newGhostSpawn;
    40.                 }
    41.             }
    I tested with launching a grenade and the line 15 in the Execute method above gets not called which uses the ghostType. You may correct me, but the ghostType member of the job contains a hashcode and the hashcode does not seem to match the newGhostSpawn.GhostType. The number ranges seem to be quite different. Thats what it looks in the Debugger when launching a grenade:
    upload_2023-6-17_17-21-23.png
    So it seems to me, that there is still a bug. I use a GhostClassificationSystem in my project which is based on the sample code and only want to ensure that it works as expected.

    Edit: Created a bug report in IN-45105
     
    Last edited: Jun 23, 2023
  4. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    257
  5. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    224
    Hey FaithlessOne! You're right, it's very odd that the ECSB-504 issue no longer exists, but the IN-45105 link does. I've pinged the relevant QA folk to see what's going on there. As for status: We're actually looking at this issue in this sprint, so it should be sorted relatively soon. Thanks for the report about the bug link itself (lol), and for your patience.
     
    FaithlessOne likes this.
  6. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    224