角色控制器

Author : Charley

在LayaAir3引擎中,角色控制器的类为 CharacterController,继承自 PhysicsColliderComponent。本文档介绍角色控制器的碰撞形状、专有属性和运动控制方法。关于角色控制器的概念说明,请参考《3D物理组件》总览

1、碰撞形状相关

碰撞形状是用于描述物体与其他物体发生碰撞时,如何检测和响应碰撞的几何体。它定义了物体的物理边界,即物体的外形,以便物理引擎能够准确判断物体之间是否发生接触,并据此计算碰撞后的反应。

由于角色控制器默认是胶囊碰撞形状,且不建议修改。所以角色控制器在IDE中无法更改碰撞形状类型,但是我们提供了碰撞形状大小改变(胶囊半径、胶囊高度)以及碰撞形状偏移(胶囊偏移)的属性,用于调整碰撞形状。

1.1 胶囊半径 radius

该属性表示角色控制器所使用的胶囊碰撞形状的半径。决定了角色在水平方向上的碰撞范围大小。如动图1-1所示:

(动图1-1)

1.2 胶囊高度 height

该属性表示角色控制器所使用的胶囊碰撞形状的高度,决定了角色在垂直方向上的碰撞范围大小。如动图1-2所示:

(动图1-2)

1.3 碰撞形状编辑工具

除了通过属性数值的调整,也可以直接在场景的碰撞形态上修改。

如动图1-3所示,直接点击碰撞形状顶部的“显示碰撞形状编辑工具”即可,

进入编辑模式后,可以看到几个白色方块,这些就是编辑点,通过拖动编辑点,可以实现便捷的形状外观改变。

(动图1-3)

1.4 胶囊偏移 centerOffset

该属性表示角色控制器所使用的胶囊碰撞形状的中心偏移,用于控制胶囊碰撞形状在角色控制器中的位置。

当角色模型的原点与实际的碰撞中心不一致时,使用中心偏移量来修正胶囊体的位置,确保碰撞检测的准确性。

(动图1-4)

2、碰撞分组设置

角色控制器继承自物理碰撞器组件基类 PhysicsColliderComponent,支持碰撞分组功能。通过设置所属碰撞组(collisionGroup)和可碰撞组(canCollideWith),可以控制角色与哪些物体发生碰撞。

关于碰撞分组的详细说明,请参考《3D刚体》的碰撞分组章节

3、IDE面板的专有属性

3.1 重力 gravity

重力指的是物理引擎施加在刚体上的一种恒定加速度,通常模拟现实世界中的引力。

重力会影响刚体的运动,使其向某个方向(通常是向下,即 Y 轴负方向)持续加速,从而模拟真实世界中的自由落体效果。

默认的重力值为 (0, -9.8, 0),表示物体会以 9.8 m/s² 的加速度向下坠落,效果如动图3-1所示。

(动图3-1)

3.2 推动力 pushForce

当角色与其他可推动的物体发生碰撞时,推动力会作用在物体上,使其产生移动。

如动图3-2所示,设置了推动力后,方块障碍未能阻挡角色的步伐,如果推动力为0,则无法推开方块,角色会被挡住。

(动图3-2)

3.3 最大坡度 maxSlope

最大坡度是指角色控制器能够攀爬的最大坡度角度。如果斜坡的角度超过该值,角色将无法继续向上移动,可能会开始滑落或停在斜坡下方。

如动图3-3所示,当最大坡度设置为50的时候,角色可以轻松走上锥体,但是面对90度的方块障碍物就无法通过了。

(动图3-3)

3.4 脚步高度 stepHeight

角色行走的脚步高度,用于表示角色能够顺利跨越的台阶最大高度。如果台阶高度超过了这个设定值,角色就无法直接跨越该台阶,会被阻挡或者需要采用其他方式通过(比如绕路)。

该值通常在 0.1 - 1之间,例如动图3-4中,最大坡度为默认值90度,脚步高度设置为0.5,可以轻松通过图中较低障碍,但无法通过相对较高的障碍。

(动图3-4)

3.5 皮肤宽度 skinWidth

皮肤宽度用于设置角色控制器的碰撞皮肤厚度。它定义了角色与其他碰撞体之间保持的最小距离缓冲区。较大的值可以减少角色卡在几何体中的概率,但可能导致角色看起来悬浮在地面上方;较小的值使角色更贴近地面,但可能导致碰撞穿透。

3.6 起跳速度 jumpSpeed

起跳速度用于设置角色控制器跳跃时的初始速度大小。值越大,角色跳跃时的初始向上速度越快,跳得越高。

3.7 最小移动距离 minDistance

最小移动距离用于设置角色控制器移动时的最小距离阈值。当移动的距离小于该值时,角色不会产生实际位移。该属性可以用于过滤掉微小的抖动运动。

4、引擎中的运动控制

角色的运动控制相关,需要在代码逻辑中调用实现。

4.1 角色位置 position

角色位置用于获取和设置角色控制器的位置,通常应用于获取角色当前位置,或者设置角色位置初始化(例如出生点与传送点)等需求。

代码设置示例如下:

const { regClass, property } = Laya;
@regClass()
export default class DirectMove extends Laya.Script {
    declare owner: Laya.Sprite3D;
    private characterController: Laya.CharacterController;
    onAwake(): void {
        // 获取 角色控制器 组件并赋值给 characterController
        this.characterController = this.owner.getComponent(Laya.CharacterController);
        //设置出生点位置
        this.characterController.position = new Laya.Vector3(0, 0, 0);
    }
}

