Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Resolved Handle local UI in multiplayer

Discussion in 'Netcode for GameObjects' started by casteillet, Nov 7, 2023.

  1. casteillet

    casteillet

    Joined:
    Jun 29, 2019
    Posts:
    13
    Hi,

    I was searching online opinions for managing local UI in multiplayer and I just found multiple answer like :

    - UI should update itself by getting the local client at OnNetworkSpawn() and then I think it could subscribe to events maybe ?
    - Player if it is local player can FindObject the UI and set variables from the player

    What do you think is the best option ?
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    7,263
    The first thing you ought to do is to decouple your UI from all other code. Put all UI code in its own assembly. UI consumes (depends on) other assemblies, but nothing else should depend on the UI except for, if needed, even higher level UI code.

    NOTHING in the UI should reference ANYTHING from the Netcode!

    The UI should not know whether a value it displays has been synchronized over the network, or was changed in singleplayer mode, or was modified through some other means (eg playback of an input recording aka 'replay'). The UI is a dumb state machine that receives value-changed events, and some state-change events (eg show the inventory). The UI should never synchronize any state over the network itself, or directly register with network synchronization events, because that tremendously increases the UI code's complexity and side-effects.

    Then the UI registers for events in the respective subsystems (eg Player, World, GameState) that it is interest in, eg. "OnPlayerHealthChanged" or "OnBeforeSceneChange" or "OnEnterCombatMode" etc etc

    Player-specific data the UI needs to display is registered through the "Player" class that handles the local player stuff. Everything else, like other player's data, names, hitpoints, and such would be handled by a NetworkGameState class the UI can register for event updates.
     
    Last edited: Nov 7, 2023
    RikuTheFuffs-U and casteillet like this.
  3. casteillet

    casteillet

    Joined:
    Jun 29, 2019
    Posts:
    13
    Thank you for this clear answer
     
    CodeSmile likes this.
  4. grifster

    grifster

    Joined:
    Mar 17, 2015
    Posts:
    2
    Do you have an example of how you would implement this? In the Unity NGO sample projects (e.g. Boss Room) they are directly subscribing to NetworkVariable OnValueChanged events in the UI. (See UIHealth / UIStateDisplay, for example).
     
  5. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    7,263
    That's okay because the UI is subscribing to an event, and it won't attempt to write to those variables (I hope).

    Basically that's how decoupling in general would work. You have a network state change, that raises an event, the UI subscribes to the events it is interested in. But the UI objects should not have a NetworkObject or NetworkTransform or send/receive RPCs.