补间动画
经常需要让实体或其他数值随时间从一种状态过渡到另一种状态,这称为补间动画(tweening)。playcanvas-tween 是 PlayCanvas 的补间动画库,支持缓动曲线、循环、往返和事件。
安装
库提供两种构建,位于仓库的 dist 目录:
tween.umd.js:经典脚本。将其作为脚本资源添加到编辑器项目后,会为实体和应用添加tween()方法。如果应用在库加载后才创建,需要调用app.addTweenManager(),为其启用补间动画。tween.mjs:ES 模块,适用于 ESM 脚本和仅使用引擎的项目。可以调用tweenEntity(),或调用一次addTweenExtensions(),为实体和应用添加tween()方法:
import * as pc from 'playcanvas';
import { addTweenExtensions, SineOut } from './tween.mjs';
// adds tween() to entities and the application
addTweenExtensions(pc);
entity.tween(entity.getLocalPosition()).to({ x: 10, y: 0, z: 0 }, 1, SineOut).start();
实体补间动画
entity.tween() 接收要执行动画的值,to() 接收目标值、以秒为单位的时长,以及缓动曲线。下面让实体的局部位置永久往返变化:
this.entity
.tween(this.entity.getLocalPosition())
.to(new Vec3(4, 0, 0), 1.0, SineOut)
.loop(true)
.yoyo(true)
.start();
旋转应使用 rotate() 而非 to()。它接受欧拉角或四元数,其中欧拉角会通过四元数进行插值:
this.entity
.tween(this.entity.getLocalEulerAngles())
.rotate(new Vec3(180, 0, 180), 1.0, Linear)
.loop(true)
.yoyo(true)
.start();
缩放的使用方式与位置相同:
this.entity
.tween(this.entity.getLocalScale())
.to(new Vec3(3, 3, 3), 1.0, SineOut)
.loop(true)
.yoyo(true)
.start();
其他数值的补间动画
app.tween() 可以对颜色等任意对象执行补间动画。目标对象与原对象共有的属性会参与插值,并通过 onUpdate() 在变化时应用数值:
const color = new Color(0, 0, 0);
const material = this.entity.render.material;
this.app
.tween(color)
.to(new Color(1, 1, 1), 1.0, Linear)
.loop(true)
.yoyo(true)
.onUpdate(() => {
material.diffuse = color;
material.update();
})
.start();
上述演示来自 Using the Tween library 项目。
控制补间动画
补间动画的方法可以链式调用:
| 方法 | 说明 |
|---|---|
start()、stop() | 开始和停止补间动画。 |
pause()、resume() | 暂停和恢复补间动画。 |
delay(seconds) | 延迟开始。 |
repeat(count) | 播放 count 次。 |
loop(true) | 永久循环播放。 |
yoyo(true) | 每次正向播放后反向播放。需与 repeat 或 loop 结合,才能看到反向过程。 |
reverse() | 反转补间动画方向。 |
播放期间会调用以下回调:
| 回调 | 说明 |
|---|---|
onUpdate(callback) | 每次更新时调用,传入时间步长。 |
onComplete(callback) | 补间动画结束时调用。 |
onLoop(callback) | 循环动画每完成一轮时调用,代替 onComplete。 |
缓动
缓动曲线决定数值从起点到目标的变化方式。库提供 Linear,以及 Quadratic、Cubic、Quartic、Quintic、Sine、Exponential、Circular、Back、Bounce 和 Elastic 的 In、Out、InOut 变体,例如 SineOut 或 ElasticInOut。