Search Unity

Bug Non Replicated Components not present in the Ghost Prefab/Instance

Discussion in 'NetCode for ECS' started by Opeth001, Nov 11, 2023.

  1. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Hello Unity Team,

    Non Replicated Components Added added to ghosts shows in the GhostAuthoringInspectionComponent but not present in the Ghost Prefab/Instance.

    Notes:

    Sample:
    Code (CSharp):
    1.  [WorldSystemFilter(WorldSystemFilterFlags.BakingSystem)]
    2.     [RequireMatchingQueriesForUpdate, BurstCompile]
    3.     public partial struct GameplayActorBakingSystem : ISystem
    4.     {
    5.         //GameplayAttributes Data
    6.         private NativeBitArray _gameplayAttributesReplicatedComponentsMask;
    7.         private NativeHashMap<AttributeKey, ComponentType> _gameplayAttributesReplicatedComponentTypes;
    8.  
    9.         //GameplayTags Data
    10.         private NativeBitArray _gameplayTagsReplicatedComponentsMask;
    11.         private NativeHashMap<int, ComponentType> _gameplayTagsReplicatedComponentTypes;
    12.  
    13.         public void OnCreate(ref SystemState state)
    14.         {
    15.             //GameplayAttributes
    16.             var gameplayAttributesGenerator = GameplayAttributesGenerator.Instance;
    17.             _gameplayAttributesReplicatedComponentsMask =
    18.                 gameplayAttributesGenerator.GetReplicationBitMask(Allocator.Persistent);
    19.             _gameplayAttributesReplicatedComponentTypes =
    20.                 gameplayAttributesGenerator.GetReplicatedComponentTypesHashMap(Allocator.Persistent);
    21.  
    22.             //GameplayTags
    23.             var gameplayTagsGenerator = GameplayTagsGenerator.Instance;
    24.             _gameplayTagsReplicatedComponentsMask =
    25.                 gameplayTagsGenerator.GetReplicationBitMask(Allocator.Persistent);
    26.             _gameplayTagsReplicatedComponentTypes =
    27.                 gameplayTagsGenerator.GetReplicatedComponentTypesHashMap(Allocator.Persistent);
    28.         }
    29.  
    30.         [BurstCompile]
    31.         public void OnUpdate(ref SystemState state)
    32.         {
    33.             var ecb = new EntityCommandBuffer(Allocator.TempJob);
    34.             var replicateComponentsAndTagsJobs = new ReplicateComponentsAndTagsJobs()
    35.             {
    36.                 gameplayTagsReplicatedComponentsMask = _gameplayTagsReplicatedComponentsMask,
    37.                 gameplayTagsReplicatedComponentTypes = _gameplayTagsReplicatedComponentTypes,
    38.  
    39.                 gameplayAttributesReplicatedComponentsMask = _gameplayAttributesReplicatedComponentsMask,
    40.                 gameplayAttributesReplicatedComponentTypes = _gameplayAttributesReplicatedComponentTypes,
    41.  
    42.                 ecb = ecb,
    43.             };
    44.  
    45.             state.Dependency = replicateComponentsAndTagsJobs.Schedule(state.Dependency);
    46.  
    47.             state.CompleteDependency();
    48.  
    49.             if (ecb.ShouldPlayback)
    50.                 ecb.Playback(state.EntityManager);
    51.  
    52.             ecb.Dispose();
    53.         }
    54.  
    55.         [BurstCompile]
    56.         public void OnDestroy(ref SystemState state)
    57.         {
    58.             //GameplayAttributes
    59.             _gameplayAttributesReplicatedComponentsMask.Dispose();
    60.             _gameplayAttributesReplicatedComponentTypes.Dispose();
    61.             //GameplayTags  
    62.             _gameplayTagsReplicatedComponentsMask.Dispose();
    63.             _gameplayTagsReplicatedComponentTypes.Dispose();
    64.         }
    65.  
    66.  
    67.         [BurstCompile]
    68.         public unsafe partial struct ReplicateComponentsAndTagsJobs : IJobEntity
    69.         {
    70.             //GameplayAttributes
    71.             [ReadOnly] public NativeBitArray gameplayAttributesReplicatedComponentsMask;
    72.  
    73.             [ReadOnly] public NativeHashMap<AttributeKey, ComponentType> gameplayAttributesReplicatedComponentTypes;
    74.  
    75.             //GameplayTags
    76.             [ReadOnly] public NativeBitArray gameplayTagsReplicatedComponentsMask;
    77.             [ReadOnly] public NativeHashMap<int, ComponentType> gameplayTagsReplicatedComponentTypes;
    78.  
    79.             public EntityCommandBuffer ecb;
    80.  
    81.             private void Execute(Entity actorEntity,
    82.                 in DynamicBuffer<ActorGameplayAttributes> actorGameplayAttributes,
    83.                 in ActorGameplayTags actorGameplayTags)
    84.             {
    85.                 //Replicate Attributes as Components  
    86.                 for (var i = 0; i < actorGameplayAttributes.Length; i++)
    87.                 {
    88.                     var attribute = actorGameplayAttributes[i];
    89.  
    90.                     //Check if Attribute Require Replication or Component Code is generated
    91.                     if (!gameplayAttributesReplicatedComponentsMask.IsSet(attribute.Key.value) ||
    92.                         !gameplayAttributesReplicatedComponentTypes.TryGetValue(attribute.Key, out var componentType))
    93.                         continue;
    94.  
    95.                     //Replicate Attribute Component
    96.                     ecb.AddComponentDataUnsafe(actorEntity, componentType.TypeIndex,
    97.                         4, UnsafeUtility.AddressOf(ref attribute.Value.Current));
    98.                 }
    99.  
    100.                 //Add the Applied GameplayTags as ComponentTags.
    101.                 for (var i = 0; i < gameplayTagsReplicatedComponentsMask.Length; i++)
    102.                     if (actorGameplayTags.Base.IsBitSet(i) && //The Applied GameplayTag
    103.                         gameplayTagsReplicatedComponentsMask.IsSet(i)) //The GameplayTag Require Replication
    104.  
    105.                         //Add the Replicated ComponentType
    106.                         if (gameplayTagsReplicatedComponentTypes.TryGetValue(i, out var tagComponentType))
    107.                             ecb.AddComponent(actorEntity, tagComponentType);
    108.             }
    109.         }
    110.     }

    ECB Extension:
    Code (CSharp):
    1.  
    2. namespace Unity.Entities
    3. {
    4.     public static unsafe class EntityCommandBufferExtension
    5.     {
    6.        
    7.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
    8.         public static void SetComponentDataUnsafe(this ref EntityCommandBuffer.ParallelWriter ecb, int sortKey, Entity e
    9.             , TypeIndex typeIndex, int typeSize, void* componentDataPtr) =>
    10.             ecb.UnsafeSetComponent(sortKey, e, typeIndex, typeSize, componentDataPtr);
    11.  
    12.      
    13.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
    14.         public static void SetComponentDataUnsafe(this ref EntityCommandBuffer ecb, Entity e, TypeIndex typeIndex,
    15.             int typeSize, void* componentDataPtr) =>
    16.             ecb.UnsafeSetComponent(e, typeIndex, typeSize, componentDataPtr);
    17.  
    18.          
    19.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
    20.         public static void AddComponentDataUnsafe(this ref EntityCommandBuffer.ParallelWriter ecb, int sortKey,
    21.             Entity e, TypeIndex typeIndex, int typeSize, void* componentDataPtr) =>
    22.             ecb.UnsafeAddComponent(sortKey, e, typeIndex, typeSize, componentDataPtr);
    23.  
    24.  
    25.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
    26.         public static void AddComponentDataUnsafe(this ref EntityCommandBuffer ecb, Entity e, TypeIndex typeIndex,
    27.             int typeSize, void* componentDataPtr) =>
    28.             ecb.UnsafeAddComponent(e, typeIndex, typeSize, componentDataPtr);
    29.     }
    30. }

    GhostAuthoringInspectionComponent: