我有一个可以在 UNET 上工作的播放器控制器。我一定不明白,因为任何远程玩家加入游戏都无法控制他们的角色。
托管本地玩家可以很好地控制他/她的角色。
基本上我认为这是可行的方式是在Update
本地播放器中可以按键。这些按键Command
向设置同步布尔值的服务器发出 s。
在FixedUpdate
服务器中,根据设置的布尔值移动刚体。在播放器对象上,我有一个 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;
}
}