首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有Xbox One控制器支持的通用FPS运动控制器

带有Xbox One控制器支持的通用FPS运动控制器
EN

Code Review用户
提问于 2017-05-15 14:45:36
回答 1查看 80关注 0票数 3

我目前正在工作的FPS射击游戏,我需要一个通用的运动控制器,既支持键盘和Xbox一控制器输入。设计此控制器的主要目的是解决我之前设计的FPS控制器中出现的两个常见问题,它们是:

  • 当使用键盘设置时,对角线移动(扫射)会使玩家移动速度增加一倍。
  • 跳入一个低天花板的环境中,导致玩家“坚持”到所说的天花板上。

下面是代码:

代码语言:javascript
复制
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>();
    }
}

还有什么可以改进的吗?是否有任何潜在的陷阱或问题可以发生?

EN

回答 1

Code Review用户

回答已采纳

发布于 2017-05-15 15:05:02

旋转()

在该方法中,if分支之间唯一的区别是获取XY的位置。将这些代码放到分支中就足够了,因此您可以删除一些重复的代码,但是只需将需要的string's分配给以下两个变量就更好了

代码语言:javascript
复制
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
    );
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/163397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档