UNet播放器控制器问题

时间:2016-03-10 03:29:29

标签: unity3d unity3d-5 unity3d-unet

我有一个应该在UNET上工作的玩家控制器。我不能理解某些东西,因为任何加入游戏的远程玩家都无法控制他们的角色。

托管本地玩家可以很好地控制他/她的角色。

基本上我认为的方式是有效的,在Update本地玩家可以按键。这些按键将Command发送到设置了同步bool的服务器。

FixedUpdate中,服务器根据设置的bool移动Rigidbody。在播放器对象上,我有一个NetworkTransform,因此服务器所做的任何移动都应该发送回客户端。

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

[RequireComponent(typeof(NetworkIdentity))]
public class PlayerController : NetworkBehaviour {
    public GameObject NormalBullet;

    public Vector3 size = new Vector3(0.25f, 0.25f, 0.25f);
    private float speed = 8;
    private float angularSpeed = 35;
    private float jumpForce = 10;

    private Rigidbody _rigidbody;
    private Map _map;
    private NHNetworkedPool _pool;

    private bool _active = false;
    private Vector3 _lastPosition;

    [SyncVar]
    private bool _moveForward;
    [SyncVar]
    private bool _moveBackward;
    [SyncVar]
    private bool _turnLeft;
    [SyncVar]
    private bool _turnRight;
    [SyncVar]
    private bool _jump;
    [SyncVar]
    private bool _isgrounded;
    [SyncVar]
    private bool _isFireing;

    void Awake () {
        Messenger.AddListener ("MAP_LOADED", OnMapLoaded);

        _rigidbody = gameObject.GetComponent<Rigidbody> ();
        _map = GameObject.Find ("Map").GetComponent<Map> ();

        Physics.IgnoreLayerCollision(LayerMask.NameToLayer("Players"), LayerMask.NameToLayer("Players"), true);
    }

    override public void OnStartClient () {
        _rigidbody.position = new Vector3 (-100, -100, -100);

        if (NetworkServer.active) {
            _pool = FindObjectOfType<NHNetworkedPool> ();
        }
    }

    /// <summary>
    /// Once the board is built, hookup the camera if this is the local player
    /// and set the player as active.
    /// </summary>
    void OnMapLoaded () {
        if (isLocalPlayer) {
            // Hook up the camera
            PlayerCamera cam = Camera.main.GetComponent<PlayerCamera>();
            cam.target = transform;

            // Move the player to the it's spawn location
            CmdSpawn();
        }

        // Set the player as active
        _active = true;
    }

    /// <summary>
    /// Only and active local player should be able to
    /// issue commands for the player
    /// </summary>
    void Update () {
        if (!isLocalPlayer || !_active) {
            return;
        }

        if (Input.GetKeyDown ("up")) {
            CmdSetMoveForward (true);
        }
        if (Input.GetKeyUp ("up")) {
            CmdSetMoveForward (false);
        }
        if (Input.GetKeyDown ("down")) {
            CmdSetMoveBackward (true);
        }
        if (Input.GetKeyUp ("down")) {
            CmdSetMoveBackward (false);
        }
        if (Input.GetKeyDown ("left")) {
            CmdSetTurnLeft (true);
        }
        if (Input.GetKeyUp ("left")) {
            CmdSetTurnLeft (false);
        }
        if (Input.GetKeyDown ("right")) {
            CmdSetTurnRight (true);
        }
        if (Input.GetKeyUp ("right")) {
            CmdSetTurnRight (false);
        }
        if (Input.GetKeyDown (KeyCode.Space)) {
            CmdSetJump (true);
        }
        if (Input.GetKeyUp (KeyCode.Space)) {
            CmdSetJump (false);
        }
        if (Input.GetKeyDown (KeyCode.LeftShift)) {
            CmdSetShooting(true);
        }
        if (Input.GetKeyUp (KeyCode.LeftShift)) {
            CmdSetShooting(false);
        }
    }

    /// <summary>
    /// Only the server should update the player's location
    /// the transform is synced to the clients
    /// </summary>
    void FixedUpdate () {
        if (!isServer) {
            return;
        }

        if (_moveForward) {
            float moveAmount = speed * Time.deltaTime;
            _rigidbody.MovePosition(_rigidbody.position + _rigidbody.transform.forward * moveAmount);
        }

        if (_moveBackward) {
            float moveAmount = (-speed * 0.6f) * Time.deltaTime;
            _rigidbody.MovePosition(_rigidbody.position + _rigidbody.transform.forward * moveAmount);
        }

        if (_turnLeft) {
            Quaternion rotateAmount = Quaternion.Euler(new Vector3(0f, -angularSpeed, 0f) * Time.deltaTime);
            _rigidbody.MoveRotation(_rigidbody.rotation * rotateAmount);
        }

        if (_turnRight) {
            Quaternion rotateAmount = Quaternion.Euler(new Vector3(0f, angularSpeed, 0f) * Time.deltaTime);
            _rigidbody.MoveRotation(_rigidbody.rotation * rotateAmount);
        }

        if (_jump && _isgrounded) {
            _rigidbody.AddForce(Vector3.up * 250);
        }
    }

    void OnCollisionStay (Collision collision) {
        if(collision.gameObject.tag.ToUpper() == "GROUND") {
            _isgrounded = true;
        }
    }

    void OnCollisionExit (Collision collision) {
        if(collision.gameObject.tag.ToUpper() == "GROUND") {
            _isgrounded = false;
        }
    }

    /// <summary>
    /// Client -> Server
    /// Move the player to a spawn location
    /// </summary>
    void CmdSpawn() {
        _rigidbody.position = _map.GetPlayerSpawn();
        _rigidbody.velocity = Vector3.zero;
    }

    /// <summary>
    /// Client -> Server
    /// Set the forward move of the player on/off
    /// </summary>
    [Command]
    void CmdSetMoveForward (bool active) {
        _moveForward = active;
    }

    /// <summary>
    /// Client -> Server
    /// Set the backward of the player on/off
    /// </summary>
    [Command]
    void CmdSetMoveBackward (bool active) {
        _moveBackward = active;
    }

    /// <summary>
    /// Client -> Server
    /// Set the left turn of the player on/off
    /// </summary>
    [Command]
    void CmdSetTurnLeft (bool active) {
        _turnLeft = active;
    }

    /// <summary>
    /// Client -> Server
    /// Set the right turn of the player on/off
    /// </summary>
    [Command]
    void CmdSetTurnRight (bool active) {
        _turnRight = active;
    }

    /// <summary>
    /// Client -> Server
    /// Set the jumpping of the player on/off
    /// </summary>
    [Command]
    void CmdSetJump (bool active) {
        _jump = active;
    }

    /// <summary>
    /// Client -> Server
    /// Set shooting weapon on/off
    /// </summary>
    [Command]
    void CmdSetShooting (bool active) {
        _isFireing = true;
    }
}

1 个答案:

答案 0 :(得分:0)

您不应该在服务器上进行移动。重写它以便在客户端上计算和执行移动。 然后将NetworkTransform组件添加到播放器,它应该可以工作。

只有Fire方法必须是Command。但是因为我不知道_isFireing = true时我实际上发生了什么,我无法告诉你应该写什么;)

编辑:如果您没有,还需要播放器上的NetworkIdentity组件