mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7mobile wallpaper 8
1439 字
4 分钟
Unity开发日记|从零搭建角色控制系统
2026-09-20

Unity开发日记,顾名思义就是记录我学习并使用Unity开发游戏的系列。

使用Unity开发是一个考虑了很久才决定的事情,这是一个很长很长的故事…//

🍅小番茄:这里就不多说了,嘻嘻//(๑˃̵ᴗ˂̵)و

话不多说,进入正题。


🌱 人物创建#

独立去学习游戏开发,第一个令大多数人头疼的什么——建模。

🍅小番茄:啊?对齁…我都没有人物模型,那我还是先去学习建模吧…//( ´•̥̥̥ω•̥̥̥` )

诶~先别急着走,那是另一个技术了哦,战线拉太长了,只会消磨对游戏开发的热情。

我们现在应该聚焦于如何快速实现一些游戏玩法,再去琢磨其它的,游戏模型我们完全可以使用一些公开免费的资源,以下推荐几个网站:

KENNEY Low Poly风格模型,上千游戏资源免费资源且可以商用

Unity资源商店 Unity的官方资源商店,有免费也有付费,也推荐大家直接下载导入自己看到且喜欢的免费场景

🍅小番茄:哇!找到我喜欢的模型了//(≧∇≦)ノ我们快开始叭!

将人物模型导入场景当中,并把它命名为Player。

把相机绑到角色头部,这样模型移动,相机也会一块动。

角色创建

这样,一个角色就创建好了。接下来就是让他动起来了。


🌸 角色移动#

到这里我们即将要开始写代码了哦!

编程语言是C#,如果有一定的编程基础,这一块会理解的比较快。

🍅小番茄:哼哼,难道学完以后我要成为深沉的黑客了吗,这可真让人兴奋呀…#超绝气泡音#

笑)

现在选中我们的角色,为它添加CharacterController组件。

cc组件添加

在项目窗口新建一个Script文件夹,在文件夹当中创建一个C# Script文件,将其命名为PlayerController。

随后打开这个文件。

TIP

✨这里Unity会默认以Visual Studio打开;如果你想使用Rider等IDE去开发也可以。

打开后会发现里面有如下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerState : MonoBehaviour
{
//游戏启动时执行
void Start()
{
}
//游戏实时更新
void Update()
{
}
}

在顶部删掉不需要的命名空间,只保留”using UnityEngine” 首先我们需要先定义几个以下字段:

using UnityEngine;
public class PlayerState : MonoBehaviour
{
public float speed = 1f; //移动速度
private CharacterController _character; //用于获取刚刚添加的CharacterController组件
private float verticalMove; //获取按下前后移动键后返回的值(-1~1)
private float horizontalMove; //获取按下左右移动键后返回的值(-1~1)
private Vector3 dir; //用于存储移动向量
//游戏启动时执行
void Start()
{
}
//游戏实时更新
void Update()
{
}
}
TIP

声明为public的字段可以直接在Unity Editor中设置值

现在需要我们在游戏启动时获取CharacterController组件并赋值给”_character”字段。

并使用Input.GetAsix()方法获取游戏过程中玩家按下前后左右移动键这个行为,并赋值给”verticalMove”和”horizontalMove”字段。

并把值乘以角色前后方向以及左右方向的单位向量之和赋给移动向量”dir”。

using UnityEngine;
public class PlayerState : MonoBehaviour
{
public float speed; //移动速度
private CharacterController _character; //用于获取刚刚添加的CharacterController组件
private float verticalMove; //获取按下前后移动键后返回的值(-1~1)
private float horizontalMove; //获取按下左右移动键后返回的值(-1~1)
private Vector3 dir; //用于存储移动向量
//游戏启动时执行
void Start()
{
_character = GetComponent<CharacterController>(); //获取CharacterController组件
}
//游戏实时更新
void Update()
{
verticalMove = Input.GetAsix("Vertical");
horizontalMove = Input.GetAsix("Horizontal");
dir = transform.forward * verticalMove + transform.right * horizontalMove;
dir.Normalize(); //这个.Normalize()方法是使向量标准化,避免斜着移动会更快。初学者直接用就好
}
}
IMPORTANT

如果觉得移动有延迟感可以将.GetAsix()换为.GetAsixRaw(),这样是松开急停的

或者在Unity Editor中,打开Edit -> Project Settings -> Input Manager

分别展开Axes -> Horizontal 和 Vertical

把 Gravity(重力) 从默认的 3 调大到 10~30 之间

数值越大,松开按键后输入归零越快,延迟越短

接下来,就是让它动起来了!

调用CharacterController的Move()方法,实现角色移动。

当然,如果直接移动向量”dir * speed”是不行的,这样游戏的帧率会影响移动的速度,所以我们要乘一个Time.deltaTime,

这是上一帧到这一帧的时间,这样就可以避免帧率不同,移动速度不同的现象了。

using UnityEngine;
public class PlayerState : MonoBehaviour
{
public float speed = 1f; //移动速度
private CharacterController _character; //用于获取刚刚添加的CharacterController组件
private float verticalMove; //获取按下前后移动键后返回的值(-1~1)
private float horizontalMove; //获取按下左右移动键后返回的值(-1~1)
private Vector3 dir; //用于存储移动向量
//游戏启动时执行
void Start()
{
_character = GetComponent<CharacterController>(); //获取CharacterController组件
}
//游戏实时更新
void Update()
{
verticalMove = Input.GetAsix("Vertical");
horizontalMove = Input.GetAsix("Horizontal");
dir = transform.forward * verticalMove + transform.right * horizontalMove;
dir.Normalize(); //这个.Normalize()方法是使向量标准化,避免斜着移动会更快。初学者直接用就好
_character.Move(dir * speed * Time.deltaTime); //角色移动!
}
}

