跳至主要內容

AnimatorController

yisky大约 8 分钟组件文档组件动画控制器AnimatorController

AnimatorController——动画控制器,用于动画的各种状态控制。

提示

AnimatorController 是一个抽象类,其它动画控制器都必须继承自 AnimatorController 或 AnimatorController 的子类。

DefaultAnimatorController

DefaultAnimatorController 是 Fantasy 3D 内置的关键帧动画的控制器。DefaultAnimatorController 存在以下两种创建方式:

  1. 解析包含关键帧动画的 glb/gltf 数据时,由引擎自动创建,详见“Animator->创建”

  2. 手动创建,如下所示:

import { AnimationClip, InterpolateLinear, VectorKeyframeTrack } from 'three';
import { Animator, DefaultAnimatorController } from '@fantasy3d/core';

// 获取实体的 Transform 组件
const { transform } = entity;

// 获取 three.js 原生 Object3D 对象
const { object3D } = transform;

// 设置 Object3D 对象名称,后面创建动画关键帧时候会用到
object3D.name = 'Node';

// 创建一个动画关键帧,用于控制 Object3D 对象位置变化
const keyframe = new VectorKeyframeTrack(

    'Node.position',                // 对象名称 + 要控制的属性名称
    [ 0.0, 1.0, 2.0, 3.0, 4.0 ],    // 关键帧时间数组
    [ 
        
        0.0, 0.5, 0.0,              // 0.0时刻位置
        0.0, 2.0, 0.0,              // 1.0时刻位置
        0.0, 3.5, 0.0,              // 2.0时刻位置
        0.0, 2.0, 0.0,              // 3.0时刻位置
        0.0, 0.5, 0.0               // 4.0时刻位置

    ],
    InterpolateLinear               // 插值方法

);

// 创建动画片段
const animationClip = new AnimationClip(

    'jump',         // 动画名称
    4.0,            // 动画时长
    [ keyframe ]    // 动画关键帧数组

);

// 创建关键帧动画控制器
const controller = new DefaultAnimatorController(  object3D, [ animationClip ] );

// 添加动画组件
entity.addComponent( Animator, { controller } );

属性

方法

import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取动画名称
const names = controller.animationNames();
  • play - 播放指定名称动画。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 播放名为“Fly”的动画
controller.play( 'Fly' );
  • pause - 暂停或继续播放指定名称动画。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 暂停名为“Fly”的动画
controller.pause( 'Fly', true );

// 继续播放名为“Fly”的动画
controller.pause( 'Fly', false );
  • stop - 停止指定名称动画。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 停止名为“Fly”的动画
controller.stop( 'Fly' );
  • reset - 重置指定名称动画。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 重置名为“Fly”的动画
controller.reset( 'Fly' );
  • isScheduled - 判断指定名称动画是否已激活。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 判断名为“Fly”的动画是否已激活
if ( controller.isScheduled( 'Fly' ) ) {

    // TODO:

}
  • isRunning - 判断指定名称动画是否正在运行。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 判断名为“Fly”的动画是否正在运行
if ( controller.isRunning( 'Fly' ) ) {

    // TODO:

}
  • isPaused - 判断指定名称动画是否已暂停。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 判断名为“Fly”的动画是否已暂停
if ( controller.isPaused( 'Fly' ) ) {

    // TODO:

}
  • setEnabled - 设置启用/禁用指定名称的动画。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 启用名为“Fly”的动画
controller.setEnabled( 'Fly' );

// 禁用名为“Fly”的动画
controller.setEnabled( 'Fly' );
  • setLoop - 设置指定名称动画循环模式。
import { LoopRepeat } from 'three';
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画循环播放
controller.setLoop( 'Fly', LoopRepeat );

提示

  1. 动画循环模式可选值,详见“THREE动画常量”open in new window
  2. 如果动画循环模式选择 LoopRepeatLoopPingPong,可以指定循环次数,如下所示:
// 设置循环播放“Fly”动画,且循环5次
controller.setLoop( 'Fly', LoopRepeat, 5 );
  • setDuration - 设置指定名称动画播放总时长,单位:秒。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画播放总时长为4秒
controller.setDuration( "Fly", 4.0 );
  • getDuration - 获取指定名称动画播放总时长,单位:秒。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取名为“Fly”的动画播放总时长
const duration = controller.getDuration( 'Fly' );
  • setTimeScale - 设置指定名称动画的时间比例,值为0时会使动画暂停,值为负数时动画会反向执行。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画的时间比例因子
controller.setTimeScale( 'Fly', 1.5 );

提示

setTimeScale 可以用于调节动画的播放速度。

