角色控制器(CharacterController)是一种特殊的碰撞器组件,专门用于处理角色的物理运动。它提供了专门的移动算法和碰撞检测,能够处理台阶、斜坡等复杂地形,特别适合第一人称或第三人称游戏中的角色控制。
与其他碰撞器不同,角色控制器只能添加一个碰撞形状。通常建议使用胶囊体(CapsuleColliderShape)作为角色的碰撞形状。
属性 | 描述 |
---|---|
shapes | 碰撞形状集合 |
属性 | 描述 | 默认值 |
---|---|---|
stepOffset | 角色可以自动跨越的最大台阶高度。
| 0.5 |
slopeLimit | 角色可以行走的最大斜坡角度(度)。
| 45° |
nonWalkableMode | 定义如何处理不可行走的表面。
| PreventClimbing |
upDirection | 定义角色的向上方向。默认为 (0, 1, 0),即世界空间的 Y 轴向上。影响移动和碰撞检测的方向判定 | (0, 1, 0) |
方法名 | 描述 |
---|---|
addShape | 添加碰撞形状 |
removeShape | 移除指定碰撞形状 |
clearShapes | 清空所有碰撞形状 |
方法名 | 描述 |
---|---|
move | 移动角色控制器。返回一个碰撞标志值,标识碰撞状态。
|
移动函数 move()
会返回一个碰撞标志值,用于表示角色控制器与环境的碰撞状态。这些标志可以通过按位与运算(&)来检测:
标志名称 | 值 | 说明 |
---|---|---|
None | 0 | 没有发生任何碰撞 |
Sides | 1 | 与侧面发生碰撞 |
Up | 2 | 与上方发生碰撞(如天花板) |
Down | 4 | 与下方发生碰撞(如地面) |
// 创建角色控制器
const controller = entity.addComponent(CharacterController);
// 添加胶囊体形状
const capsule = new CapsuleColliderShape();
capsule.radius = 0.5;
capsule.height = 2;
controller.addShape(capsule);
// 配置控制器属性
controller.stepOffset = 0.5; // 设置台阶高度
controller.slopeLimit = 45; // 设置最大可行走斜坡角度
controller.upDirection = new Vector3(0, 1, 0); // 设置向上方向
class CharacterMovement extends Script {
private _velocity = new Vector3();
onUpdate() {
const controller = this.entity.getComponent(CharacterController);
const deltaTime = engine.deltaTime;
// 创建位移向量
const displacement = new Vector3();
Vector3.scale(this._velocity, deltaTime, displacement);
// 执行移动并获取碰撞标志
// minDist: 最小移动距离,通常设为0
// deltaTime: 经过的时间,用于物理计算
const collisionFlags = controller.move(displacement, 0, deltaTime);
// 处理碰撞响应
if (collisionFlags & ControllerCollisionFlag.Down) {
// 角色接触地面
}
}
}
使用示例:
const flags = controller.move(displacement, 0, deltaTime);
// 检查是否接触地面
if (flags & ControllerCollisionFlag.Down) {
// 角色在地面上
this._isGrounded = true;
}
// 检查是否撞到天花板
if (flags & ControllerCollisionFlag.Up) {
// 角色撞到头部
this._velocity.y = 0;
}
// 检查是否撞到墙壁
if (flags & ControllerCollisionFlag.Sides) {
// 角色撞到墙壁
this._handleWallCollision();
}
// 可以同时检查多个标志
if ((flags & ControllerCollisionFlag.Down) &&
(flags & ControllerCollisionFlag.Sides)) {
// 角色同时接触地面和墙壁
}
// 通过设置 slopeLimit 控制可行走的斜坡角度
controller.slopeLimit = 60; // 允许更陡的斜坡
// 设置不可行走斜面的处理方式
controller.nonWalkableMode = ControllerNonWalkableMode.PreventClimbingAndForceSliding; // 在太陡的斜面上会滑下
// 调整 stepOffset 来控制可跨越的台阶高度
controller.stepOffset = 0.3; // 较低的台阶
controller.stepOffset = 0.5; // 较高的台阶
完整的示例效果可以参考: