Unity——第一人称控制器的实现

Unity——第一人称控制器的实现

一、功能描述

在一个场景中实现人物的前后左右移动和跳跃功能;其中前后左右移动通过W、A、S、D方向键实现,跳跃功能通过空格键实现,并且考虑到重力作用,来调节跳跃功能。

二、功能实现

2.1创建一个Character Controller

  1. 先创建一个新的GameObject,并重命名为Player

  2. 并为其添加一个Character Controller组件

  3. 在Player下,创建一个Cylinder物体(代替人物),并将场景中的主相机(Main Camera)放于Player下

Unity——第一人称控制器的实现

Unity——第一人称控制器的实现

将Cylinder物体中的Capsule Collider组件删除,解决碰撞问题。

Unity——第一人称控制器的实现

2.2实现相机(第一人称视角的旋转,左右)的移动

相机的视角通过鼠标mouse进行控制

  1. Assets文件夹下创建Scripts文件夹,用来保存代码文件;并在Scripts文件夹下创建CameraMove的C#文件并打开;

  2. 直接放代码,相关解释在代码里:

    //所有代码如下:
    public class CameraMove : MonoBehaviour
    {
        //定义鼠标移动速度
        public float mouseSpeed = 100f;
        
        public Transform playerBody;
    ​
        float xRotation = 0f;
        // Start is called before the first frame update
        void Start()
        {
            //将鼠标隐藏
            Cursor.lockState = CursorLockMode.Locked;
        }
    ​
        // Update is called once per frame
        void Update()
        {
            float mouseX = Input.GetAxisRaw("Mouse X") * mouseSpeed * Time.deltaTime;
            float mouseY = Input.GetAxisRaw("Mouse Y") * mouseSpeed * Time.deltaTime;
            //这里的Mouse X和Mouse Y是鼠标所控制的X,Y,这里在前面新定义了一个鼠标移动的速度mouseSpeed,用来控制鼠标移动速度,Time.deltaTime是为了解决帧率问题
            xRotation -= mouseY;//不能为+=,会让鼠标控制的摄像机方向颠倒
            xRotation = Mathf.Clamp(xRotation, -90f, 90f);//将摄像机上下可调节范围控制在-90到90度之间
    ​
            transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
            playerBody.Rotate(Vector3.up * mouseX);//绕着y轴旋转
    ​
        }
    }

     

     
  3. 注意:摄像机和物体Cylinder的y轴差距不要很大,很大的话会出现问题,尽量重合。

  4. 保存文件,并将Camera Move文件作为组件添加给主摄像机,并把Player拖入到Player Body上,如图:Unity——第一人称控制器的实现

     

     

     

     

  5. 运行并调试,摄像机可以根据鼠标运动而改变视野角度。

2.3人物左右移动和跳跃

同上,在Assets文件夹下创建Scripts文件夹,用来保存代码文件;并在Scripts文件夹下创建Player Movement的C#文件并打开

直接上代码:

public class PlayerMovement : MonoBehaviour
{
    public CharacterController controller;
    
    //这里是人物行走时的速度
    public float walkSpeed = 5f;
    
    //人物跑动时的速度
    public float runSpeed = 6f;
    
    //重力
    public float gravity = -9.81f;
    
    //三维向量组x,y,z
    Vector3 velocity;
​
    public Transform groundCheck;
    
    //检测人物是否与地面碰撞的半径
    public float groundDistance = 0.4f;
​
    public LayerMask groundMask;
    
    //人物是否在地面上
    bool isGrounded;
​
    public float jumpHeight = 2f;
    
    // Start is called before the first frame update
    void Start()
    {
        
    }
​
    // Update is called once per frame
    void Update()
    {
        //物理检测,是否在地面上
        isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
        
        if(isGrounded && velocity.y < 0)
        {
            velocity.y = -2f;//正好在地面上,可以为0f,但-2f更好一些
        }
        
        //跳跃  这里默认空格键是跳跃按键
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
        }
        
        //这里在unity中默认“W”为向前,“D”向右,即通过控制x轴方向来控制物体在水平方向的运动;控制z轴,来控制物体前后移动
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
​
        Vector3 move = transform.right * x + transform.forward * z;
        
        //将控制的方向与速度相乘,就能实现物体的运动,同样,这里的Time.deltaTime也是解决帧率问题
        controller.Move(move * walkSpeed * Time.deltaTime);
        
        //三维向量组中的y   y=1/2*g*t*t
        //重力在每一帧的变化
        velocity.y += gravity * Time.deltaTime;
​
        controller.Move(velocity * Time.deltaTime);
        
        //当同时按下键盘上的“W”和“Q”键,进入跑步
        if(Input.GetKey(KeyCode.W)&& Input.GetKey(KeyCode.Q))
        {
            controller.Move(move * runSpeed * Time.deltaTime);
        }
        
    }
}

保存文件。

  1. 添加一个新的GameObject,重命名为GroundCheck;并调整其位置于物体最下方。

  2. 为Player添加Player Movement组件,如图将各个变量加入进去

Unity——第一人称控制器的实现

注意:如果没有Ground这个选项,可以在最上方的Layers中新建一个,并将点击场景修改图层为Ground。

Unity——第一人称控制器的实现

Unity——第一人称控制器的实现

到此,基本功能就可以实现。

本文为博主自己根据b站上的视频学习总结,如有疑问,可以参考b站原视频:

https://www.bilibili.com/video/BV1nE411b7X8?t=1407



1 float mouseX = Input.GetAxisRaw("Mouse X") * mouseSpeed * Time.deltaTime;
2 ​
3 float mouseY = Input.GetAxisRaw("Mouse Y") * mouseSpeed * Time.deltaTime;
4 //这里的Mouse X和Mouse Y是鼠标所控制的X,Y,这里在前面新定义了一个鼠标移动的速度mouseSpeed,用来控制鼠标移动速度,Time.deltaTime是为了解决帧率问题
上一篇:App轮播图


下一篇:R语言中strptime返回值永远为NA的问题