2D Movement in Unity
Character Controller
地面检测的两个关键问题:
- 什么是地面?
- What is Ground属性:除了Player自身以外的Everything
- 检测到地面的条件是什么?
- Ground Check:脚部坐标点,用于检测和地面之间的碰撞
- Ceiling Check:头部坐标点,检测和头顶物体的碰撞
2点需要注意:
- Mass比其他物体稍大,跳跃下落的效果更好
- Collision Detection设置为Continuous,不然在玩家下落时会出现短暂的地面卡顿
- Z旋转轴锁死,因为会出现下面的情况:
Tilemap这里划分成3个模块:
- 前景:不被遮挡无碰撞元素
- 后景:被遮挡的无碰撞元素
- 平台:碰撞元素
这里为需要进行碰撞检测的Tilemap添加3个脚本:
- Rigidbody 2D:开启Static类型
- Tilemap Collider 2D
- Composite Collider 2D
Tips1: 在Edit Collider的时候,按住alt键可以进行对称编辑
Tips2: 鼠标拖动调整属性时,按住alt可以进行细调
角色如果只用一个Box Collider或者Circle Collider进行碰撞检测,
效果都会有缺点,仅使用Box Collider的时候,斜坡地段会出现卡顿的情况
这里作者建议角色上半身用Box Collider,
下半身用Circle Collider:
Movement
Brackeys提供的CharacterController2D类,
其中提供移动的主要方法就是Move,
Move需要3个参数:
- float move:水平移动距离
- bool crouch:是否下蹲
- bool jump:是否跳跃
为Player添加一个新的脚本PlayerMovement:
1 | public class PlayerMovement : MonoBehaviour |
并将之前为玩家添加的Character Controller 2D脚本与controller2D属性关联。
Unity提供按键检测的方法:
1 | Input.GetButtonDown("Jump"); // 检测按键按下 |
这样只要我们按下W键,这个方法就会返回true,
W键-Jump的对应关系在Unity内可以修改:
Edit - Project Settings - Input Manager
在PlayerMovement中添加进行跳跃检测的代码:
1 | public class PlayerMovement : MonoBehaviour |
这样做是可以进行跳跃,但是可能会出现角色卡在平台边缘的情况,
这是因为角色上半身的方形碰撞盒和平台碰撞盒之间存在摩擦力,
因此可以为角色的碰撞盒添加新的Physics Material:
- Fiction = 0
- Bounciness = 0
这样在平台边缘,角色就会因为缺少摩擦力自动滑下来
在PlayerMovement中对下蹲进行检测:
1 | public class PlayerMovement : MonoBehaviour |
在为Player添加碰撞体时,分别为上半身和下半身添加了一个碰撞体积,
下蹲实际实现的是使上半身的碰撞盒失效,
这一点需要在Character Controller 2D中对Crouch Disable Collider进行配置
在按下下蹲键时,上半身的碰撞盒就会失效:
onLanding闪电触发Bug
角色跳跃时,本应只在角色落地时触发,
但现在在角色跳起之前也被触发一次,
于是角色动画就因为跳起之前的这一次被关闭了:
查看CharacterController2D代码,发现地面检测是在FixedUpdate函数中被调用的,
因此应当是因为跳跃之后的第一帧,角色还没有离地,CharacterController2D的FixedUpdate函数就被调用了,
于是就判定跳跃结束,
因此这里在FixedUpdate函数中使用Invoke进行延时调用:
1 | // 地面检测函数 |