Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We’re making changes to the Unity Runtime Fee pricing policy that we announced on September 12th. Access our latest thread for more information!
    Dismiss Notice
  3. Dismiss Notice

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 unity_3vBL-lfiBWfyrQ, Jun 5, 2023.

  1. unity_3vBL-lfiBWfyrQ

    unity_3vBL-lfiBWfyrQ

    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:
    21
    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. unity_3vBL-lfiBWfyrQ

    unity_3vBL-lfiBWfyrQ

    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. unity_3vBL-lfiBWfyrQ

    unity_3vBL-lfiBWfyrQ

    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