2D动画组件(Animator2D)

Animator2D 是LayaAir引擎中用于2D节点的动画状态机组件,功能上与3D的 Animator 类似,但专门针对2D节点设计。通过 Animator2D 组件,可以为2D节点播放时间轴动画,并通过动画状态机来管理多个动画状态之间的切换。

关于动画状态机的通用概念(状态、切换、条件、分层等),请参考 动画状态机详解

关于时间轴动画的编辑操作,请参考 时间轴动画编辑详解

一、添加Animator2D组件

1.1 在IDE中添加

选中一个2D节点后,在右侧属性面板中点击 增加组件,选择 Animator2D 即可为该节点添加2D动画组件。

注意:Animator2D 只能添加到2D节点上,3D节点只能添加 Animator

1.2 创建动画时自动添加

当选中一个2D节点,在时间轴动画面板中点击 创建 按钮创建动画时,IDE会自动为该节点添加 Animator2D 组件,同时创建动画文件(.mc)和动画状态机文件(.mcc)。

1.3 通过代码添加

let sprite = new Laya.Sprite();
// 添加Animator2D组件
let animator2D = sprite.addComponent(Laya.Animator2D);

二、组件属性

Animator2D 组件在IDE属性面板中有以下属性:

Controller:绑定的2D动画控制器文件(.mcc),即动画状态机文件。需要先创建或指定一个动画状态机文件,才能编辑和播放动画。

Speed:动画播放速度,默认为1.0。设置为0可暂停动画,设置为0.5可半速播放,设置为2可双倍速播放。负数可以倒播。

三、与3D Animator的差异

虽然 Animator2DAnimator 在状态机的整体架构上是一致的(状态、切换、条件、分层),但存在以下差异:

对比项 Animator2D(2D) Animator(3D)
适用节点 2D节点(Sprite等) 3D节点(Sprite3D等)
动画文件后缀 .mc .lani
状态机文件后缀 .mcc .controller
动画状态类 AnimatorState2D AnimatorState
状态机层类 AnimatorControllerLayer2D AnimatorControllerLayer
播放状态类 AnimatorPlayState2D AnimatorPlayState
状态脚本类 AnimatorState2DScript AnimatorStateScript
录制模式 默认开启录制模式 需要手动点击录制按钮
动画属性 每个属性值允许单独设置 Vector属性不可缺少,删除会自动补上
循环控制 支持loop次数设定(-1/0/1/2...) 通过Is Looping布尔值控制
YoYo模式 支持(一次正播一次倒播) 不支持

四、动画状态属性(AnimatorState2D)

2D动画状态 AnimatorState2D 拥有以下可配置的属性:

Name:动画状态名称,用于代码中指定播放。

Speed:该状态的播放速度,默认1.0。

Loop:动画循环次数。-1 表示使用动画文件自身的循环设置,0 表示无限循环,1 表示播放一次,2 表示播放两次,以此类推。

Cycle Offset:循环偏移,基于播放起始时间的偏移值,仅作用于动画首次播放(0-1之间)。

Clip Start:动画文件的起始播放位置(0-1之间)。

Clip End:动画文件的停止播放位置(0-1之间)。

Clip:动画文件(.mc)。

YoYo:是否为往返播放模式,即一次正向播放,一次反向播放。默认关闭。

五、代码中使用

5.1 获取组件

// 获取2D动画组件
let animator2D = sprite.getComponent<Laya.Animator2D>(Laya.Animator2D);

5.2 播放动画

使用 play() 方法播放指定的动画状态:

/**
 * 播放动画。
 * @param name 动画状态名称,为null则播放默认动画。
 * @param layerIndex 层索引,默认为0。
 * @param normalizedTime 归一化的播放起始时间。
 */
animator2D.play("idle");

// 指定从50%位置开始播放
animator2D.play("run", 0, 0.5);

5.3 融合过渡

使用 crossFade() 方法在当前动画和目标动画之间进行融合过渡:

/**
 * 在当前动画状态和目标动画状态之间进行融合过渡播放。
 * @param name 目标动画状态名称。
 * @param layerIndex 层索引,默认为0。
 * @param normalizedTime 归一化的播放起始时间。
 * @param transitionDuration 过渡时间,归一化时间(0-1)。
 */
