[Unity3D]最简单最详细的第一人称角色控制器
自学Unity3D有一段时间了,一直想弄一个第一人称角色控制器,网上还是有很多教程和资料,但感觉有很多教程和资料理解起来比较复杂,在这里我结合网上所学的知识自己写了一个比较容易理解的Unity3D第一人称控制器脚本。
首先来看一下完成后的效果
接下来逐步讲解如何实现这个功能
- 首先我们打开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的教程和内容哦(● ∀ ●)
更新一个新教程