14个版本 (破坏性更新)
0.11.0 | 2024年7月8日 |
---|---|
0.10.0 | 2024年2月27日 |
0.9.0 | 2023年11月7日 |
0.8.0 | 2023年7月12日 |
0.1.0 | 2021年12月24日 |
#14 in 游戏开发
2,689 下载/月
在 4 包 中使用
800KB
3K SLoC
🍃 Bevy Tweening
Bevy游戏引擎的补间动画插件。
功能
- 可以动画化任何组件或资源的任何字段,包括自定义的。
- 可以并行地对每个组件/资源运行多个补间(动画)。
- 可以一个接一个地链式多个补间(动画),以创建复杂的动画。
- 当补间完成时,可以触发一个Bevy事件或调用一个回调函数。
用法
依赖项
添加到 Cargo.toml
[dependencies]
bevy_tweening = "0.11"
此包支持以下功能
功能 | 默认 | 描述 |
---|---|---|
bevy_asset |
是 | 启用对组件(以及资源)进行动画化。 |
bevy_sprite |
是 | 包括一些与 Sprite 相关组件的内置透镜。 |
bevy_ui |
是 | 包括一些与UI相关组件的内置透镜。 |
bevy_text |
是 | 包括一些与 Text 相关组件的内置透镜。 |
系统配置
将 TweeningPlugin
添加到您的应用程序中
App::default()
.add_plugins(DefaultPlugins)
.add_plugins(TweeningPlugin)
.run();
这提供了使用 🍃 Bevy Tweening 的基本设置。但是,根据您想要动画化的组件和资源,可能还需要进行额外的设置。
-
为了确保组件
C
被动画化,必须在每帧运行component_animator_system::<C>
系统并添加一个Animator::<C>
组件到与C
相同的实体。 -
为了确保资源
A
被动画化,必须在每帧运行asset_animator_system::<A>
系统并添加一个AssetAnimator<A>
组件到任何实体。动画资源还需要启用bevy_asset
功能(默认启用)。
默认情况下,🍃 Bevy Tweening 采用极简主义方法,TweeningPlugin
将仅添加用于动画组件和资产的系统,前提是 🍃 Bevy Tweening 本身提供了 Lens
。这意味着任何其他 Bevy 组件或资产(无论是来自 Bevy 本身的内置组件,还是自定义组件)都需要手动安排适当的系统。
组件或资产 | TweeningPlugin 添加的动画系统? |
---|---|
变换 |
是 |
精灵 |
仅当启用 bevy_sprite 功能时 |
颜色材质 |
仅当启用 bevy_sprite 功能时 |
样式 |
仅当启用 bevy_ui 功能时 |
文本 |
仅当启用 bevy_text 功能时 |
所有其他组件 | 否 |
要为组件 C
添加系统,使用
app.add_systems(Update, component_animator_system::<C>.in_set(AnimationSystem::AnimationUpdate));
类似地,对于资产 A
,使用
app.add_systems(Update, asset_animator_system::<A>.in_set(AnimationSystem::AnimationUpdate));
动画组件
通过为变换创建一个 Tween
动画来动画化实体的变换位置,并添加一个带有该缓动的 Animator
组件
// Create a single animation (tween) to move an entity.
let tween = Tween::new(
// Use a quadratic easing on both endpoints.
EaseFunction::QuadraticInOut,
// Animation time (one way only; for ping-pong it takes 2 seconds
// to come back to start).
Duration::from_secs(1),
// The lens gives the Animator access to the Transform component,
// to animate it. It also contains the start and end values associated
// with the animation ratios 0. and 1.
TransformPositionLens {
start: Vec3::ZERO,
end: Vec3::new(1., 2., -4.),
},
)
// Repeat twice (one per way)
.with_repeat_count(RepeatCount::Finite(2))
// After each iteration, reverse direction (ping-pong)
.with_repeat_strategy(RepeatStrategy::MirroredRepeat);
commands.spawn((
// Spawn a Sprite entity to animate the position of.
SpriteBundle {
sprite: Sprite {
color: Color::RED,
custom_size: Some(Vec2::new(size, size)),
..default()
},
..default()
},
// Add an Animator component to control and execute the animation.
Animator::new(tween),
));
动画链
Bevy Tweening 支持几种类型的 可缓动 构建块,这些构建块可以组合成复杂的动画。可缓动是一种实现 Tweenable<T>
特性的类型。
Tween
- 两个值之间的简单缓动(缓和)动画。Sequence
- 一系列依次执行的缓动。Tracks
- 一系列并行执行的缓动。Delay
- 时间延迟。
大多数缓动都可以通过 then()
操作符进行链式调用
// Produce a sequence executing 'tween1' then 'tween2'
let tween1 = Tween { [...] }
let tween2 = Tween { [...] }
let seq = tween1.then(tween2);
预定义的镜头
对于最常用的用例,提供了一些预定义的镜头,这些镜头也作为示例。强烈建议用户编写自己的镜头,以便根据他们的用例调整动画。
预定义镜头的命名方案为 "<TargetName><FieldName>Lens"
,其中 <TargetName>
是要修改的内部动画系统查询的目标 Bevy 组件或资产类型的名称,而 <FieldName>
是由镜头就地修改的字段。所有预定义的镜头都修改单个字段。可以编写修改多个字段的自定义镜头。
Bevy 组件
目标组件 | 动画字段 | 镜头 | 功能 |
---|---|---|---|
变换 |
平移 |
TransformPositionLens |
|
rotation (Quat )¹ |
TransformRotationLens |
||
rotation (角度)² |
TransformRotateXLens |
||
rotation (角度)² |
TransformRotateYLens |
||
rotation (角度)² |
TransformRotateZLens |
||
rotation (角度)² |
TransformRotateAxisLens |
||
缩放 |
TransformScaleLens |
||
精灵 |
颜色 |
SpriteColorLens |
bevy_sprite |
样式 |
位置 |
UiPositionLens |
bevy_ui |
背景颜色 |
UiBackgroundColorLens |
bevy_ui |
|
文本 |
文本样式::颜色 |
TextColorLens |
bevy_text |
¹ 通过 Quat::slerp()
使用最短路径插值在两个旋转之间。
² 基于角度的插值,适用于超过半圈的旋转。
有关旋转镜头的比较,请参阅 详情。
Bevy 资产
资产动画始终需要 bevy_asset
功能。
目标资产 | 动画字段 | 镜头 | 功能 |
---|---|---|---|
颜色材质 |
颜色 |
颜色材质颜色透镜 |
bevy_asset + bevy_sprite |
自定义透镜
自定义透镜允许动画化 Bevy 组件或资产的任何字段或字段组。自定义透镜是实现 Lens
特质的类型,它是组件或资产类型的泛型。
struct MyXAxisLens {
start: f32,
end: f32,
}
impl Lens<Transform> for MyXAxisLens {
fn lerp(&mut self, target: &mut Transform, ratio: f32) {
let start = Vec3::new(self.start, 0., 0.);
let end = Vec3::new(self.end, 0., 0.);
target.translation = start + (end - start) * ratio;
}
}
请注意,透镜始终以 线性 的方式插值组件或资产的字段。应用的缓动类型会改变 ratio
参数演变的速率,并在调用 lerp()
函数之前应用。
lerp(线性插值)的基本公式可以是以下两种之一
开始+ (结束-开始) *标量
开始* (1.0 -标量) +结束*标量
这两种公式在数学上是等价的,但根据要插值的类型、可用的操作以及潜在的浮点精度误差,其中一种可能比另一种更适合。
自定义组件支持
自定义组件通过类似于 Bevy 组件 中描述的自定义透镜进行动画化。
#[derive(Component)]
struct MyCustomComponent(f32);
struct MyCustomLens {
start: f32,
end: f32,
}
impl Lens<MyCustomComponent> for MyCustomLens {
fn lerp(&mut self, target: &mut MyCustomComponent, ratio: f32) {
target.0 = self.start + (self.end - self.start) * ratio;
}
}
然后,还需要添加 component_animator_system::<CustomComponent>
系统到应用程序中,如 系统设置 中所述。此系统将提取每个帧上具有相同实体的所有 CustomComponent
实例,并通过其动画器对其组件进行动画化。
自定义资产支持
过程与自定义组件类似,为自定义资产创建自定义透镜。需要添加的系统是 asset_animator_system::<CustomAsset>
,如 系统设置 中所述。这需要 bevy_asset
功能(默认启用)。
示例
请参阅 examples/
文件夹。
菜单
cargo run --example menu --features="bevy/bevy_winit"
精灵颜色
cargo run --example sprite_color --features="bevy/bevy_winit"
变换旋转
cargo run --example transform_rotation --features="bevy/bevy_winit"
变换平移
cargo run --example transform_translation --features="bevy/bevy_winit"
颜色材质颜色
cargo run --example colormaterial_color --features="bevy/bevy_winit"
UI 位置
cargo run --example ui_position --features="bevy/bevy_winit"
序列
cargo run --example sequence --features="bevy/bevy_winit"
缓动函数
提供了许多 缓动函数
- 二次内
- 二次外
- 二次内外
- 三次内
- 三次外
- 三次内外
- 四次内
- 四次外
- 四次内外
- 五次内
- 五次外
- 五次内外
- 正弦内
- 正弦外
- 正弦内外
- 圆形内
- 圆形外
- 圆形内外
- 指数内
- 指数外
- 指数内外
- 弹性内
- 弹性外
- 弹性内外
- 回弹内
- 回弹外
- 回弹内外
- 弹跳内
- 弹跳外
- 弹跳内外
兼容的 Bevy 版本
main
分支与最新的 Bevy 版本兼容。
bevy_tweening
版本的兼容性
bevy_tweening |
bevy |
---|---|
0.11 |
0.14 |
0.10 |
0.13 |
0.9 |
0.12 |
0.8 |
0.11 |
0.7 |
0.10 |
0.6 |
0.9 |
0.5 |
0.8 |
0.4 |
0.7 |
0.2 -0.3 |
0.6 |
0.1 |
0.5 |
由于 Bevy 发展迅速且经常进行破坏性更改,以及维护 🍃 Bevy Tweening 的资源有限,因此不支持(未发布)的 main
Bevy 分支。然而,每次新的 bevy
发布后,都会升级 bevy_tweening
crate 以支持新发布的版本。
与 bevy_easings
的比较
bevy_tweening
库最初是 François Mocker 的 bevy_easings
库的分支,目的是
- 探索基于透镜而不是通用类型的替代设计,以用于每个easer/animator。这减少了所需的通用类型数量,并有望减少代码大小,以及执行插值所需系统的数量。
- 改进资产插值以避免像
bevy_easings
那样创建许多副本,而是原地修改资产(以及,通过相似性,组件)而不进行复制。原地修改还允许更优化的插值,仅修改感兴趣的领域,而不是在每帧创建整个组件的新副本。
依赖项
~19–58MB
~1M SLoC