[Unity3D]最简单的最详细的第一人称角色控制器

[Unity3D]最简单最详细的第一人称角色控制器

自学Unity3D有一段时间了,一直想弄一个第一人称角色控制器,网上还是有很多教程和资料,但感觉有很多教程和资料理解起来比较复杂,在这里我结合网上所学的知识自己写了一个比较容易理解的Unity3D第一人称控制器脚本。

首先来看一下完成后的效果
在这里插入图片描述
接下来逐步讲解如何实现这个功能

  1. 首先我们打开Unity创建一个Unity3D工程
    在这里插入图片描述
    2.在Hierarchy面板空白处单击右键,点击Create Empty创建一个空对象,点击创建好的空对象,右键单击rename重新命名为Player
    在这里插入图片描述
    3.在Hierarchy面板下单击右键,选择3D Object—Terrain创建一个地形,再单击右键,选择3D Object—Capsule创建一个胶囊体充当角色,将其拖拽至Player下使其成为Player的一个子对象在这里插入图片描述
    此时场景如图所示
    在这里插入图片描述
    再右键单击Hierarchy面板,点击3D Object—cube创建一个正方体,适当调整其Transform数值,调整其大小和位置,使其位于胶囊体的正前方,以此辨别方向
    在这里插入图片描述
    在这里插入图片描述
    调整完成后一个人物的基本模型就制作好了,如图所示
    在这里插入图片描述
    4.在Hierarchy面板下单击Player,在其Inspector面板下点击Add Component添加一个Character Controller组件,添加成功后会出现绿色的网格将胶囊体包围,如下图所示,调整Character Controller上的数值可以改变其网格的大小(如果你的网格不是恰好把你的这个人物包围好的话)在这里插入图片描述
    5.在Hierarchy面板下单击Player,在其Inspector面板下点击Add Component添加一脚本,命名为PlayerMove在这里插入图片描述
    PlayerMove创建好后双击红色圈圈里面的脚本,进入Visual Studio 中进行编写脚本
    在这里插入图片描述
    6.PlayerMove脚本的编辑

    //定义一个移动速度MoveSpeed 其类型为public类型
    public float MoveSpeed;
    //用户在PlayerMove脚本界面可以对其进行调整
    //(用public定义,脚本外可以修改,并以脚本外修改的为主)
    //(如果是private类型则只能在脚本修改)
    
    //定义两个私有类型的浮点型数据horizontal和vertical来记录A、D键和
    //W、S键的数据,也可以理解为记录水平轴和竖直轴的数据,即X轴和Y轴 
    private float horizontal;
    private float vertical;
    
    //定义一个重力gravity 
    private float gravity = 9.8f;
    //定义一个起跳速度
    public float JumpSpeed = 15f;
    //定义一个公有类型的CharacterController,将其命名为PlayerController
    //用于实例化对象
    public CharacterController PlayerController;
    
    //定义一个Vector3
    //Vector3向量既可以用来表示位置,也可以用来表示方向
    //在立体三维坐标系中,分别取与x轴、y轴,z轴方向相同的3个单位向量i,j, k作为一组基底。
    //若a为该坐标系内的任意向量,以坐标原点O为起点作向量OP=a。由空间基本定理知,有且只有一组实数(x,y, z)
    //使得 a=向量OP=xi+yj+zk,因此把实数对(x,y, z)叫做向量a的坐标
    //记作a=(x,y, z)。这就是向量a的坐标表示。其中(x,y, z),也就是点P的坐标。向量OP称为点P的位置向量。
    Vector3 Player_Move;
    //如果还是不理解的话可以去CSDN上详细了解,这里就不做过多说明了

    //放在Updata里面每一帧都会执行,导致不能够保存前一时刻的值   
    void Update()
    {
    
    
        //判断PlayerController是否在地面上,如果不是在地面上就不能够前后左右移动,也不能够起跳
        if(PlayerController.isGrounded)
        {
    
    
        //Input.GetAxis("Horizontal")为获取X(横轴)轴方向的值给horizontal
            horizontal = Input.GetAxis("Horizontal");
        //Input.GetAxis("Vertical")为获取Z(纵轴)轴方向的值给Vertical
            vertical = Input.GetAxis("Vertical");
            
        //transform为本物体所在位置,forward是向前的一个分量
        //transform.forward * vertical为物体向前的方向乘获取的Z轴的值,即物体向前移动的量,如果vertical为负数,则物体后退
        //transform.right * horizontal为物体向右的方向乘获取的X轴的值,即物体向右移动的量,如果horizon为负数,则物体向左
        //两者相加后最后面乘移动数度,赋值给Vector3类型的Player_Move即为物体实际运动的方向           
            Player_Move = (transform.forward * vertical + transform.right * horizontal) * MoveSpeed;

            //判断玩家是否按下空格键
            if (Input.GetAxis("Jump")==1)
            {
    
    
            //按下空格键,给其竖直方向添加一个向上的数度,使其跳起
            //Player_Move.y相当于Player_Move下的Vector3(0,1,0)
                Player_Move.y = Player_Move.y + JumpSpeed;
            }
        }
        
        //模拟重力下降的效果,让向上的量减去重力下降的量
        //变量deltaTime表示为unity本地变量,作为Time类中的数据在各帧中被更新,在各帧中,该变量显示了距上一帧所经历的时间值(以秒计算)。 
        //这个变量的优点: 使用这个函数他会与你的游戏帧速率无关 放在Update()函数中的代码是以帧来执行的
        //我们需要将移动的物体乘以秒来执行,而乘以deltaTime其就可以实现 
        //例如:想让一个游戏对象向前以每秒10m移动的话 用你的速度10乘Time.deltaTime  他表示每秒移动的距离为10m而不是每帧10m      
        Player_Move.y = Player_Move.y - gravity * Time.deltaTime;
        
        //PlayerController下的.Move为实现物体运动的函数
        //Move()括号内放入一个Vector3类型的量,本例中为Player_Move
        PlayerController.Move(Player_Move*Time.deltaTime);
    }

