Crates.io | bevy_state_curves |
lib.rs | bevy_state_curves |
version | |
source | src |
created_at | 2023-10-24 04:57:31.016271 |
updated_at | 2024-12-01 06:12:25.592687 |
description | A state saving and management crate for the Bevy Game Engine saving via curve keyframes |
homepage | https://github.com/NoahShomette/bevy_state_curves |
repository | https://github.com/NoahShomette/bevy_state_curves |
max_upload_size | |
id | 1012060 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
bevy_state_curves
Bevy_State_Curves is an implementation of the state storage and interpolation system described in this blog post. This system was used in Planetary Annihilation and has some neat features that arise for mostly free from it.
The implementation of this crate is focused on compile time curves and integration with the ECS. Compile time curves were chosen for the performance factors while ECS because ECS everything.
Version Compatibility Table:
Bevy Version | Crate Version |
---|---|
0.15 |
0.7.0 |
0.14 |
0.6.0 |
0.13 |
0.5.0 |
0.12 |
0.3.1 - 0.4.0 |
Create a new curve keyframe type
/// Only Clone is needed for the CurveKeyframes. I also recommend `Component` as it is
/// an ergonomic way to handle having the current interpolated state be the state thats
/// on the entity physically
#[derive(Clone)]
pub struct ObjectRadius {
radius: f32,
}
impl LinearKeyframe<ObjectRadius> for ObjectRadius {
fn lerp(&self, next_frame_state: &ObjectRadius, ratio: f64) -> ObjectRadius {
ObjectRadius {
radius: self.radius + (next_frame_state.radius - self.radius) * ratio as f32,
}
}
}
/// Generally only implement one Keyframe type for a specific type of state.
/// Nothing technically stops you from doing all three for one but theres absolutely no reason to do that.
impl SteppedKeyframe<ObjectRadius> for ObjectRadius {}
impl PulseKeyframe<ObjectRadius> for ObjectRadius {}
Insert it into an entity using the right curve component type for your curve type. LinearCurve<ObjectRadius>
, PulseCurve<ObjectRadius>
, or SteppedCurve<ObjectRadius>
.
commands.entity(entity).insert(LinearCurve::<ObjectRadius>::new());
Add/remove keyframes using the curve as a normal component on an entity. Get state in a normal system using normal queries!
fn insert_keyframes(mut radius_query: Query<&mut LinearCurve<ObjectRadius>){
for radius in radius_query.iter_mut(){
radius.insert_keyframe(1, ObjectRadius{radius: 1.0});
radius.insert_keyframe(10, ObjectRadius{radius: 2.0});
}
}
fn curve_entity_system(radius_query: Query<&LinearCurve<ObjectRadius>){
for radius in radius_query.iter(){
let radius_at_tick = radius.get_state(5);
assert_eq!(radius_at_tick, 1.5);
}
}
This crate relies on an internal GameTick
type alias of a u64 to create a sense of time. Higher ticks are considered later/older chronologically than lower numbered ticks. When using this crate you will have to decide what the ticks will look like in your crate and implement those systems yourself. This crate does nothing with GameTick
other than provide it and use it as an identifier of state keyframes.
See the solar_system.rs example for an example of using GameTick
in a game concept.
This crate supports three types of curves. See the docs.rs documentation for each one for details on how they work. Each of these is a Bevy Component.
LinearCurve<T: LinearKeyFrame>
SteppedCurve<T: SteppedKeyFrame>
PulseCurve<T: PulseKeyFrame>
Bevy_State_Curves
is created for a specific open source project idea I have. As that project takes shape I will eventually link it here. Because of this features to this crate will be driven by features needed for that project. If you randomly and terribly decide to use this crate, let me know if theres something wrong, it needs updating, or even better, make prs and issues as needed!
At this time, current potential ideas for features are:
SystemParam
that is used to spawn and manage curves. Used to drive other featuresStateLifetime
. Essentially when a state exists in the world. This would be used to drive filtering of global state concepts. Eg reset the world to this tick filtering states by only those that "existed" at this time.CurveTrait
functions. No clue yet but I'm sure some more will be needed eventuallySome of these features will most likely not materialize in this crate itself. They are too specific and easier implemented in whatever project is using this crate manually. Others like tests, serde, and similar will be here quickly.