0
\$\begingroup\$

Im making a simple as possible scene in Unity for mulitplayer game. The character has a walking animation of which the speed is to be set exactly the same as the Z velocity relative to the object.

I have Unity Network Manager etc on the object and they spawn fine on multiple computers. They move fine also in terms of transform position, rotation etc.

On the screen that I am currently moused onto and active with, the animation speed also does work and stops at zero etc. But for the inactive screen, the walking animation is always at 1.00 default.

I've been trying to use a SyncVar to control the animSpeed. But I read that this is incorrect because Im sending the change to it via a call in the Client instance and not the server. It says I should use COMMAND but I am unsure if this needs to be within a script on my Player Object or do I need to make a script that attaches to the Network MAnager or something and would hold all the animSpeeds for each player object? (I kinda feel Unity Networking will do that, it says that SyncVars are handled automaticallly and updated when they change to all clients. - This implies to me I should be putting the COMMAND on the script for my Player object.)

Here is the script I have now that doesn't work correctly:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Player_mp : NetworkBehaviour {
CharacterController characterCont;
Animator anim;
public float walkSpeed, sideSpeed, turnSpeed;
Vector3 movementInWorldSpace;

[SyncVar] float animVelZ;

public override void OnStartClient()
{
    characterCont = GetComponent<CharacterController>();
    anim = GetComponentInChildren<Animator>();

}

void FixedUpdate () {
    if (!isLocalPlayer)
    {
        return;
    }

    float mouseX = Input.GetAxis("Mouse X");
    transform.SetPositionAndRotation(transform.position, Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y + (mouseX * turnSpeed * Time.deltaTime), transform.eulerAngles.z));

    Vector3 movement = new Vector3(Input.GetAxis("Horizontal") * walkSpeed * Time.deltaTime, 0, Input.GetAxis("Vertical") * sideSpeed * Time.deltaTime);
    movementInWorldSpace = transform.TransformVector(movement);

    Vector3 velLocalised = transform.InverseTransformVector(characterCont.velocity);
    //if (velLocalised != Vector3.zero) 
    //    Debug.Log("Vel = " + velLocalised);

    animVelZ = velLocalised.z;
    if (animVelZ < 0)
        animVelZ *= -1;
    anim.speed = animVelZ;
}

private void LateUpdate()
{
    if (!isLocalPlayer)
    {
        return;
    }

    characterCont.Move(movementInWorldSpace);
}

}

I've also tried this version with a method CmdSetAnimSpeed():

public class Player_mp : NetworkBehaviour {
CharacterController characterCont;
Animator anim;
public float walkSpeed, sideSpeed, turnSpeed;
Vector3 movementInWorldSpace;


[SyncVar] float animVelZ;

public override void OnStartClient()
{
    characterCont = GetComponent<CharacterController>();
    anim = GetComponentInChildren<Animator>();

}

void FixedUpdate () {
    if (!isLocalPlayer)
    {
        return;
    }

    float mouseX = Input.GetAxis("Mouse X");
    transform.SetPositionAndRotation(transform.position, Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y + (mouseX * turnSpeed * Time.deltaTime), transform.eulerAngles.z));

    Vector3 movement = new Vector3(Input.GetAxis("Horizontal") * walkSpeed * Time.deltaTime, 0, Input.GetAxis("Vertical") * sideSpeed * Time.deltaTime);
    movementInWorldSpace = transform.TransformVector(movement);


    CmdSetAnimSpeed();
}

private void LateUpdate()
{
    if (!isLocalPlayer)
    {
        return;
    }

    characterCont.Move(movementInWorldSpace);
}

[Command]
void CmdSetAnimSpeed()
{
    Vector3 velLocalised = transform.InverseTransformVector(characterCont.velocity);
    //if (velLocalised != Vector3.zero) 
    //    Debug.Log("Vel = " + velLocalised);

    animVelZ = velLocalised.z;
    if (animVelZ < 0)
        animVelZ *= -1;
    anim.speed = animVelZ;
}

}

Could anyone tell me how exactly I can make it so the 'animVelZ' speed can be set properly on the network and so they all stop their feet if not moving on every screen of the game? Thanks for any help

\$\endgroup\$
0
\$\begingroup\$

Ok, well almost by trial-and-error I seem to have fixed this. I will post what I did here in case it ever helps anyone, but hopefully it is correct. All I know is the speed of the animation is now syncing on all screens (ie. The Host server-client and all other remote clients)

I had to use ClientRpc instead of Command, and then in Update i put if isServer, then a call to the Rpc I made:

public class Player_mp : NetworkBehaviour {
CharacterController characterCont;
Animator anim;
public float walkSpeed, sideSpeed, turnSpeed;
Vector3 movementInWorldSpace;


float animVelZ;

public override void OnStartClient()
{
    characterCont = GetComponent<CharacterController>();
    anim = GetComponentInChildren<Animator>();
}

void FixedUpdate () {
    if (isServer)
    {
        RpcSetAnimSpeed();
    }

    if (!isLocalPlayer)
    {
        return;
    }



    float mouseX = Input.GetAxis("Mouse X");
    transform.SetPositionAndRotation(transform.position, Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y + (mouseX * turnSpeed * Time.deltaTime), transform.eulerAngles.z));

    Vector3 movement = new Vector3(Input.GetAxis("Horizontal") * walkSpeed * Time.deltaTime, 0, Input.GetAxis("Vertical") * sideSpeed * Time.deltaTime);
    movementInWorldSpace = transform.TransformVector(movement);



}

private void LateUpdate()
{
    if (!isLocalPlayer)
    {
        return;
    }

    characterCont.Move(movementInWorldSpace);
}

[ClientRpc]
void RpcSetAnimSpeed()
{
    Vector3 velLocalised = transform.InverseTransformVector(characterCont.velocity);
    //if (velLocalised != Vector3.zero) 
    //    Debug.Log("Vel = " + velLocalised);

    animVelZ = velLocalised.z;
    if (animVelZ < 0)
        animVelZ *= -1;
    anim.speed = animVelZ;
}

}

animSpeed , nor any of the variables used, needed to by a SyncVar

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.