到这里我们Ctrl+S保存,回到Unity中,将CharacterController拖拽至PlayerMove脚本下的PlayerController中在这里插入图片描述

7.单击运行按钮,在键盘上点击W、A、S、D就可以移动啦

在这里插入图片描述在这里插入图片描述8.但是现在我们还不能够控制角色移动的方向,接下来我们要为Camera写一个脚本来控制人物移动的方向,在这之前,我们要移动摄像机,调整摄像机Mian Camera的Transform数值,使其位于人物的头部,如图所示,并将Main Camera移动到Player下使其成为Player的一个子对象。在这里插入图片描述在这里插入图片描述
9.单击Camera,在其Inspector面板下单击Add Component,输入CameraControlle来New Script一个摄像机脚本,双击进去编辑在这里插入图片描述在这里插入图片描述
接下来编辑CameraController脚本,使其能够让玩家用鼠标控制方向

    //创建一个Transform类型的量CameraRotation用来保存实现相机旋转
    public Transform CameraRotation;

   //定义两个私有类型的量Mouse_X,Mouse_Y分别接收鼠标向各个方向滑动的值
    private float Mouse_X;
    private float Mouse_Y;

   //鼠标灵敏度
    public float MouseSensitivity;
   
   //定义一个浮点类型的量,记录绕X轴旋转的角度
    public float xRotation;
    
   //放在Updata里面每一帧都会执行,导致不能够保存前一时刻的值 
    void Update()
    {
    
    
        //获取鼠标左右移动的量乘上灵敏度的值
        Mouse_X = Input.GetAxis("Mouse X") * MouseSensitivity * Time.deltaTime;
        //获取鼠标上下移动的量乘上灵敏度的值
        Mouse_Y = Input.GetAxis("Mouse Y") * MouseSensitivity * Time.deltaTime;

        xRotation = xRotation - Mouse_Y;
        //xRotation值为正时,屏幕下移,当xRotation值为负时,屏幕上移
        //当鼠标向上滑动,Mouse_Y值为正,xRotation-Mouse_Y的值为负,xRotation总的值为负,屏幕视角向上滑动
        //当鼠标向下滑动,Mouse_Y值为负,xRotation-Mouse_Y的值为正,xRotation总的值为正,屏幕视角向下滑动
        //简单来说就是要控制鼠标滑动的方向与屏幕移动的方向要相同

        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        //限制 value的值在-90f,90f之间,如果xRotation大于90f,则返回90f,如果xRotation小于-90f,则返回-90f,否者返回xRotation;

        //相机左右旋转时,是以Y轴为中心旋转的,上下旋转时,是以X轴为中心旋转的
        CameraRotation.Rotate(Vector3.up * Mouse_X);
        //Vector3.up相当于Vector3(0,1,0),CameraRotation.Rotate(Vector3.up * Mouse_X)相当于使CameraRotation对象绕y轴旋转Mouse_X个单位
        //即相机左右旋转时,是以Y轴为中心旋转的,此时Mouse_X控制着值的大小

        //相机在上下旋转移动时,相机方向不会随着移动,类似于低头和抬头,左右移动时,相机方向会随着向左向右移动,类似于向左向右看
        //所以在控制相机向左向右旋转时,要保证和父物体一起转动
        this.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
        //this.transform指这个CameraRotation的位置,localRotation指的是旋转轴
        //transform.localRotation = Quaternion.Eular(x,y,z)控制旋转的时候,按照X-Y-Z轴的旋转顺规
        //即以围绕X轴旋转x度,围绕Y轴旋转y度,围绕Z轴旋转z度
        //且绕轴旋转的坐标轴是父节点本地坐标系的坐标轴
    }

记住相机在水平方向的转动是围绕X轴来的,上下转动是围绕Y轴来的,所以Mouse_X的值控制相机上下移动,Mouse_Y的值控制相机左右移动,我怕有人不理解为什么CameraRotation.Rotate(Vector3.up * Mouse_X)中Vector3.up一个y方向的量要乘以鼠标X轴方向的量,因为是绕着Y轴转的,X值是控制其旋转大小的值…下面画了一张草图(鼠标有点问题,没画好),实在不懂就先这么写着吧,或者去其它地方搜一搜T T在这里插入图片描述接下来Ctrl+S保存,回到Unity中,将hierarchy面板下的MainCamera拖拽至MainCamera中Inspector面板下CameraController的脚本中,设置鼠标灵敏度为100在这里插入图片描述点击运行按钮,人物就可以转动了O(∩_∩)O
在这里插入图片描述

第一次写博客,有什么不对的地方还请多多指教,喜欢的话点个赞吧,后续还会更新更多有关于Unity的教程和内容哦(● ∀ ●)

更新一个新教程

[Unity3D]最简单最详细的第一人称射击教程

[Unity3D]自动寻路/智能寻路链接

猜你喜欢

转载自blog.csdn.net/Z_hongli/article/details/109782483