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.
Take a look at this example project:
http://unity3d.com/support/resources/example-projects/networking-example
It has a script in it called “NetworkSyncAnimation” (Although I don’t understand as well as you might because it uses C#)
I looked at that project, but I dont understand whats going on. I need the most simplest example on how it is done.
That is the most simple example on how it’s done. The techniques used in that example are very basic.
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.
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.
public class NetworkSyncAnimation : MonoBehaviour {
//enum must stand for enumeration, so I believe this variable stores an array of integers
public enum AniStates
{
walk = 0,
run,
kick,
punch,
jump,
jumpfall,
idle,
gotbit,
gothit,
walljump,
deathfall,
jetpackjump,
ledgefall,
buttstomp,
jumpland
}
//Why is AniStates being declared again and where did
//currentAnimation come from, It was never declared as a variable first.
//could it be a extention of some sort of AniStates?
public AniStates currentAnimation = AniStates.idle;
public AniStates lastAnimation = AniStates.idle;
public void SyncAnimation(String animationValue)
{
//I dont get anything of whats going on with this line. What is Enum.Parse?
//animationValue was never declared as a variable.
currentAnimation = (AniStates)Enum.Parse(typeof(AniStates), animationValue);
}
// Update is called once per frame
void Update () {
if (lastAnimation != currentAnimation)
{
//why make lastAnimaiton equal current animation?
lastAnimation = currentAnimation;
//I dont know how this works
animation.CrossFade(Enum.GetName(typeof(AniStates), currentAnimation));
animation["run"].normalizedSpeed = 1.0F;
animation["walk"].normalizedSpeed = 1.0F;
}
}
//Does this function get called when something gets serialized?!? I have no idea.
void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
if (stream.isWriting)
{
//I dont understand what a char type is. What is (char)currentAnimation doing?
char ani = (char)currentAnimation;
//what is steam.Serialize doing? I dont understand whats in the argument. is ani a variable?
// it was never declared as one. Unless its being declared now.
//I dont know what type ref is
stream.Serialize(ref ani);
}
else
{
//did we just change ani from a ref to a char? Whats (char)0?
char ani = (char)0;
stream.Serialize(ref ani);
//whats with the parenthesis? And why is ani next to it?
currentAnimation = (AniStates)ani;
}
}
}
- Enum stands for Enumeration, correct. But AniStates is a type, not a variable.
- currentAnimation is declared right under AniStates. It’s a field, not a type, it doesn’t extend AniStates
- Enum.Parse takes a string and turns it into (if possible) the enum value of the type passed in whos name matches the string.
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.
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/75385-Ultimate-Unity-Networking-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.
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.
I’d strongly suggest starting with a single-player game, so you can find your feet with the language first.
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.
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!
In this script:
using UnityEngine;
using System.Collections;
using System;
public class NetworkSyncAnimation : MonoBehaviour {
public enum AniStates
{
walk = 0,
run,
kick,
punch,
jump,
jumpfall,
idle,
gotbit,
gothit,
walljump,
deathfall,
jetpackjump,
ledgefall,
buttstomp,
jumpland
}
public AniStates currentAnimation = AniStates.idle;
public AniStates lastAnimation = AniStates.idle;
public void SyncAnimation(String animationValue)
{
currentAnimation = (AniStates)Enum.Parse(typeof(AniStates), animationValue);
}
// Update is called once per frame
void Update () {
if (lastAnimation != currentAnimation)
{
lastAnimation = currentAnimation;
animation.CrossFade(Enum.GetName(typeof(AniStates), currentAnimation));
animation["run"].normalizedSpeed = 1.0F;
animation["walk"].normalizedSpeed = 1.0F;
}
}
void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
if (stream.isWriting)
{
char ani = (char)currentAnimation;
stream.Serialize(ref ani);
}
else
{
char ani = (char)0;
stream.Serialize(ref ani);
currentAnimation = (AniStates)ani;
}
}
}
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).
I will try this on my project since no one seems to want to help me.
Get a 1 month lynda.com subscription and do their C# essentials training video…
http://www.lynda.com/Visual-Studio-2010-tutorials/C-Essential-Training/83789-2.html
I’ve found out how to get animations to play over the network. It was just a matter of using a RPC.
function Update (){
if (Input.GetMouseButtonDown (0)){
networkView.RPC("animations",RPCMode.all);
}
}
@RPC
function animations( ){
animation.Play("shooting");
}
That is a very naive approach, the animations will end up being de-synced from the movement.
It appears synced to me when I run two instances though.
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 …
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.