1、角色控制基础:理解Pawn与Character的区别,创建第一个可控制的角色蓝图
好,咱们正式开始角色控制系统的第一课。
说实话,很多新手甚至一些有经验的开发者,对 Pawn 和 Character 的理解都停留在「差不多」的层面。但在我多年的项目经验里,这两者的选择直接决定了后续的扩展成本和性能表现。今天咱们就把这个基础打扎实。
1.1 Pawn 与 Character:到底差在哪?
先问大家一个问题:你做一个游戏角色,为什么 Unreal 要给你两个选择?
其实说白了,Pawn 是基础,Character 是带人形骨架的升级版。
| 特性 | Pawn | Character |
|---|---|---|
| 继承关系 | 继承自 Actor | 继承自 Pawn |
| 默认组件 | 无 | CharacterMovementComponent + CapsuleComponent |
| 适用场景 | 载具、炮台、AI 简单体 | 人形角色、NPC、玩家 |
| 移动逻辑 | 需手动实现 | 内置行走、跳跃、蹲伏 |
| 网络同步 | 基础支持 | 优化过的角色同步 |
我在项目中遇到过这样一个坑:团队刚开始做一款载具射击游戏,有人直接用 Character 做坦克,结果发现坦克根本不需要跳跃和蹲伏,反而因为 CharacterMovementComponent 的额外计算拖了性能。后来全部改成 Pawn,帧率直接提升了 15%。
核心原则:如果你的角色需要「走路、跑步、跳跃、蹲伏」这些人类基本动作,用 Character。否则,用 Pawn 更轻量、更可控。
1.2 创建第一个可控制的角色蓝图
好,理论说完了,咱们直接动手。我习惯从空白项目开始,这样你能看到每一步的依赖关系。
步骤一:创建 Character 蓝图类
- 在 Content Browser 右键 → Blueprint Class
- 父类选择
Character - 命名为
BP_MyCharacter
打开蓝图后,你会看到默认组件里已经有一个 CapsuleComponent(碰撞体)和 CharacterMovementComponent(移动组件)。嗯,这里要注意:CapsuleComponent 的半高和半径决定了角色的通过性。我曾经见过一个项目,角色胶囊半径设了 50,结果门框只有 60 宽,角色卡门卡到怀疑人生。
我的建议:胶囊半径默认 42,半高默认 96。除非你的游戏有特殊比例,否则先别动这两个值。
步骤二:添加网格体与动画
为了让角色「看得见」,我们需要一个 Skeletal Mesh。我个人习惯用 Unreal 自带的 SK_Mannequin,因为它骨骼标准,动画兼容性好。
// 在蓝图事件图表中,BeginPlay 时设置:
// 1. 获取 SkeletalMeshComponent
// 2. 设置 Skeletal Mesh 为 SK_Mannequin
// 3. 设置 Anim Blueprint Class(后续章节会详细讲)
你想想看,如果没有动画蓝图,角色就是一个僵硬的模型。所以这一步虽然简单,但千万别跳过。
步骤三:绑定输入
这是让角色「动起来」的关键。我们需要在 Project Settings → Input 中先定义好 Action Mappings 和 Axis Mappings。
| 映射名称 | 按键 | 类型 |
|---|---|---|
| MoveForward | W / S | Axis |
| MoveRight | A / D | Axis |
| Jump | Space Bar | Action |
然后在蓝图的 SetupPlayerInputComponent 事件中绑定这些映射:
// 伪代码逻辑
BindAxis("MoveForward", 自己, 函数名 "MoveForward")
BindAxis("MoveRight", 自己, 函数名 "MoveRight")
BindAction("Jump", IE_Pressed, 自己, 函数名 "Jump")
避坑指南:我曾经犯过一个低级错误——在 BeginPlay 里绑定输入,结果角色在客户端永远无法响应按键。记住,输入绑定必须在 SetupPlayerInputComponent 中完成,这是 Unreal 的输入处理生命周期决定的。
步骤四:实现移动逻辑
在角色蓝图中添加两个自定义事件:MoveForward 和 MoveRight。逻辑其实很简单:
// MoveForward 实现
输入值 = GetAxisValue("MoveForward")
方向 = GetActorForwardVector()
AddMovementInput(方向, 输入值)
// MoveRight 实现
输入值 = GetAxisValue("MoveRight")
方向 = GetActorRightVector()
AddMovementInput(方向, 输入值)
为什么用 AddMovementInput 而不是直接设置位置?因为 CharacterMovementComponent 会处理物理、碰撞、斜坡等复杂情况。你直接设位置的话,角色会穿墙的——我见过有人这么干过,结果测试时角色直接掉出地图。
1.3 测试你的第一个角色
把 BP_MyCharacter 拖到场景中,然后在 World Settings 中设置 Game Mode Override 的 Default Pawn Class 为 BP_MyCharacter。
运行游戏,按 W/A/S/D 移动,按空格跳跃。如果一切正常,恭喜你,你已经完成了第一个可控制的角色。
一个小技巧:在测试时打开控制台(~键),输入 ShowDebug INPUT,可以看到实时的输入值。这在我调试手柄输入时帮了大忙。
1.4 本章小结
今天我们做了三件事:
- 理解了 Pawn 和 Character 的本质区别
- 创建了第一个 Character 蓝图
- 绑定了输入并实现了基本移动
下一章我们会深入 CharacterMovementComponent 的参数调优,让你的角色手感从「滑冰」变成「扎实」。到时候我会分享一个我在射击项目里调了整整两周的移动参数表,保证让你少走弯路。
好,今天就到这里。动手试试,有问题随时翻回来看。