Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Network Variable OnValueChanged not working

Discussion in 'Netcode for GameObjects' started by M1st3rButt3r, Jun 28, 2021.

  1. M1st3rButt3r

    M1st3rButt3r

    Joined:
    Oct 22, 2020
    Posts:
    11
    Hi there,
    we are currently testing the MLAPI and we ran pretty fast in a problem with the NetworkVariables. We have an enum to store the player states(Alive, Dead, ...). The Starting value is None. We subscribe to the OnValueChanged in NetworkStart and also change the value from None to Alive and this is working for the host, the problem is the client there the OnValueChanged event does not suplly the right value for the old Player State says Alive instead of None. This is kinda annoying. Does anyone has some advice or is more used to MLAPI and knows how to fix the Problem?

    Thanks!

    Unity Version: 2020.2.2f1
    MLAPI Version: 0.1
    Code:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Threading;
    5. using MLAPI;
    6. using MLAPI.Messaging;
    7. using MLAPI.NetworkVariable;
    8. using UnityEngine;
    9.  
    10. public enum PlayerState
    11. {
    12.     None,
    13.     Alive,
    14.     Dead
    15. }
    16.  
    17. public class Player : NetworkBehaviour
    18. {
    19.     private static readonly Dictionary<PlayerState, PlayerStateLogic> PlayerStates = new Dictionary<PlayerState, PlayerStateLogic>
    20.     {
    21.         {PlayerState.None, new PlayerStateNone()},
    22.         {PlayerState.Alive, new PlayerStateAlive()},
    23.         {PlayerState.Dead, new PlayerStateDead()}
    24.     };
    25.  
    26.     public readonly NetworkVariable<PlayerState> _playerState = new NetworkVariable<PlayerState>(new NetworkVariableSettings
    27.     {
    28.         ReadPermission = NetworkVariablePermission.Everyone,
    29.         WritePermission = NetworkVariablePermission.Everyone
    30.     }, PlayerState.None);
    31.  
    32.     public override void NetworkStart()
    33.     {
    34.         _playerState.OnValueChanged += ChangedPlayerState;
    35.         Debug.Log(_playerState.Value);
    36.         base.NetworkStart();
    37.         if (!IsServer)
    38.         {
    39.             return;    
    40.         }              
    41.                        
    42.         ChangePlayerState(PlayerState.Alive);
    43.     }                  
    44.                        
    45.     private void Update()
    46.     {                  
    47.         PlayerStates[_playerState.Value].Update();
    48.     }
    49.  
    50.     public void ChangePlayerState(PlayerState newPlayerState)
    51.     {
    52.         _playerState.Value = newPlayerState;
    53.         _playerState.SetDirty(true);
    54.     }
    55.  
    56.     private void ChangedPlayerState(PlayerState oldPlayerState, PlayerState newPlayerState)
    57.     {
    58.         Debug.Log($"{OwnerClientId} Changed Player State from {oldPlayerState.ToString()} to {newPlayerState.ToString()}");
    59.         PlayerStates[oldPlayerState].End();
    60.         PlayerStates[newPlayerState].Start();
    61.     }
    62. }
    63.  
     
  2. kakhao

    kakhao

    Joined:
    Jan 1, 2020
    Posts:
    4
    Better register delegate in OnEnable method. This way you won't miss even triggers.
     
  3. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
  4. makled

    makled

    Joined:
    May 28, 2017
    Posts:
    14
    This seems to remain an issue? Is there a workaround if you would like to change values on spawn?

    I tried invoking the change after 5 seconds of spawn, but it still remains a problem. The Network Variable changes, however the OnChanged event is never triggered
     
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    685
    I'm having the same issue. On the client when the object is spawned in the OnValueChanged call the previousValue and newValue are the same. This is a problem as the way I have it coded no action is taken if those values are the same. What's the best workaround for this?
     
  6. TheGamery

    TheGamery

    Joined:
    Oct 14, 2013
    Posts:
    94
    Not sure if this is related to your problem but just in case it is...

    I noticed when joining a server with players already spawned, the NetworkVariable already had a non-default value set in Start and OnValueChange wasn't called despite the delegate being set in OnEnable.

    My solution for now is to check for non-default value in start and then call the OnValueChange destination manually.
     
    cerestorm likes this.
  7. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    685
    I've not delved into players late joining so haven't come across that issue yet but thanks for mentioning it. Currently I do a specific condition check which I hope to remove when the issue is fixed. I did try working around it but it was creating timing issues and I decided it wasn't worth the hassle going down that route.