我目前正在工作的FPS射击游戏,我需要一个通用的运动控制器,既支持键盘和Xbox一控制器输入。设计此控制器的主要目的是解决我之前设计的FPS控制器中出现的两个常见问题,它们是:
下面是代码:
using UnityEngine;
using System.Collections;
/// <summary>
/// This class is responsible for controlling the players movement.
/// </summary>
[RequireComponent(typeof(CharacterController))]
public class CharacterMovementController : MonoBehaviour
{
public bool UseController;
public Vector3 JumpSpeed;
public Vector3 GravitySpeed;
public Vector2 MovementSpeed;
public Vector2 CameraRotationSpeed;
public Vector2 CameraRotationConstraints;
public CharacterController CharacterController { get; set; }
public Vector3 MovementVector { get; set; }
public float VerticalRotation { get; set; }
/// <summary>
/// Rotate the player.
/// </summary>
public void Rotate()
{
if(this.UseController)
{
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis("Xbox Look X"), 0.0f) * this.CameraRotationSpeed.x * Time.deltaTime);
this.VerticalRotation += Input.GetAxis("Xbox Look Y") * this.CameraRotationSpeed.y * Time.deltaTime;
this.VerticalRotation = Mathf.Clamp(this.VerticalRotation, this.CameraRotationConstraints.x, this.CameraRotationConstraints.y);
Camera.main.transform.eulerAngles = new Vector3(
-this.VerticalRotation,
Camera.main.transform.eulerAngles.y,
Camera.main.transform.eulerAngles.z
);
}
else
{
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis("Mouse X"), 0.0f) * this.CameraRotationSpeed.x * Time.deltaTime);
this.VerticalRotation += -Input.GetAxis("Mouse Y") * this.CameraRotationSpeed.y * Time.deltaTime;
this.VerticalRotation = Mathf.Clamp(this.VerticalRotation, this.CameraRotationConstraints.x, this.CameraRotationConstraints.y);
Camera.main.transform.eulerAngles = new Vector3(
-this.VerticalRotation,
Camera.main.transform.eulerAngles.y,
Camera.main.transform.eulerAngles.z
);
}
}
/// <summary>
/// Move the player.
/// </summary>
public void Move()
{
if(this.UseController)
{
this.MovementVector += Vector3.forward * Input.GetAxis("Xbox Forward / Backward") * this.MovementSpeed.y;
this.MovementVector += Vector3.right * Input.GetAxis("Xbox Left / Right") * this.MovementSpeed.x;
this.MovementVector = this.transform.rotation * this.MovementVector;
}
else
{
bool keyboardMovingForwardBackward = false;
bool keyboardMovingLeftRight = false;
if(Input.GetButton("Keyboard Forward"))
{
this.MovementVector -= this.transform.forward * this.MovementSpeed.y;
keyboardMovingForwardBackward = true;
}
else if(Input.GetButton("Keyboard Backward"))
{
this.MovementVector += this.transform.forward * this.MovementSpeed.y;
keyboardMovingForwardBackward = true;
}
if(Input.GetButton("Keyboard Left"))
{
this.MovementVector -= this.transform.right * this.MovementSpeed.x;
keyboardMovingLeftRight = true;
}
else if(Input.GetButton("Keyboard Right"))
{
this.MovementVector += this.transform.right * this.MovementSpeed.x;
keyboardMovingLeftRight = true;
}
if(keyboardMovingForwardBackward && keyboardMovingLeftRight)
{
this.MovementVector = new Vector3(
this.MovementVector.x * (1.0f / Mathf.Sqrt(2.0f)),
this.MovementVector.y,
this.MovementVector.z * (1.0f / Mathf.Sqrt(2.0f))
);
}
}
if(!this.CharacterController.isGrounded)
{
this.MovementVector += this.GravitySpeed * Time.deltaTime;
}
else
{
this.MovementVector = new Vector3(this.MovementVector.x, 0.0f, this.MovementVector.z);
}
if(Input.GetButton("Xbox A") && this.CharacterController.isGrounded)
{
this.MovementVector += this.JumpSpeed;
}
RaycastHit upperGroundedRaycastHit;
if(Physics.Raycast(this.transform.position, this.transform.up, out upperGroundedRaycastHit, (this.CharacterController.height / 2.0f) + 0.1f))
{
this.MovementVector = new Vector3(this.MovementVector.x, this.GravitySpeed.y, this.MovementVector.z);
}
this.CharacterController.Move(this.MovementVector * Time.deltaTime);
this.MovementVector = new Vector3(0.0f, this.MovementVector.y, 0.0f);
}
/// <summary>
/// Update is called once per frame.
/// </summary>
public void Update()
{
this.Rotate();
this.Move();
}
/// <summary>
/// Start is called once.
/// </summary>
public void Start()
{
this.CharacterController = this.GetComponent<CharacterController>();
}
}还有什么可以改进的吗?是否有任何潜在的陷阱或问题可以发生?
发布于 2017-05-15 15:05:02
在该方法中,if分支之间唯一的区别是获取X和Y的位置。将这些代码放到分支中就足够了,因此您可以删除一些重复的代码,但是只需将需要的string's分配给以下两个变量就更好了
var xKey = "Mouse X";
var yKey = "Mouse Y";
if(this.UseController)
{
xKey = "Xbox Look X";
yKey = "Xbox Look Y";
}
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis(xKey), 0.0f) * this.CameraRotationSpeed.x * Time.deltaTime);
this.VerticalRotation += Input.GetAxis(yKey) * this.CameraRotationSpeed.y * Time.deltaTime;
this.VerticalRotation = Mathf.Clamp(this.VerticalRotation, this.CameraRotationConstraints.x, this.CameraRotationConstraints.y);
Camera.main.transform.eulerAngles = new Vector3(
-this.VerticalRotation,
Camera.main.transform.eulerAngles.y,
Camera.main.transform.eulerAngles.z
);https://codereview.stackexchange.com/questions/163397
复制相似问题