animator2D.crossFade("run", 0, Number.NEGATIVE_INFINITY, 0.3);

5.4 跳转到指定位置并停止

// 跳转到指定动画状态的归一化时间位置并停止
animator2D.gotoAndStop("idle", 0, 0.5);

// 跳转到指定帧并停止
animator2D.gotoAndStopByFrame("idle", 0, 10);

5.5 停止动画

animator2D.stop();

5.6 控制播放速度

// 暂停动画
animator2D.speed = 0;
// 正常播放
animator2D.speed = 1.0;
// 半速播放
animator2D.speed = 0.5;
// 倒放
animator2D.speed = -1.0;

5.7 判断是否正在播放

if (animator2D.isPlaying) {
    console.log("动画正在播放中");
}

5.8 动画切换条件

与3D Animator一样,Animator2D 支持通过参数来控制状态切换:

// 设置Float参数
animator2D.setParamsNumber("speed", 2.0);

// 设置Bool参数
animator2D.setParamsBool("isRunning", true);

// 触发Trigger
animator2D.setParamsTrigger("attack");

5.9 获取播放状态

// 获取控制器层
let layer = animator2D.getControllerLayer(0);

// 获取当前播放状态
let playState = layer.getCurrentPlayState();

// 获取当前动画持续时间(秒)
let duration = playState.duration;

// 获取当前动画状态
let currentState = playState.animatorState;

5.10 获取与操作动画状态

// 获取默认动画状态
let defaultState = animator2D.getDefaultState(0);

// 通过层获取指定动画状态
let layer = animator2D.getControllerLayer(0);
let state = layer.getStateByName("idle");

// 修改状态属性
state.speed = 2.0;
state.loop = 0; // 无限循环

六、状态脚本(AnimatorState2DScript)

2D动画状态支持添加状态脚本 AnimatorState2DScript,用于在动画状态的不同生命周期阶段执行自定义逻辑。

6.1 脚本生命周期

AnimatorState2DScript 提供以下回调方法:

  • onStateEnter():动画状态开始时执行。
  • onStateUpdate(normalizeTime):动画状态运行中执行,参数为归一化播放时间。
  • onStateExit():动画状态退出时执行。
  • onStateLoop():动画循环时,每次循环结束时执行。
  • onStateSwitch(currentState):切换到新状态时执行。

6.2 使用示例

在IDE中为动画状态添加脚本后,编写如下代码:

const { regClass } = Laya;

@regClass()
export class MyAniScript extends Laya.AnimatorState2DScript {

    constructor() {
        super();
    }

    /**
     * 动画状态开始时执行
     */
    onStateEnter(): void {
        console.log("2D动画状态进入");
    }

    /**
     * 动画状态运行中
     * @param normalizeTime 0-1 归一化播放时间
     */
    onStateUpdate(normalizeTime: number): void {
        if (normalizeTime > 0.5) {
            console.log("动画播放过半");
        }
    }

    /**
     * 动画状态退出时执行
     */
    onStateExit(): void {
        console.log("2D动画状态退出");
    }

    /**
     * 动画循环时执行
     */
    onStateLoop(): void {
        console.log("动画完成一次循环");
    }
}

6.3 通过事件监听状态

除了状态脚本,AnimatorState2D 还支持通过事件来监听状态变化:

let layer = animator2D.getControllerLayer(0);
let state = layer.getStateByName("idle");

// 监听状态进入
state.on(Laya.AnimatorState2D.EVENT_OnStateEnter, this, () => {
    console.log("进入idle状态");
});

// 监听状态退出
state.on(Laya.AnimatorState2D.EVENT_OnStateExit, this, () => {
    console.log("退出idle状态");
});

// 监听状态更新
state.on(Laya.AnimatorState2D.EVENT_OnStateUpdate, this, () => {
    console.log("idle状态更新");
});

// 监听状态循环
state.on(Laya.AnimatorState2D.EVENT_OnStateLoop, this, () => {
    console.log("idle状态完成一次循环");
});
Copyright ©Layabox 2026 all right reserved,powered by LayaAir Engine更新时间: 2026-06-02 11:29:26

results matching ""

    No results matching ""