import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取名为“Fly”的动画的时间比例
const timeScale = controller.getTimeScale( 'Fly' );
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画的有效时间比例
controller.setEffectiveTimeScale( 'Fly', 0.5 );
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取名为“Fly”的动画的有效时间比例
const effectiveTimeScale = controller.getEffectiveScale( 'Fly' );
  • setTime - 设置指定名称动画当前播放时刻。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画播放时刻
controller.setTime( 'Fly', 0.5 );
  • getTime - 获取指定名称动画当前播放时刻。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取名为“Fly”的动画当前播放时刻
const time = controller.getTime( 'Fly' );
  • setStartAt - 设置指定名称动画的开始时刻。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画开始时刻
const time = controller.setStartAt( 'Fly', 0.5 );

注意

动画开始时刻需要大于等于0且小于等于动画播放总时长!

  • setStopAt - 设置指定名称动画的结束时刻。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画结束时刻
const time = controller.setStopAt( 'Fly', 2.5 );
  • halt - 在传入的时间间隔内,通过从当前值开始逐渐降低时间比例(timeScale)使指定名称动画逐渐减速至0。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 在2秒钟内逐渐降低名为“Fly”的动画的速度
controller.halt( 'Fly', 2.0 );
  • setWeight - 设置指定名称动画的影响权重,取值范围 [ 0 ~ 1 ],0表示无影响,1表示完全影响
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画影响权重
controller.setWeight( 'Fly', 0.5 );
  • getWeight - 获取指定名称动画的影响权重。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取名为“Fly”的动画影响权重
const weight = controller.getWeight( 'Fly' );
  • setEffectiveWeight - 设置指定名称动画的有效影响权重,取值范围 [ 0 ~ 1 ],0表示无影响,1表示完全影响
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画有效影响权重
controller.setEffectiveWeight( 'Fly', 0.5 );
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 获取名为“Fly”的动画有效影响权重
const weight = controller.getEffectiveWeight( 'Fly' );
  • setClampWhenFinished - 设置指定名称动画播放结束后停留在最后一帧还是回到初始帧,true停留在最后一帧,false返回初始帧。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 设置名为“Fly”的动画播放结束后返回初始帧
controller.setClampWhenFinished( 'Fly', false );
  • syncWith - 同步两个指定名称的动画。

提示

同步操作会将第二个动画的开始时刻(time)和时间比例(timeScale)同步给第一个动画。

import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 将动画“Run”的开始时刻和时间比例同步给动画“Fly”
controller.syncWith( 'Fly', 'Run' );
  • crossFadeFromTo - 在传入的时间段内,逐渐淡出第一个动画,并淡入第二个动画,如果 warp 参数值是 true, 额外的时间比例的渐变将会被应用。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 在两秒钟内逐渐淡出动画“Fly”并淡入“Run”动画
controller.crossFadeFromTo( 'Fly', 'Run', 2.0, true );
  • fadeIn - 在传入的时间间隔内,逐渐将指定名称动画的权重(weight)由0升到1。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 逐渐淡入“Fly”动画
controller.fadeIn( 'Fly', 2.0 );
  • fadeOut - 在传入的时间间隔内,逐渐将指定名称动画的的权重(weight)由1降到0。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 逐渐淡出“Fly”动画
controller.fadeOut( 'Fly', 2.0 );
  • stopFading - 停止指定名称动画的所有预定淡入/淡出。
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 停止“Fly”动画的所有预定淡入/淡出
controller.stopFading( 'Fly' );
  • wrap - 在传入的事件间隔内,通过逐渐将时间比例 timeScalestartTimeScale 修改至 endTimeScale 来改变播放速度。

注意

startTimeScaleendTimeScale 参数的取值范围 [ 0 ~ 1 ]

import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 在2秒钟内将“Fly”动画的时间比例由1.0提升到3.0
controller.wrap( 'Fly', 1.0, 3.0, 2.0 );
import { Animator } from '@fantasy3d/core';

const { controller } = entity.getComponent( Animator );

// 取消“Fly”动画的所有预定 wraping
controller.stopWraping( 'Fly' );

事件

通过 three.js 原生动画混合器(https://threejs.org/docs/index.html#api/en/animation/AnimationMixer),监听动画事件,目前支持以下两种类型事件:

  • finished - 动画结束事件
// 获取 three.js 原生动画混合器
const { animationMixer } = controller;

// 监听“finished”事件
animationMixer.addEventListener( 'finished', ( event ) => {

    // TODO:

} );

提示

LoopOnce 动画循环模式下,在动画播放结束后会触发 finished 事件。

  • loop - 动画循环事件
// 获取 three.js 原生动画混合器
const { animationMixer } = controller;

// 监听“loop”事件
animationMixer.addEventListener( 'loop', ( event ) => {

    // TODO:

} );

提示

LoopRepeatLoopPingPong 动画循环模式下,每完成一次动画播放就会触发一次 loop 事件。

上次编辑于: