Search Unity

Bug Objects are duplicated in a client & server build

Discussion in 'NetCode for ECS' started by MhmdAL1111, Dec 1, 2022.

  1. MhmdAL1111

    MhmdAL1111

    Joined:
    Oct 25, 2017
    Posts:
    30
    Hi,

    When I run a client&server build, sprites are being rendered twice. This becomes clear when I increase the latency to something like 200ms. I have a system which moves these sprites (which are ghosts) in a path. This system runs only on the server world. For some reason, even though there is no presentation systems on the server world, the ghosts are being rendered twice. In both worlds the inspector shows that the ghosts have sprite renderers. When I connect to the instance running the server from another instance, I'm only creating a client world and so the gosts are rendering correctly.

    It does not happen in the NetCube sample, but I tried adding a sprite as a child of the cube prefab, and the same issue happens.

    Can someone inform me what I'm doing wrong?

    Thank you
     
  2. philsa-unity

    philsa-unity

    Unity Technologies

    Joined:
    Aug 23, 2022
    Posts:
    115
    While SpriteRenderers are compatible with baking, they do rely on a "Companion GameObject" to do their rendering (look for the "Companion Link" component on the converted entity of your sprite). Lights are another example of baking-compatible objects that rely on companion GameObjects.

    GameObjects and MonoBehaviours have no understanding of which ECS World they belong to, and their rendering doesn't get updated by ECS systems in the Presentation group. Therefore, if you have a sprite prefab that relies on a companion gameObject, and that prefab gets instantiated in both Client and Server worlds; this will instantiate two companion GameObjects, and they will both be rendered.

    A solution would be to separate the actual sprite object from the ghost prefab it belongs to, and find a way to only instantiate the sprite if its parent is in a world that has a PresentationSystemGroup
     
    Occuros, MhmdAL1111 and NikiWalker like this.
  3. MhmdAL1111

    MhmdAL1111

    Joined:
    Oct 25, 2017
    Posts:
    30
    Thank you for the reply

    I will try to find a way to disable the companion gameobject (or its sprite renderer) to the entity on the server world if that's possible, if that doesn't work I will try your solution.
     
  4. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    I just deleted the companion GO on server spawned objects at initialization. The GOs on pre-spawned objects share references so dont delete those or else it'll error about null reference exceptions.

    Edit: Here's the entirety of the script I use. ComponentLink requires internal access to obtain so a bit of ref-hack is required to make it work.
    Code (CSharp):
    1. [BurstCompile]
    2. [UpdateInGroup(typeof(InitializationSystemGroup))]
    3. [WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
    4. public partial struct ServerClearCompanions : ISystem
    5. {
    6.     private EntityQuery _players, _sprites;
    7.  
    8.     public void OnCreate(ref SystemState state)
    9.     {
    10.         _players = state.GetEntityQuery(EntityExt.CompLink, typeof(PlayerTag));
    11.         _sprites = state.GetEntityQuery(ComponentType.ReadOnly<SpriteRenderer>());
    12.         state.RequireAnyForUpdate(_players, _sprites);
    13.     }
    14.  
    15.     public void OnDestroy(ref SystemState state)
    16.     {
    17.     }
    18.  
    19.     [BurstCompile]
    20.     public void OnUpdate(ref SystemState state)
    21.     {
    22.         state.EntityManager.RemoveComponent(_players, EntityExt.CompLink);
    23.         state.EntityManager.RemoveComponent<SpriteRenderer>(_sprites);
    24.     }
    25. }
     
    Last edited: Dec 1, 2022
    MhmdAL1111 and philsa-unity like this.
  5. MhmdAL1111

    MhmdAL1111

    Joined:
    Oct 25, 2017
    Posts:
    30
    That worked! Thanks

    But I replaced
    Code (CSharp):
    1. EntityExt.CompLink
    with
    Code (CSharp):
    1. typeof(CompanionLink)
    and it worked.