Search Unity

[Netcode, Playmode] How to check if Playmode is started as server or client

Discussion in 'NetCode for ECS' started by metalfussel, Apr 4, 2020.

  1. metalfussel

    metalfussel

    Joined:
    Nov 14, 2019
    Posts:
    8
    Hi, im new to Unity and Netcode and i have a question:
    With netcode i can choose if the playmode is starting as client, server or both over "Multiplayer" -> "PlayMode tools", how can is check in a c# script if im running as server or client?
    The "UNITY_SERVER" definition is set when i build the game and then run it, is there something similar in playmode?
     
  2. RichardWepner

    RichardWepner

    Joined:
    May 29, 2013
    Posts:
    33
    Well, a workaround would be to check the worlds that got created. If there is a server world, the game also runs the server. On the other hand: why do you want to check this?
     
  3. RichardWepner

    RichardWepner

    Joined:
    May 29, 2013
    Posts:
    33
    I took a look into the package sources and inside "ClientServerBootstrap" i found the following line:
    Code (CSharp):
    1. public static PlayType RequestedPlayType => (PlayType) UnityEditor.EditorPrefs.GetInt("MultiplayerPlayMode_" + UnityEngine.Application.productName + "_Type");
    I assume you could use the same code to determine the playtype, but don't forget to surround it with
    #if UNITY_EDITOR
    and
    #endif
    , because otherwise it'll work in the editor but not in a build.
     
  4. Flipps

    Flipps

    Joined:
    Jul 30, 2019
    Posts:
    51
    I am using a NetworkUtility class:
    (note: i am only using the Simulation Gorups)


    Code (CSharp):
    1. public static class NetworkUtility
    2. {
    3.     public static World GetServerWorld()
    4.     {
    5.         return GetWorld<ClientSimulationSystemGroup>();
    6.     }
    7.  
    8.     public static World GetClientWorld()
    9.     {
    10.         return GetWorld<ClientSimulationSystemGroup>();
    11.     }
    12.  
    13.     private static World GetWorld<TWorld>() where TWorld : ComponentSystemGroup
    14.     {
    15.         foreach (var world in World.All)
    16.         {
    17.             if (world.GetExistingSystem<TWorld>() != null)
    18.             {
    19.                 return world;
    20.             }
    21.         }
    22.         return null;
    23.     }
    24.  
    25.     public static bool IsClientWorld(World world)
    26.     {
    27.         return world.GetExistingSystem<ClientSimulationSystemGroup>() != null;
    28.     }
    29.  
    30.     public static bool IsServerWorld(World world)
    31.     {
    32.         return world.GetExistingSystem<ServerSimulationSystemGroup>() != null;
    33.     }
    34. }
     
  5. RichardWepner

    RichardWepner

    Joined:
    May 29, 2013
    Posts:
    33
    @Flipps: your
    GetServerWorld
    and
    GetClientWorld
    do the exact same thing. I guess the server one is supposed to use the
    ServerSimulationSystemGroup
    , isn't it?
     
  6. metalfussel

    metalfussel

    Joined:
    Nov 14, 2019
    Posts:
    8
    Thanks both of you! :)
    Richard, your solution works fine.
    Thanks Flipps for your solution, i'll try that one, but first i'll have to read more about SimulationGroups etc. :)

    EDIT: i want to check this, because i have one project for the client and the server and i have a empty scene to start with in which i check if i have to load a "menu scene"(if started as client) or if i can directly load the real game scene.
     
  7. Flipps

    Flipps

    Joined:
    Jul 30, 2019
    Posts:
    51
    You are right, thanks for the hint!
     
  8. RichardWepner

    RichardWepner

    Joined:
    May 29, 2013
    Posts:
    33
    I didn't do it myself, but the documentation mentions that you can implement your own bootstrapper with your own, custom logic (and your own configuration).

    and @Flipps code is basically my first suggestion. Since you probably want to create your own bootstrapper, it looks more like a workaround to me tbh.