Search Unity

Question Animator sync does not work when the host has more than two connections. What's the problem?

Discussion in 'Netcode for GameObjects' started by ZYMA123, Jun 5, 2023.

  1. ZYMA123

    ZYMA123

    Joined:
    Jun 27, 2019
    Posts:
    8
    When the host has more than two connections, the host and the second client are in sync well, but the first client is out of sync.
    If to the host connection one client than everything works well.
    I will be grateful for help.
     
  2. neviovalsa

    neviovalsa

    Joined:
    Jun 24, 2019
    Posts:
    52
    Without details it's hard to answer, but maybe are attaching a `NetworkAnimator` component to clients with ownership? If that's the case you might want to try extending the NetworkAnimator component like so:

    Code (CSharp):
    1.     public class OwnerNetworkAnimator : NetworkAnimator
    2.     {
    3.         protected override bool OnIsServerAuthoritative()
    4.         {
    5.             return false;
    6.         }
    7.     }
     
  3. ZYMA123

    ZYMA123

    Joined:
    Jun 27, 2019
    Posts:
    8
    I tried this, but it didn't help me.
    My player prefab has a OwnerNetworkAnimator, Network Transport and Network Object(I show their configurations) and other components. adfds.png
    When a match is starting, the HostPlayer calls StartGame method and calls StartMove() method from the Runner:
    Code (CSharp):
    1. public class HostPlayer : INetworkPlayer
    2. {
    3.       public void StartGame()
    4.         {
    5.             Debug.Log("OnStartGame");
    6.             IEnumerator<IRunner> runners = _allRunnersNetworkObjectData.Keys.GetEnumerator();
    7.             while (runners.MoveNext() == true)
    8.             {
    9.                 if (_oldClientData?[_reversePlayersRunners[runners.Current]].IsFinished == true)
    10.                     continue;
    11.                 runners.Current.StartMove();
    12.             }
    13.  
    14.             // some code
    15.         }
    16. }
    Code (CSharp):
    1. public class Runner : MonoBehaviour, IRunner
    2. {
    3.      public void StartMove()
    4.         {
    5.             _cinemachineDollyCart.m_Speed = _startSpeed;
    6.  
    7.             if (_cinemachineDollyCart.m_Speed < MIN_MOVE_SPEED_VALUE)
    8.                 _cinemachineDollyCart.m_Speed = MIN_MOVE_SPEED_VALUE;
    9.             if (_cinemachineDollyCart.m_Speed > MAX_MOVE_SPEED_VALUE)
    10.                 _cinemachineDollyCart.m_Speed = MAX_MOVE_SPEED_VALUE;
    11.  
    12.             _animator.SetBool(_isRunningParamentrName, true);
    13.         }
    14. }
    The animator controller will be shown. asdfdsfd.png
    With one client(host + client) everything works well, but with two clients(host + first client + second client), first client's animator parameters "IsRunning" is not synchronized.
     
  4. ZYMA123

    ZYMA123

    Joined:
    Jun 27, 2019
    Posts:
    8
    I found a temporary option of solution for this problem:

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Netcode;
    3.  
    4. public class RunnerNetworkAnimator : NetworkBehaviour
    5.     {
    6.         #region Fields
    7.  
    8.         [Header("Animator")]
    9.         [SerializeField] private Animator _runnerAnimator;
    10.         [Header("Parameters")]
    11.         [SerializeField] private string _isRunningParameterName = "IsRunning";
    12.  
    13.         private NetworkVariable<bool> _isRunning = new NetworkVariable<bool>();
    14.  
    15.         #endregion
    16.  
    17.         #region Unity Methods
    18.  
    19.         public override void OnNetworkSpawn()
    20.         {
    21.             _isRunning.OnValueChanged += HandleParameterChanged;
    22.         }
    23.         public override void OnNetworkDespawn()
    24.         {
    25.             _isRunning.OnValueChanged -= HandleParameterChanged;
    26.         }
    27.  
    28.         #endregion
    29.  
    30.         #region Public Methods
    31.  
    32.         public void SetIsRunning(bool isRunning)
    33.         {
    34.             _isRunning.Value = isRunning;
    35.         }
    36.  
    37.         #endregion
    38.  
    39.         #region Private Methods
    40.  
    41.         private void HandleParameterChanged(bool oldValue, bool newValue)
    42.         {
    43.             _runnerAnimator.SetBool(_isRunningParameterName, newValue);
    44.         }
    45.  
    46.         #endregion
    47.     }
    But the question remains open because this problem is strange to me and I don't understand how to solve it.
     
    Last edited: Jun 6, 2023