Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

(Question) NetCode How to Identify Local Player

Discussion in 'NetCode for ECS' started by Ericky14, Mar 29, 2020.

  1. Ericky14

    Ericky14

    Joined:
    Jun 10, 2016
    Posts:
    34
    Hello,

    I am fairly new to the data oriented approach and I have been watching all the available tutorials and looking at the DOTS example project. But I am still having trouble understanding all the concepts of it.

    How would you go about identifying which of the entities with LocalPlayer data component is the player for that connection? Basically if I wanted to do specific logic to it such as coloring its mesh a different color.

    I have this code that spawns the network players,

    Code (CSharp):
    1. [UpdateInGroup(typeof(ClientSimulationSystemGroup))]
    2. public class GoInGameClientSystem : ComponentSystem {
    3.     protected override void OnCreate() {
    4.     }
    5.  
    6.     protected override void OnUpdate() {
    7.         Entities.WithNone<NetworkStreamInGame>().ForEach((Entity ent, ref NetworkIdComponent id) => {
    8.             PostUpdateCommands.AddComponent<NetworkStreamInGame>(ent);
    9.             var req = PostUpdateCommands.CreateEntity();
    10.             PostUpdateCommands.AddComponent<GoInGameRequest>(req);
    11.             PostUpdateCommands.AddComponent(req, new SendRpcCommandRequestComponent { TargetConnection = ent });
    12.         });
    13.     }
    14. }
    15.  
    16. [UpdateInGroup(typeof(ServerSimulationSystemGroup))]
    17. public class GoInGameServerSystem : ComponentSystem {
    18.     protected override void OnUpdate() {
    19.         Entities.WithNone<SendRpcCommandRequestComponent>().ForEach((Entity reqEnt, ref GoInGameRequest req, ref ReceiveRpcCommandRequestComponent reqSrc) => {
    20.             PostUpdateCommands.AddComponent<NetworkStreamInGame>(reqSrc.SourceConnection);
    21.             UnityEngine.Debug.Log(String.Format("Server setting connection {0} to in game", EntityManager.GetComponentData<NetworkIdComponent>(reqSrc.SourceConnection).Value));
    22.             var ghostCollection = GetSingleton<GhostPrefabCollectionComponent>();
    23.             var ghostId = ShooterGhostSerializerCollection.FindGhostType<PlayerSnapshotData>();
    24.             var prefab = EntityManager.GetBuffer<GhostPrefabBuffer>(ghostCollection.serverPrefabs)[ghostId].Value;
    25.             var player = EntityManager.Instantiate(prefab);
    26.  
    27.             EntityManager.SetComponentData(player, new LocalPlayer {
    28.                 PlayerId = EntityManager.GetComponentData<NetworkIdComponent>(reqSrc.SourceConnection).Value,
    29.                 playerEntity = player
    30.             });
    31.             PostUpdateCommands.AddBuffer<MovementInput>(player);
    32.  
    33.             PostUpdateCommands.SetComponent(reqSrc.SourceConnection, new CommandTargetComponent { targetEntity = player });
    34.  
    35.             PostUpdateCommands.DestroyEntity(reqEnt);
    36.         });
    37.     }
    38. }
     
  2. Chebn

    Chebn

    Joined:
    Oct 25, 2019
    Posts:
    9
    Code (CSharp):
    1.  
    2. EntityManager.SetComponentData(player, new LocalPlayer {
    3.     PlayerId = EntityManager.GetComponentData<NetworkIdComponent>(reqSrc.SourceConnection).Value,
    4.     playerEntity = player
    5. });
    6.  
    That basically spawned a character with your network ID. With that network ID, you can now reference it in your code with something like this:

    Code (CSharp):
    1.  
    2. [UpdateInGroup(typeof(ClientSimulationSystemGroup))]
    3. public class YourSystem : SystemBase
    4. {
    5.     protected override void OnUpdate()
    6.     {
    7.         // Should define RequireSingletonForUpdate<NetworkIdComponent>() in OnCreate
    8.         var localPlayerId = this.GetSingleton<NetworkIdComponent>().Value;
    9.  
    10.         this.Dependency = Entities.ForEach((Entity entity, in LocalPlayer localPlayer) =>
    11.         {
    12.             if (localPlayer.Identifier == localPlayerId)
    13.             {
    14.                 // do your player specific thing
    15.             }
    16.         }).Schedule(this.Dependency);
    17.     }
    18. }
    19.  
     
    AdamBebko likes this.
  3. Ericky14

    Ericky14

    Joined:
    Jun 10, 2016
    Posts:
    34
    Oh I see! Thank you very much!
     
  4. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,112
    Im not familiar with Dots Netcode, but I think this case can be handled by the normal Data oriented design Which is adding a CD Tag LocalPlayer for your local Player Entity.
    This way you can easly access that specific entity and prevent useless iterations and verifications, Specially if you have a lot of players.
     
    Orimay likes this.