- Home /
Command not being called on client
So the player move command isn't being called. The loop is being called and I checked that it is only on the local player. But the actual command isn't being called. The script is on the player prefab which is registered in the network manager. What am I doing wrong?
using UnityEngine;
using UnityEngine.Networking;
public class MovePlayer : NetworkBehaviour {
float speed;
Rigidbody2D rigidbody;
Player player;
int verticalDir = 0;
float rot_z;
int horizontalDir = 0;
void Start () {
player = gameObject.GetComponent<Player>();
rigidbody = gameObject.GetComponent<Rigidbody2D>();
speed = player.moveSpeed;
}
void Update () {
if (!player.dead && isLocalPlayer)
{
// Key Movement
verticalDir = 0;
horizontalDir = 0;
if (Input.GetKey("w"))
{
verticalDir += 1;
}
if (Input.GetKey("s"))
{
verticalDir -= 1;
}
if (Input.GetKey("a"))
{
horizontalDir -= 1;
}
if (Input.GetKey("d"))
{
horizontalDir += 1;
}
// Mouse Tracking
Vector3 diff = player.camera.ScreenToWorldPoint(Input.mousePosition) - transform.position;
diff.Normalize();
rot_z = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
CmdMove();
// Velocity limit
if (rigidbody.velocity.x > speed)
{
rigidbody.velocity = new Vector2(speed, rigidbody.velocity.y);
}
if (rigidbody.velocity.y > speed)
{
rigidbody.velocity = new Vector2(rigidbody.velocity.x, speed);
}
}
}
[Command]
void CmdMove()
{
var locVel = new Vector2(speed * horizontalDir, speed * verticalDir);
rigidbody.velocity = locVel;
gameObject.transform.rotation = Quaternion.Euler(0f, 0f, rot_z - 90);
}
}
Answer by Zarenityx · Aug 14, 2018 at 08:27 PM
It's quite likely that the command is being called, but you don't actually see it since none of the data you modify in it actually gets sent to the clients. Commands are called on the server, and so the server's version of the object had these values changed, but the clients never saw it. What's needed is a SyncVar or a ClientRPC. RPCs are called on the client, and can be called in a command function. This causes the Rpc function to be called on every client. What you need is something along the lines of:
[Command]
void CmdMove(Vector2 movedir, float rotz)
{
RpcMove(movedir, rotz);
}
[ClientRPC]
void RpcMove(Vector2 movedir, float rotz){
var locVel = movedir*speed;
rigidbody.velocity = locVel;
gameObject.transform.rotation = Quaternion.Euler(0f, 0f, rotz - 90);
}
(Code above is untested, but the general idea is that you need to be calling an RPC).
Note 2 things about the above code
The Command tells the server to call the RPC on all the clients
The movement vectors are passed in as parameters. The movement vector isn't synchronized and is only accurate on the client doing the moving. For all other clients and for the server this is zero, so we need to tell the server what our move vector is.
Alternately, the [SyncVar] attribute causes a variable to get sent to all clients whenever it is changed on the server, so the RPC step gets done for you.
Always remember that [Command], [ClientRPC], [TargetRPC], and [SyncVar] are just ways of hiding the messages that are being sent internally, and none of the other clients will know what your client knows until you tell the server and the server tells them.
Your answer
Follow this Question
Related Questions
How would I continue an object's movement in the same direction as per last user input? 1 Answer
How to handle movement in a multiplayer FPS? 0 Answers
Can I change movement from Unity 3d into Unity 3D iOS 2 Answers
Unity networking tutorial? 6 Answers
How to make your camera move to the middle of the player photon c#? 2 Answers