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

Sync a special animation with the server?

Discussion in 'Multiplayer' started by dominicpoppe, Feb 13, 2018.

  1. dominicpoppe

    dominicpoppe

    Joined:
    Feb 10, 2018
    Posts:
    21
    Hey,

    I have an animation controller and so on. Everything works with the NetworkAnimator (all integers etc. ticked) and all that syncs with the server.

    I only have one issue, I call a special animation like this

    anim.Play ("Dance");

    this displays on the local client but not on the connected player.
    How would I only sync this single animation?

    The reason why I am not doing this with modifying integers or anything like that is because this animation has to be callable instantly and without waiting to exit, thats why anim.play works perfect.

    Regards
     
  2. dominicpoppe

    dominicpoppe

    Joined:
    Feb 10, 2018
    Posts:
    21
    Code (CSharp):
    1.  
    2.     void PlayAnimation(string Animation) {
    3.         if (!isLocalPlayer)
    4.         {
    5.             return;
    6.         }
    7.         CmdPlayAnimation(Animation);
    8.     }
    9.  
    10.     //Only executed on the Server but uses data from this client:
    11.     [Command]
    12.     void CmdPlayAnimation(string Animation) {
    13.         NetworkServer.FindLocalObject(this.netId).GetComponent<Animator>().Play(Animation);
    14.         RpcPlayAnimation(Animation);
    15.     }
    16.  
    17.     //Executes this on all connected players with server data:
    18.     [ClientRpc]
    19.     void RpcPlayAnimation(string Animation) {
    20.         anim.Play(Animation);
    21.     }
     
    Last edited: Feb 15, 2018
  3. dominicpoppe

    dominicpoppe

    Joined:
    Feb 10, 2018
    Posts:
    21
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. MovementController.RpcPlayAnimation (System.String Animation) (at Assets/MovementController.cs:184)
    3. MovementController.InvokeRpcRpcPlayAnimation (UnityEngine.Networking.NetworkBehaviour obj, UnityEngine.Networking.NetworkReader reader)
    This error I get now when a connected client sends the animation.
    I mean, everything is correctly displayed but apparently there is an issue.
    It is printed for line 20. Any ideas?
     
  4. ItsaMeTuni

    ItsaMeTuni

    Joined:
    Jan 19, 2015
    Posts:
    44
    anim variable is probably not being set correctly on other players. That would be my guess...
    Just use
    Code (CSharp):
    1. GetComponent<Animator>()
    so you don't need to set anim reference on start.

    Btw, you don't need to use
    Code (CSharp):
    1. NetworkServer.FindLocalObject(this.netId).GetComponent<Animator>()
    just use
    Code (CSharp):
    1. GetComponent<Animator>()
    since the command will be executed on the same object it was called by the client.
     
    dominicpoppe likes this.
  5. dominicpoppe

    dominicpoppe

    Joined:
    Feb 10, 2018
    Posts:
    21
    Thanks, that works aswell but I fixed it like this:

    Code (CSharp):
    1.     void PlayAnimation(string Animation) {
    2.         if (!isLocalPlayer)
    3.         {
    4.             return;
    5.         }
    6.         anim.Play(Animation);
    7.         NetworkIdentity myNetId = gameObject.GetComponent<NetworkIdentity> ();
    8.         CmdPlayAnimation(Animation, myNetId);
    9.     }
    10.  
    11.     //Only executed on the Server but uses data from this client:
    12.     [Command]
    13.     void CmdPlayAnimation(string Animation, NetworkIdentity senderAgent) {
    14.         Animator senderAgentAnim = senderAgent.transform.root.GetComponent<Animator> ();
    15.         senderAgentAnim.Play(Animation);
    16.         RpcPlayAnimation(Animation, senderAgent);
    17.     }
    18.  
    19.     //Executes this on all connected players with server data:
    20.     [ClientRpc]
    21.     void RpcPlayAnimation(string Animation, NetworkIdentity senderAgent) {
    22.         if (gameObject.GetComponent<NetworkIdentity> () == senderAgent) {
    23.  
    24.         } else {
    25.             Animator senderAgentAnim = senderAgent.transform.root.GetComponent<Animator> ();
    26.             senderAgentAnim.Play(Animation);
    27.         }
    28.     }
    That is fine aswell, isn't it? Maybe that helps some people in future aswell.
     
    ItsaMeTuni likes this.
  6. ItsaMeTuni

    ItsaMeTuni

    Joined:
    Jan 19, 2015
    Posts:
    44
    If it works then it is okay, but you don't need to send in the command parameters on which object it should play since the command will run on that object. Idk if you understand how all this works so I'll make a little schematic.

    Here it is:
    upload_2018-2-18_18-32-55.png

    The command will execute on the server-side instance of the object and the RPC will execute on the client-side instance of the object on all clients. It won't execute on all objects of that same class, it will execute on all versions of the same instance.

    Without the need to send who called the command as a parameter your code will be a lot simpler, cleaner and readable.
     
    dominicpoppe likes this.
  7. dominicpoppe

    dominicpoppe

    Joined:
    Feb 10, 2018
    Posts:
    21
    Thank's a lot that helped me to understand it much more!
     
    ItsaMeTuni likes this.