AnimatorController
AnimatorController——动画控制器,用于动画的各种状态控制。
提示
AnimatorController 是一个抽象类,其它动画控制器都必须继承自 AnimatorController 或 AnimatorController 的子类。
DefaultAnimatorController
DefaultAnimatorController 是 Fantasy 3D 内置的关键帧动画的控制器。DefaultAnimatorController 存在以下两种创建方式:
解析包含关键帧动画的 glb/gltf 数据时,由引擎自动创建,详见“Animator->创建”。
手动创建,如下所示:
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 } );
提示
更多信息请参考 “three.js 动画系统介绍”。
属性
animationMixer - 获取 three.js 原生动画混合器(AnimationMixer),只读属性。
animationClips - 获取 three.js 原生动画片段(AnimationClip)数组,只读属性。
方法
- animationNames - 获取动画名称。
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 );
提示
- 动画循环模式可选值,详见“THREE动画常量”;
- 如果动画循环模式选择 LoopRepeat 或 LoopPingPong,可以指定循环次数,如下所示:
// 设置循环播放“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 可以用于调节动画的播放速度。
- getTimeScale - 获取指定名称动画的时间比例。
import { Animator } from '@fantasy3d/core';
const { controller } = entity.getComponent( Animator );
// 获取名为“Fly”的动画的时间比例
const timeScale = controller.getTimeScale( 'Fly' );
- setEffectiveTimeScale - 设置指定名称动画的有效时间比例。
import { Animator } from '@fantasy3d/core';
const { controller } = entity.getComponent( Animator );
// 设置名为“Fly”的动画的有效时间比例
controller.setEffectiveTimeScale( 'Fly', 0.5 );
- getEffectiveTimeScale - 获取指定名称动画的有效时间比例。
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 );
- getEffectiveWeight - 获取指定名称动画的有效影响权重。
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 - 在传入的事件间隔内,通过逐渐将时间比例 timeScale 由 startTimeScale 修改至 endTimeScale 来改变播放速度。
注意
startTimeScale 和 endTimeScale 参数的取值范围 [ 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 );
- stopWraping - 停用指定名称动画的所有预定的 wraping)。
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:
} );
提示
在 LoopRepeat 或 LoopPingPong 动画循环模式下,每完成一次动画播放就会触发一次 loop 事件。