保存!接下来就是把脚本作为组件挂载到角色上,开启游戏就可以试试WASD或上下左右移动了。

恭喜完成了角色的一个基础操作,

奖励一下自己,去喝点什么叭~

🍅小番茄:好耶!//(๑˃̵ᴗ˂̵)و


📸 视角移动#

那么接下来实现视角的移动,完善角色的基本操作。

同样,定义一下字段以下字段。

并且用Input.GetAxis()获取鼠标移动。

using UnityEngine;
public class PlayerState : MonoBehaviour
{
public float mouseSensitivity = 3f; //鼠标灵敏度
private float mouseX; //鼠标水平移动
private float mouseY; //鼠标垂直移动
public float speed = 1f; //移动速度
private CharacterController _character; //用于获取刚刚添加的CharacterController组件
private float verticalMove; //获取按下前后移动键后返回的值(-1~1)
private float horizontalMove; //获取按下左右移动键后返回的值(-1~1)
private Vector3 dir; //用于存储移动向量
//游戏启动时执行
void Start()
{
_character = GetComponent<CharacterController>(); //获取CharacterController组件
}
//游戏实时更新
void Update()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
verticalMove = Input.GetAsix("Vertical");
horizontalMove = Input.GetAsix("Horizontal");
dir = transform.forward * verticalMove + transform.right * horizontalMove;
dir.Normalize();
_character.Move(dir * speed * Time.deltaTime); //角色移动!
}
}

接下来实现视角移动,游戏对象可以通过.transform.Rotate()方法进行旋转。

但是思考一下,鼠标水平位移时,我们整个人物可以一起左右转。

但是鼠标垂直时就不行,整个人转起来,人就搁那翻跟斗了。

所以我们还需要单独操控相机上下转,我们就要获取相机这个GameObject了。

using UnityEngine;
public class PlayerState : MonoBehaviour
{
public float mouseSensitivity = 3f; //鼠标灵敏度
private float mouseX; //鼠标水平移动
private float mouseY; //鼠标垂直移动
private GameObject _playerCamera; //角色摄像机
public float speed = 1f; //移动速度
private CharacterController _character; //用于获取刚刚添加的CharacterController组件
private float verticalMove; //获取按下前后移动键后返回的值(-1~1)
private float horizontalMove; //获取按下左右移动键后返回的值(-1~1)
private Vector3 dir; //用于存储移动向量
//游戏启动时执行
void Start()
{
_character = GetComponent<CharacterController>(); //获取CharacterController组件
}
//游戏实时更新
void Update()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
//视角移动的实现
_character.transform.Rotate(Vector3.up * mouseX);
_playerCamera.transform.Rotate(Vector3.left * mouseY);
verticalMove = Input.GetAsix("Vertical");
horizontalMove = Input.GetAsix("Horizontal");
dir = transform.forward * verticalMove + transform.right * horizontalMove;
dir.Normalize();
_character.Move(dir * speed * Time.deltaTime); //角色移动!
}
}

保存!然后回到Unity Editor当中。将摄像机拖到脚本的Player Camera处,然后启动游戏。

给对象赋值

运行游戏后我们会发现视角可以移动了!

🍅小番茄:啊…?可是为什么视角可以360°转呀…//(。•́︿•̀。)

是的,我们现在的视角移动是有问题的,因为我们还没有限制视角垂直移动的值。

我们现在是直接通过直接旋转那么多值来实现的,所以我们要定义一个字段xRotation去记录目前的俯仰角,然后通过直接赋值并限制俯仰角大小,这样就可以了。

接下来我们使用Mathf.Clamp()方法来限制俯仰角大小。

using UnityEngine;
public class PlayerState : MonoBehaviour
{
private float xRotation; //俯仰角大小
public float mouseSensitivity = 3f; //鼠标灵敏度
private float mouseX; //鼠标水平移动
private float mouseY; //鼠标垂直移动
private GameObject _playerCamera; //角色摄像机
public float speed = 1f; //移动速度
private CharacterController _character; //用于获取刚刚添加的CharacterController组件
private float verticalMove; //获取按下前后移动键后返回的值(-1~1)
private float horizontalMove; //获取按下左右移动键后返回的值(-1~1)
private Vector3 dir; //用于存储移动向量
//游戏启动时执行
void Start()
{
_character = GetComponent<CharacterController>(); //获取CharacterController组件
}
//游戏实时更新
void Update()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
xRotation -= mouseY; //存储俯仰角信息
xRotation = Mathf.Clamp(xRotation, 0f, 0f); //限定俯仰角大小
_character.transform.Rotate(Vector3.up * mouseX);
_playerCamera.transform.localRotation = Quaternion.Euler(xRotation, 0, 0); //直接设置俯仰角大小
verticalMove = Input.GetAsix("Vertical");
horizontalMove = Input.GetAsix("Horizontal");
dir = transform.forward * verticalMove + transform.right * horizontalMove;
dir.Normalize();
_character.Move(dir * speed * Time.deltaTime); //角色移动!
}
}

到这里,视角移动就完事了。

让我们进入下一个内容吧。


👟 重力以及跳跃#

🚧建设中…

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Unity开发日记|从零搭建角色控制系统
https://blog.ke7chup.me/posts/unity-1/
作者
Ke7chup
发布于
2026-09-20
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录