客户端命令未被称为Unity3D

时间:2018-08-14 12:58:16

标签: c# unity3d

因此没有在客户端上调用播放器移动命令(主机可以)。正在调用该循环,我检查了它是否仅在本地播放器上。但是实际的命令没有被调用。该脚本在网络管理器中注册的播放器预制件上。我在做什么错了?

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);
    }
}

1 个答案:

答案 0 :(得分:0)

您使用/认为command错误!我将尝试简短地解释一下:

  • [Command]由客户端调用,但在服务器上执行!
  • [ClientRpc]由服务器调用,但由 ALL 客户端
  • 执行
  • [Client]仅确保该方法只能由客户端执行

现在是一个代码示例:

// This is called by the client
[Client]
private void DoSomething()
{
    if(!isLocalPlayer) return;

    // Here we call the command on the server passing our gameObject
    CmdDoSomething(gameObject);
}

// This is only executed on the server
// Since the player has a NetworkIdentity the server can identify the correct gameObject we passed
[Command]
private void CmdDoSomething (GameObject player)
{
    // Do stuff that happens only on the server here


    // Now we can send back Information
    // E.g. an int or string again passing the GameObject
    RpcDoSomething(player, "test");
}

// Usually this would be executed by ALL clients
// So we have to check if we are the player who originally called the command
// Again the NetworkIdentity makes sure we can identify the passed GameObject
[ClientRpc]
private void RpcDoSomething (GameObject player, string message)
{
    // For the special case that we are the host (server and client at the same time)
    // we maybe don't want to do something
    // since we probably already did it for ourself before while executing the [Command]
    if(isServer) return;

    // If we are not the one who invoked the command we do nothing
    if(player != gameObject) return;

    // I like to put Debug.Log containing "this" in the end so you can click a Log
    // Entry and see exactly where it came from
    Debug.Log("I received: " + message, this);
}

现在您应该可以从这里实现它了。