1个不稳定版本
0.10.0 | 2024年5月5日 |
---|
#628 in 游戏开发
用于 2 个crate(通过 lottie-renderer-bevy)
1MB
3K SLoC
🍃 Bevy Tweening Captured
Bevy游戏引擎的缓动动画插件。这是原始项目的分支,允许捕获自定义缓动函数
功能
- 可以动画化任何组件或资产的任何字段,包括自定义字段。
- 每个组件/资产可以并行运行多个缓动(动画)。
- 链式多个缓动(动画)以实现复杂的动画。
- 当缓动完成时,可以触发Bevy事件或调用回调。
用法
依赖项
添加到 Cargo.toml
[dependencies]
bevy_tweening = "0.10"
此crate支持以下功能
功能 | 默认 | 描述 |
---|---|---|
bevy_asset |
是 | 启用动画化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 添加的动画系统? |
---|---|
Transform |
是 |
Sprite |
仅当启用 bevy_sprite 功能时 |
ColorMaterial |
仅当启用 bevy_sprite 功能时 |
Style |
仅当启用 bevy_ui 功能时 |
Text |
仅当启用 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 支持多种类型的 tweenables,这些是构建块,可以组合成复杂的动画。tweenable 是实现 Tweenable<T>
特性的类型。
Tween
- 两个值之间简单的缓动(缓动)动画。Sequence
- 一系列按顺序执行的单个 tweenable。Tracks
- 并行执行的 tweenable 集合。Delay
- 时间延迟。
大多数 tweenable 可以通过 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 组件
目标组件 | 动画字段 | 镜头 | 功能 |
---|---|---|---|
Transform |
translation |
TransformPositionLens |
|
rotation (Quat )¹ |
TransformRotationLens |
||
rotation (angle)² |
TransformRotateXLens |
||
rotation (angle)² |
TransformRotateYLens |
||
rotation (angle)² |
TransformRotateZLens |
||
rotation (angle)² |
TransformRotateAxisLens |
||
scale |
TransformScaleLens |
||
Sprite |
color |
SpriteColorLens |
bevy_sprite |
Style |
position |
UiPositionLens |
bevy_ui |
BackgroundColor |
UiBackgroundColorLens |
bevy_ui |
|
Text |
TextStyle::color |
TextColorLens |
bevy_text |
¹ 使用 Quat::slerp()
在两个旋转之间进行最短路径插值。
² 基于角度的插值,适用于超过半圈的旋转。
有关旋转透镜的详细比较,请参阅 旋转透镜比较。
Bevy 资产
资产动画始终需要 bevy_asset
功能。
目标资产 | 动画字段 | 镜头 | 功能 |
---|---|---|---|
ColorMaterial |
color |
ColorMaterialColorLens |
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
实例及其 Animator<CustomComponent>
,并通过其动画器对组件进行动画化。
自定义资产支持
该过程与自定义组件类似,为自定义资产创建自定义透镜。需要添加的系统是 asset_animator_system::<CustomAsset>
,如 系统设置 中所述。这需要 bevy_asset
功能(默认启用)。
示例
请参阅 examples/
文件夹。
菜单
cargo run --example menu --features="bevy/bevy_winit"
sprite_color
cargo run --example sprite_color --features="bevy/bevy_winit"
transform_rotation
cargo run --example transform_rotation --features="bevy/bevy_winit"
transform_translation
cargo run --example transform_translation --features="bevy/bevy_winit"
colormaterial_color
cargo run --example colormaterial_color --features="bevy/bevy_winit"
ui_position
cargo run --example ui_position --features="bevy/bevy_winit"
sequence
cargo run --example sequence --features="bevy/bevy_winit"
缓动函数
提供了许多 缓动函数
- QuadraticIn
- QuadraticOut
- QuadraticInOut
- CubicIn
- CubicOut
- CubicInOut
- QuarticIn
- QuarticOut
- QuarticInOut
- QuinticIn
- QuinticOut
- QuinticInOut
- SineIn
- SineOut
- SineInOut
- CircularIn
- CircularOut
- CircularInOut
- ExponentialIn
- ExponentialOut
- ExponentialInOut
- ElasticIn
- ElasticOut
- ElasticInOut
- BackIn
- BackOut
- BackInOut
- BounceIn
- BounceOut
- BounceInOut
兼容的 Bevy 版本
main
分支与最新的 Bevy 版本兼容。
bevy_tweening
版本的兼容性
bevy_tweening |
bevy |
---|---|
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的有限资源,主(未发布)Bevy分支不支持。然而,在每次新的bevy
发布后不久,bevy_tweening
库就会升级以支持新发布的版本。
与bevy_easings
的比较
bevy_tweening
库最初是基于François Mocker的bevy_easings
库的一个分支,目标是
- 探索一种基于透镜而不是泛型类型为每个缓动器/动画器设计的替代方案。这减少了所需泛型类型的数量,并可能减少代码大小以及执行插值所需的系统数量。
- 改进资产插值以避免创建许多副本,如
bevy_easings
所做的那样,而是原地修改资产(以及相似地,组件)而不进行复制。原地修改还允许更优化的插值,仅修改感兴趣的字段,而不是在每一帧创建组件的新副本。
依赖关系
~19–58MB
~1M SLoC