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 have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Animations In Multiplayer

Discussion in 'Multiplayer' started by roger0, Jul 11, 2012.

  1. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I'm very new to networking and i'm trying to figure out how to sync character animations accross a multiplayer game. Such as a FPS game where players can see other players running, standing, etc. I've followed the Introduction to Networking tutorial on Unity Cookie. But thats all I know. Could someone post a simple code of how its done? I would think it has something to do with RPC functions.
     
  2. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
  3. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I looked at that project, but I dont understand whats going on. I need the most simplest example on how it is done.
     
  4. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    That is the most simple example on how it's done. The techniques used in that example are very basic.
     
  5. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,086
    Running, standing, etc. can be determined without any network traffic. If you're syncing positions and rotations already, each client can figure out how fast the remote players are moving by calculating position changes over time, and can play the right animations based on movement speed locally without needing the owner of that remote object to waste bandwidth.
     
  6. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    If it is the most simplest example, I will need a little help understanding. I dont know C# that well so its a little harder. The problem is I see alot of new terminology. This script is seperate from the script making the actual calls for the animation so I assume its dependant on that one. I've commented areas I need help with.

    Code (csharp):
    1.  
    2. public class NetworkSyncAnimation : MonoBehaviour {
    3.    
    4. //enum must stand for enumeration, so I believe this variable stores an array of integers
    5.  
    6.     public enum AniStates
    7.     {
    8.         walk = 0,
    9.         run,
    10.         kick,
    11.         punch,
    12.         jump,
    13.         jumpfall,
    14.         idle,
    15.         gotbit,
    16.         gothit,
    17.         walljump,
    18.         deathfall,
    19.         jetpackjump,
    20.         ledgefall,
    21.         buttstomp,
    22.         jumpland
    23.     }
    24.    
    25. //Why is AniStates being declared again and where did
    26. //currentAnimation come from, It was never declared as a variable first.
    27. //could it be a extention of some sort of AniStates?
    28.     public AniStates currentAnimation = AniStates.idle;
    29.     public AniStates lastAnimation = AniStates.idle;
    30.    
    31.     public void SyncAnimation(String animationValue)
    32.     {
    33.  //I dont get anything of whats going on with this line. What is Enum.Parse?
    34. //animationValue was never declared as a variable.
    35.         currentAnimation = (AniStates)Enum.Parse(typeof(AniStates), animationValue);
    36.     }
    37.    
    38.     // Update is called once per frame
    39.     void Update () {
    40.        
    41.         if (lastAnimation != currentAnimation)
    42.         {                
    43. //why make lastAnimaiton equal current animation?
    44.             lastAnimation = currentAnimation;
    45.  //I dont know how this works
    46.             animation.CrossFade(Enum.GetName(typeof(AniStates), currentAnimation));
    47.             animation["run"].normalizedSpeed = 1.0F;
    48.             animation["walk"].normalizedSpeed = 1.0F;
    49.         }
    50.     }
    51.    
    52. //Does this function get called when something gets serialized?!? I have no idea.
    53.     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    54.     {
    55.         if (stream.isWriting)
    56.         {          
    57. //I dont understand what a char type is. What is (char)currentAnimation doing?
    58.             char ani = (char)currentAnimation;
    59.  //what is steam.Serialize doing? I dont understand whats in the argument. is ani a variable?
    60.  // it was never declared as one. Unless its being declared now.
    61.  //I dont know what type ref is
    62.             stream.Serialize(ref ani);
    63.         }
    64.         else
    65.         {              
    66.  //did we just change ani from a ref to a char? Whats (char)0?
    67.             char ani = (char)0;
    68.             stream.Serialize(ref ani);
    69. //whats with the parenthesis? And why is ani next to it?
    70.             currentAnimation = (AniStates)ani;
    71.         }  
    72.    
    73.     }
    74.  
    75. }
     
    Last edited: Jul 12, 2012
  7. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    1) Enum stands for Enumeration, correct. But AniStates is a type, not a variable.
    2) currentAnimation is declared right under AniStates. It's a field, not a type, it doesn't extend AniStates
    3) Enum.Parse takes a string and turns it into (if possible) the enum value of the type passed in whos name matches the string.
     
  8. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    Hello. I accidently posted my message in the middle of writing it. So you probably got a half writting version. I've finished it now and updated it. Sorry about that.
     
  9. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Looking at your comments now, you basically need help with every single line of the whole script, now there's nothing wrong with that, but even if we help you here you will not get far after that before you need an entirely other script explained to you in minute detail. I would advice you to buy a C# book and a Unity book, read both of them, and then buy the "Ultimate Unity Networking Project", here: http://forum.unity3d.com/threads/75...ng-project-Add-multiplayer-to-your-game-today!

    I say this because some of the things you're asking are stuff that you will learn on literally page 2 of any C# book.
     
  10. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    Yeah I am pretty new at C#. So some of my questions will be very basic. Theres a couple books I found about to be ordered, and I just purchased the Unity Network project today. Although I have not found anything in it regarding playing animations in multiplayer games. So was a little disappointed.

    I'm still however, searching for a way to get animations to play on a multiplayer game. If someone can give me some more insight as to how its done, or explain the code above, it would greatly help.
     
    Last edited: Jul 13, 2012
  11. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    I'd strongly suggest starting with a single-player game, so you can find your feet with the language first.
     
  12. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I've been learning scripting for a solid 9 months. So I can translate C# and javascript alright if its basic enough. I'll learn C# eventually. But im not trying to learn a whole different language right now. Just trying to solve the animation issue.
     
  13. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    I'll help you, because I hate it when people tell me I have to go out and buy books and Unity assets, when you have the forums for free! :D

    In this script:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;
    5.  
    6. public class NetworkSyncAnimation : MonoBehaviour {
    7.    
    8.     public enum AniStates
    9.     {
    10.         walk = 0,
    11.         run,
    12.         kick,
    13.         punch,
    14.         jump,
    15.         jumpfall,
    16.         idle,
    17.         gotbit,
    18.         gothit,
    19.         walljump,
    20.         deathfall,
    21.         jetpackjump,
    22.         ledgefall,
    23.         buttstomp,
    24.         jumpland
    25.     }
    26.    
    27.     public AniStates currentAnimation = AniStates.idle;
    28.     public AniStates lastAnimation = AniStates.idle;
    29.    
    30.     public void SyncAnimation(String animationValue)
    31.     {
    32.         currentAnimation = (AniStates)Enum.Parse(typeof(AniStates), animationValue);
    33.     }
    34.    
    35.     // Update is called once per frame
    36.     void Update () {
    37.        
    38.         if (lastAnimation != currentAnimation)
    39.         {
    40.             lastAnimation = currentAnimation;
    41.             animation.CrossFade(Enum.GetName(typeof(AniStates), currentAnimation));
    42.             animation["run"].normalizedSpeed = 1.0F;
    43.             animation["walk"].normalizedSpeed = 1.0F;
    44.         }
    45.     }
    46.    
    47.     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    48.     {
    49.         if (stream.isWriting)
    50.         {
    51.             char ani = (char)currentAnimation;
    52.             stream.Serialize(ref ani);
    53.         }
    54.         else
    55.         {
    56.             char ani = (char)0;
    57.             stream.Serialize(ref ani);
    58.            
    59.             currentAnimation = (AniStates)ani;
    60.         }  
    61.    
    62.     }
    63.  
    64. }
    65.  
    Basically:

    public class NetworkSyncAnimation is a class (Holder of all the script data)

    enum AniStates are the different types of animation states you can have (Change these if necessary)

    current and last animations are what they obviously are. They are both default at idle.

    SyncAnimation is a void (function in javascript) that makes currentAnimaiton equal the type animation state you are sending.

    Update is called once per frame. In it, if the last animation is not the same as the current animation, we make it the same. Then we fade into the current animation. Also, we set the run and walk normalized speeds back to 1.0F

    OnSerializeNetworkView is called from the networkView component. Basically if we are sending data, (isWriting) then we stream.Serialize (send) the current animation. If we are receiving (else) we make our current animation the one we are receiving (ani).
     
  14. pezz

    pezz

    Joined:
    Apr 29, 2011
    Posts:
    606
    I will try this on my project since no one seems to want to help me.
     
  15. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,796
  16. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I've found out how to get animations to play over the network. It was just a matter of using a RPC.

    Code (csharp):
    1.  
    2. function Update (){
    3.  
    4. if (Input.GetMouseButtonDown (0)){
    5.  
    6.     networkView.RPC("animations",RPCMode.all);    
    7.    }
    8. }
    9.  
    10. @RPC
    11. function animations( ){
    12.  
    13. animation.Play("shooting");
    14. }
     
  17. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    That is a very naive approach, the animations will end up being de-synced from the movement.
     
  18. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    It appears synced to me when I run two instances though.
     
  19. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    yeah it's not, unless if you're running them on the same machine with 0 ping, which of course would lead to them being so close to synced that u cant tell the difference ...
     
  20. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    It seems to be a problem I have not discoverd yet. What could I do to ensure they are synced? Is calling animations different than any other RPC function?

    ps : im only going off of the networking tutorial on blender cookie here.
     
  21. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    You left me hanging. Lol. What am I doing wrong?
     
  22. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    Is this the most efficient and simplest way to play animations over a network? Or is there another way?

    Code (csharp):
    1. function Update (){
    2.      
    3.     if (Input.GetMouseButtonDown (0)){
    4.      
    5.         networkView.RPC("animations",RPCMode.all);    
    6.        }
    7.     }
    8.      
    9.     @RPC
    10.     function animations( ){
    11.      
    12.     animation.Play("shooting");
    13.     }
     
  23. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Movement animations can be deduced from velocity vectors and the rotation, so those should not even be necessary to send. Other animations should in general play as a response to some event which is raised and is almost never transmitted directly.
     
  24. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    Thanks for getting back. Your a little over my head. I never dealt much with events. The only way I know to send information is with plain network views or RPC's. So i'm not sure how an event would work.
     
  25. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I'm anxious to hear what the optimum way of doing this is.
     
  26. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,086
    An event would be like "I shot my gun". You would probably create such an event by sending an RPC or serializing a state, like an "isFiring" boolean or something. A firing event would consist of things like: enable a muzzle flash briefly, do raycasting to detect if we hit anything, play a firing animation, etc.

    What fholm is saying is most animation states should be able to be deduced directly from these events, rather than synchronized separately; that'd be a waste of bandwidth.
     
  27. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    In that case, how would I modify my shooting script adove so it gets by with the least amount of bandwidth?
     
  28. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I am very new to networking so I really can't interpret your explanation. I''m sure I'll understand more with some example code.
     
  29. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    The way this is done in general is using a bitmask of proper size, usually usually 16-64 bits depending on the complexity of your game, that contains the current state of the character which is broadcasted whenever it changes.

    Depending on the rate of change of the bitmask and the size, you're sometimes better of sending bytes, which will give you 256 different events!
     
  30. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I'm not familiar with that terminology. Perhaps you could show me how its done with UnityScript?
     
  31. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    The method i've been using to pass animations through the network have been working. I've got my game to run on three computers without game ending lag. Although it needs to be improved.

    If theres a optimum way to script RPC calls I would like to hear it. Otherwise i'll keep doing it the way i've been. And see what happens.
     
  32. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    You don't use RPCs at all, that's the point. They have a high cost and can't be sent unreliably, making them very bad for synchronizing rapidly changing state.
     
  33. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    How do I send information over a network without RPC's? Thats the part I dont get.
     
  34. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    Come on guys. I'm only getting a few sentences back per day. Your knowledge could really save me a lot of time. Thanks for the tid bits though. At least I know i'm doing something wrong.
     
  35. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I'm sorry but do we owe you something? Stop demanding answers, people help out of the kindness of their heart. If no one answers maybe they don't have time, know how to help you or want to help?
     
  36. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    You don't owe me anything. I'd just thought giving a nudge would help. But if your so easily offended you don't have to bother with me.
     
  37. waqaraliu

    waqaraliu

    Joined:
    Sep 18, 2012
    Posts:
    2
    u r an ***
     
  38. TackCo

    TackCo

    Joined:
    Jan 5, 2017
    Posts:
    1
    Hey if it's still a problem, I will solve a small portion of it. Say you have been sent two movement position through the magic that is networking. I'm not gonna tell you how they got sent, but now your PC knows "hey this was where they are last update, and this is where they are now." The others are telling you to write a script that goes "hey! The original position was on the ground here and now the new one is here in the air a bit away! They must have (whatever action could have happened)!" There are a few things that all movements share so you should practice getting a system to recognize the type of movement from two points, don't even bother with the networking right now. Write a program that, when fed two points, returns a string equal to whatever action was taken to happen between them. If you gave it point A and B, it should say something like "Walked" or "WalkJumped" or something of the like. Once you get the core functionality down so it is light and fast, then try linking the network to it, then finally the animations and actual movement. So to break it down once more, write a movement detection program that ONLY needs two points, then try sending those points over the network and having it stay fast, then finally link those points and the returned state to a movement and an animation which works over the web. I am not enough of a coding expert to do this for you off of the top of my head, but if you start and send me your progress I can help you out.

    Cheers,

    Tack Co (I'm not British)