4.2 角色移动 move()

角色移动用于通过指定移动向量来移动角色。

在代码中,如果要自由控制角色的移动,通常是放到每帧更新(onUpdate())的时候执行,通过不断调用 move 方法并传入移动向量,角色会按照指定的方向和距离进行移动。

当需要停止的时候,不仅仅是停止调用move移动向量。还要将move的移动向量重置为零向量。否则会一直基于最后一次设置的向量移动。

代码设置示例如下:

const { regClass, property } = Laya;
@regClass()
export default class DirectMove extends Laya.Script {
    declare owner: Laya.Sprite3D;
    private characterController: Laya.CharacterController;
    // 标记角色是否移动
    private ismoveing: boolean = false;
    //移动向量,速度与方向,向X轴正方向移动,速度为0.05
    private moveVector: Laya.Vector3 = new Laya.Vector3(0.05, 0, 0);
    onAwake(): void {
        // 获取 角色控制器 组件并赋值给 characterController
        this.characterController = this.owner.getComponent(Laya.CharacterController);
    }

    /**
     * 每帧更新时执行,尽量不要在这里写大循环逻辑或者使用 getComponent 方法
     * 此方法为虚方法,使用时重写覆盖即可
     */
    onUpdate(): void {
        // 如果角色可移动 (ismoveing为true时)
        if (this.ismoveing) {
            // 调用角色控制器的 move 方法,使角色按照 moveVector 向量移动
            this.characterController.move(this.moveVector);
        }
    }

    /**
     * 停止角色移动
     */
    public moveStop(): void {
        // 标记角色停止移动,不再每帧更新
        this.ismoveing = false;
        // 重置角色的移动向量置为零向量,使其停止移动
        this.characterController.move(Laya.Vector3.ZERO.clone());
    }
}

基于角色控制器,完整的自由控制角色行走示例,请使用LayaAirIDE 3.2或以上版本,创建3D-RPG示例模板项目,查看源码。

4.3 角色跳跃 jump()

角色跳跃可以控制角色控制器的跳跃方向和高度,通常是重力相反的方向(Y轴正方向),绝对值越大,单次跳跃的高度越高。

代码设置示例如下:

const { regClass, property } = Laya;
@regClass()
export default class DirectMove extends Laya.Script {
    declare owner: Laya.Sprite3D;
    private characterController: Laya.CharacterController;
    /** 跳跃的向量,Y轴正方向,高度5 */
    private jumpVector: Laya.Vector3 = new Laya.Vector3(0, 5, 0);

    onAwake(): void {
        // 获取 角色控制器 组件并赋值给 characterController
        this.characterController = this.owner.getComponent(Laya.CharacterController);
        //设置出生点位置
        this.characterController.position = new Laya.Vector3(0, 0, 0);
    }

    onKeyDown(evt: Laya.Event): void {
        switch (evt.keyCode) {
            case Laya.Keyboard.SPACE: //按键盘空格时
                this.characterController.jump(this.jumpVector); // 跳跃
                break;
        }
    }
}

4.4 获得垂直速度 getVerticalVel()

垂直速度方法主要用于获取角色在垂直方向(通常是 Y 轴)的当前速度。这个值反映了角色受重力、跳跃或其他垂直运动影响时的状态。

开发者可以通过检测垂直速度来判断角色是否在空中或刚刚落地,根据当前状态实现相应的逻辑。

  • 值为 0,表示角色位于地面;
  • 为正值,表示角色正在上升(如跳跃);
  • 为负值,表示角色在下落。

代码设置示例如下:

const { regClass, property } = Laya;
@regClass()
export default class DirectMove extends Laya.Script {
    declare owner: Laya.Sprite3D;
    private characterController: Laya.CharacterController;

    onAwake(): void {
        // 获取 角色控制器 组件并赋值给 characterController
        this.characterController = this.owner.getComponent(Laya.CharacterController);
    }

    onUpdate(): void {
        if (this.characterController.getVerticalVel() !== 0)
            // 控制台输出角色的垂直速度
            console.log("垂直速度", this.characterController.getVerticalVel());
    }
}

4.5 判断是否在地面 isGrounded() / isOnGround()

该方法用于判断角色是否站在地面上,返回布尔值。这是角色控制中非常常用的方法,可以用来控制跳跃逻辑(例如只有在地面上才能跳跃)或切换行走/下落动画。

isGrounded()isOnGround() 功能相同,都可以使用。

代码设置示例如下:

const { regClass, property } = Laya;
@regClass()
export default class DirectMove extends Laya.Script {
    declare owner: Laya.Sprite3D;
    private characterController: Laya.CharacterController;

    onAwake(): void {
        this.characterController = this.owner.getComponent(Laya.CharacterController);
    }

    onKeyDown(evt: Laya.Event): void {
        switch (evt.keyCode) {
            case Laya.Keyboard.SPACE:
                // 只有在地面上时才能跳跃
                if (this.characterController.isGrounded()) {
                    this.characterController.jump(new Laya.Vector3(0, 5, 0));
                }
                break;
        }
    }
}

5、关联文档

《3D物理系统》

Copyright ©Layabox 2026 all right reserved,powered by LayaAir Engine更新时间: 2026-06-02 11:29:27

results matching ""

    No results matching ""