Search Unity

Question Player prefab with scene references?

Discussion in 'Netcode for GameObjects' started by daniel_lochner, Jun 19, 2021.

  1. daniel_lochner

    daniel_lochner

    Joined:
    Jun 9, 2016
    Posts:
    175
    Hi there,

    I have a game scene where the player prefab already exists in the scene hierarchy. This is necessary, as many other scripts depend on components attached to the player (e.g., player statistics UI), and so need to be referenced in the inspector.

    From what I’ve found, there are two approaches I could take when using the default behaviour of “Create Player Prefab” in the
    NetworkManager
    , which handles spawning of the player on connect. I could add a “PlayerSetup” script to the game scene, which uses
    NetworkSpawnManager.GetPlayerObject()
    to set everything up load, or use singletons everywhere.

    Both aren’t ideal, as in the first case, I would have to “expose” private serialized fields (through properties) and have an additional script set everything up, and in the second case, I would prefer not having to use singletons where it feels unnecessary.

    What I would like to do instead, is have a script on the player which instructs the server to spawn itself over the network (all player prefabs are the same). This works on the host (as it is also the server), however doesn’t work on clients.

    What is the common practice for this?

    Thanks for your time!
     
  2. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    Don't know the recommended practice. I am sort of in the same boat and haven't gotten much support from the Discord. Nonetheless, here is my approach to attack GUI scripts to the player object. Note, that the player object is created "manually" using the SpawnAsPlayerObject() when the client is loading the Game scene:
    Code (CSharp):
    1.  
    2. private void Awake()
    3. {
    4.     PlayerController.onPlayerCreated += SetupComponents;
    5. }
    6.  
    7. private void SetupComponents(PlayerController player)
    8. {
    9.     if (player.OwnerClientId != NetworkManager.Singleton.LocalClientId) return;
    10.     damageReceiver = player.GetComponent<DamageReceiver>();
    11. }
    12.  
    13. PlayerController is a script on the play object that is being spawn and it has this:
    14. void Start()
    15. {
    16.     onPlayerCreated?.Invoke(this);
    17. }
    18.  
    19.  
    So essentially. When a player is created setup GUI components. But only if that player object is the Current client (so playerA get only playerA health and not PlayerB)

    I also have a null check in the UI update methods that returns if the necessary components are null. (UI should probably be event driven but have a few that is updated every update)
     
  3. daniel_lochner

    daniel_lochner

    Joined:
    Jun 9, 2016
    Posts:
    175
    Thanks! Yes, I went with a similar approach using a "PlayerSetup" script, and just used a Singleton pattern for the UI elements that needed referencing.