Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Issue with Retaining Animation Rigging State Across Multiplayer Clients [Mirror]

Discussion in 'Scripting' started by Joewa654321_, Oct 22, 2021.

  1. Joewa654321_

    Joewa654321_

    Joined:
    Apr 27, 2020
    Posts:
    32
    Hi all,

    As the title suggests, I've run into an issue that I cannot seem to solve pertaining to animation rigging state across multiplayer clients. To sum it up, I am using mirror and I have multi-aim constraints applied to my players torso and neck allowing forward and backward rotation of the spine and neck based on the where they are currently looking, and this positioning successfully carries over across clients. However, the issue is that when a client joins a game already in progress where the other players have already moved around, the animation rigging on the new clients screen for other players is warped/incorrect even though it still moves with the rig target.

    To rectify this, I have attempted to call commands from my custom network manager so that when a player joins the game, all players in the game send the position and rotation data for each bone through a clientRpc method which is supposed to update bone position and rotation for all clients so that everything matches across clients.

    The network manager method call:

    Code (CSharp):
    1.  
    2. for (int i = 0; i < playerList.Count; i++)
    3. {
    4. uint _netId = playerList[i].transform.GetComponent<NetworkIdentity>().netId;
    5. for (int j = 0; j < playerList[0].GetComponent<PlayerAnimation>().playerModel.GetComponent<SkinnedMeshRenderer>().bones.Length; j++)
    6. {
    7. Transform _bone = NetworkIdentity.spawned[_netId].GetComponent<PlayerAnimation>().playerModel.GetComponent<SkinnedMeshRenderer>().bones[j];
    8. playerList[0].GetComponent<PlayerAnimation>().DeconstructBonePosition(_netId, j, _bone.position.x, _bone.position.y, _bone.position.z, _bone.eulerAngles.x, _bone.eulerAngles.y, _bone.eulerAngles.z);
    9. }
    10. }
    The command and clientRpc methods:

    Code (CSharp):
    1. [Command]
    2. public void DeconstructBonePosition(uint netId, int _pos, float _targetXpos, float _targetYpos, float _targetZpos, float _targetXrot, float _targetYrot, float _targetZrot)
    3. {
    4. NetworkIdentity.spawned[netId].GetComponent<PlayerAnimation>().ReconstructBonePosition(_pos, _targetXpos, _targetYpos, _targetZpos, _targetXrot, _targetYrot, _targetZrot);
    5. }
    6.  
    7. [ClientRpc]
    8. public void ReconstructBonePosition(int _pos, float _targetXpos, float _targetYpos, float _targetZpos, float _targetXrot, float _targetYrot, float _targetZrot)
    9. {
    10. Transform _bone = playerModel.GetComponent<SkinnedMeshRenderer>().bones[_pos];
    11. _bone.position = new Vector3(_targetXpos, _targetYpos, _targetZpos);
    12. _bone.eulerAngles = new Vector3(_targetXrot, _targetYrot, _targetZrot);
    13. }
    Can someone potentially point out where I am going wrong? Any help is appreciated