Update AnimatableProperty
documentation, reduce crate dependencies (#18543)
## Objective - Remove the second to last `bevy_animation` dependency on `bevy_render`. - Update some older documentation to reflect later changes to the crate. ## Narrative I'm trying to make `bevy_animation` independent of `bevy_render`. The documentation for `bevy_animation::AnimatableProperty` is one of the last few dependencies. It uses `bevy_render::Projection` to demonstrate animating an arbitrary value, but I thought that could be easily swapped for something else. I then realised that the rest of the documentation was a bit out of date. Originally `AnimatableProperty` was the only way to animate a property and so the documentation was quite detailed. But over time the crate has gained more documentation and other ways to hook up properties, leaving parts of the docs stale or covered elsewhere. So I've slimmed down the `AnimatableProperty` docs and added a link to the main alternative (`animated_field`). I've probably swung too far towards brevity, so I can build them back up if preferred. Also the example is kinda contrived and doesn't show the range of `AnimatableProperty`, like being able to choose different components. And finally the memes might be a bit stale? ## Showcase  ## Testing ``` cargo doc -p bevy_animation --no-deps --all-features cargo test -p bevy_animation --doc --all-features ```
This commit is contained in:
parent
4bc4f93f5b
commit
9a3baa7dc0
@ -105,38 +105,43 @@ use bevy_platform_support::hash::Hashed;
|
||||
use bevy_reflect::{FromReflect, Reflect, Reflectable, TypeInfo, Typed};
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
|
||||
/// A value on a component that Bevy can animate.
|
||||
/// A trait for exposing a value in an entity so that it can be animated.
|
||||
///
|
||||
/// You can implement this trait on a unit struct in order to support animating
|
||||
/// custom components other than transforms and morph weights. Use that type in
|
||||
/// conjunction with [`AnimatableCurve`] (and perhaps [`AnimatableKeyframeCurve`]
|
||||
/// to define the animation itself).
|
||||
/// For example, in order to animate field of view, you might use:
|
||||
/// `AnimatableProperty` allows any value contained in an entity to be animated
|
||||
/// as long as it can be obtained by mutable reference. This makes it more
|
||||
/// flexible than [`animated_field`].
|
||||
///
|
||||
/// [`animated_field`]: crate::animated_field
|
||||
///
|
||||
/// Here, `AnimatableProperty` is used to animate a value inside an `Option`,
|
||||
/// returning an error if the option is `None`.
|
||||
///
|
||||
/// # use bevy_animation::{prelude::AnimatableProperty, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId};
|
||||
/// # use bevy_reflect::Reflect;
|
||||
/// # use bevy_ecs::component::Component;
|
||||
/// # use std::any::TypeId;
|
||||
/// # use bevy_render::camera::{Projection, PerspectiveProjection};
|
||||
/// #[derive(Reflect)]
|
||||
/// struct FieldOfViewProperty;
|
||||
/// #[derive(Component)]
|
||||
/// struct ExampleComponent {
|
||||
/// power_level: Option<f32>
|
||||
/// }
|
||||
///
|
||||
/// impl AnimatableProperty for FieldOfViewProperty {
|
||||
/// #[derive(Clone)]
|
||||
/// struct PowerLevelProperty;
|
||||
///
|
||||
/// impl AnimatableProperty for PowerLevelProperty {
|
||||
/// type Property = f32;
|
||||
/// fn get_mut<'a>(&self, entity: &'a mut AnimationEntityMut) -> Result<&'a mut Self::Property, AnimationEvaluationError> {
|
||||
/// fn get_mut<'a>(
|
||||
/// &self,
|
||||
/// entity: &'a mut AnimationEntityMut
|
||||
/// ) -> Result<&'a mut Self::Property, AnimationEvaluationError> {
|
||||
/// let component = entity
|
||||
/// .get_mut::<Projection>()
|
||||
/// .ok_or(AnimationEvaluationError::ComponentNotPresent(TypeId::of::<
|
||||
/// Projection,
|
||||
/// >(
|
||||
/// )))?
|
||||
/// .get_mut::<ExampleComponent>()
|
||||
/// .ok_or(AnimationEvaluationError::ComponentNotPresent(
|
||||
/// TypeId::of::<ExampleComponent>()
|
||||
/// ))?
|
||||
/// .into_inner();
|
||||
/// match component {
|
||||
/// Projection::Perspective(perspective) => Ok(&mut perspective.fov),
|
||||
/// _ => Err(AnimationEvaluationError::PropertyNotPresent(TypeId::of::<
|
||||
/// PerspectiveProjection,
|
||||
/// >(
|
||||
/// ))),
|
||||
/// }
|
||||
/// component.power_level.as_mut().ok_or(AnimationEvaluationError::PropertyNotPresent(
|
||||
/// TypeId::of::<Option<f32>>()
|
||||
/// ))
|
||||
/// }
|
||||
///
|
||||
/// fn evaluator_id(&self) -> EvaluatorId {
|
||||
@ -144,58 +149,44 @@ use downcast_rs::{impl_downcast, Downcast};
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// You can then create an [`AnimationClip`] to animate this property like so:
|
||||
///
|
||||
/// # use bevy_animation::{AnimationClip, AnimationTargetId, VariableCurve, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId};
|
||||
/// You can then create an [`AnimatableCurve`] to animate this property like so:
|
||||
///
|
||||
/// # use bevy_animation::{VariableCurve, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId};
|
||||
/// # use bevy_animation::prelude::{AnimatableProperty, AnimatableKeyframeCurve, AnimatableCurve};
|
||||
/// # use bevy_ecs::name::Name;
|
||||
/// # use bevy_reflect::Reflect;
|
||||
/// # use bevy_render::camera::{Projection, PerspectiveProjection};
|
||||
/// # use bevy_ecs::{name::Name, component::Component};
|
||||
/// # use std::any::TypeId;
|
||||
/// # let animation_target_id = AnimationTargetId::from(&Name::new("Test"));
|
||||
/// # #[derive(Reflect, Clone)]
|
||||
/// # struct FieldOfViewProperty;
|
||||
/// # impl AnimatableProperty for FieldOfViewProperty {
|
||||
/// # type Property = f32;
|
||||
/// # fn get_mut<'a>(&self, entity: &'a mut AnimationEntityMut) -> Result<&'a mut Self::Property, AnimationEvaluationError> {
|
||||
/// # let component = entity
|
||||
/// # .get_mut::<Projection>()
|
||||
/// # .ok_or(AnimationEvaluationError::ComponentNotPresent(TypeId::of::<
|
||||
/// # Projection,
|
||||
/// # >(
|
||||
/// # )))?
|
||||
/// # .into_inner();
|
||||
/// # match component {
|
||||
/// # Projection::Perspective(perspective) => Ok(&mut perspective.fov),
|
||||
/// # _ => Err(AnimationEvaluationError::PropertyNotPresent(TypeId::of::<
|
||||
/// # PerspectiveProjection,
|
||||
/// # >(
|
||||
/// # ))),
|
||||
/// # }
|
||||
/// # }
|
||||
/// # fn evaluator_id(&self) -> EvaluatorId {
|
||||
/// # EvaluatorId::Type(TypeId::of::<Self>())
|
||||
/// # }
|
||||
/// # #[derive(Component)]
|
||||
/// # struct ExampleComponent { power_level: Option<f32> }
|
||||
/// # #[derive(Clone)]
|
||||
/// # struct PowerLevelProperty;
|
||||
/// # impl AnimatableProperty for PowerLevelProperty {
|
||||
/// # type Property = f32;
|
||||
/// # fn get_mut<'a>(
|
||||
/// # &self,
|
||||
/// # entity: &'a mut AnimationEntityMut
|
||||
/// # ) -> Result<&'a mut Self::Property, AnimationEvaluationError> {
|
||||
/// # let component = entity
|
||||
/// # .get_mut::<ExampleComponent>()
|
||||
/// # .ok_or(AnimationEvaluationError::ComponentNotPresent(
|
||||
/// # TypeId::of::<ExampleComponent>()
|
||||
/// # ))?
|
||||
/// # .into_inner();
|
||||
/// # component.power_level.as_mut().ok_or(AnimationEvaluationError::PropertyNotPresent(
|
||||
/// # TypeId::of::<Option<f32>>()
|
||||
/// # ))
|
||||
/// # }
|
||||
/// # fn evaluator_id(&self) -> EvaluatorId {
|
||||
/// # EvaluatorId::Type(TypeId::of::<Self>())
|
||||
/// # }
|
||||
/// # }
|
||||
/// let mut animation_clip = AnimationClip::default();
|
||||
/// animation_clip.add_curve_to_target(
|
||||
/// animation_target_id,
|
||||
/// AnimatableCurve::new(
|
||||
/// FieldOfViewProperty,
|
||||
/// AnimatableKeyframeCurve::new([
|
||||
/// (0.0, core::f32::consts::PI / 4.0),
|
||||
/// (1.0, core::f32::consts::PI / 3.0),
|
||||
/// ]).expect("Failed to create font size curve")
|
||||
/// )
|
||||
/// AnimatableCurve::new(
|
||||
/// PowerLevelProperty,
|
||||
/// AnimatableKeyframeCurve::new([
|
||||
/// (0.0, 0.0),
|
||||
/// (1.0, 9001.0),
|
||||
/// ]).expect("Failed to create power level curve")
|
||||
/// );
|
||||
///
|
||||
/// Here, the use of [`AnimatableKeyframeCurve`] creates a curve out of the given keyframe time-value
|
||||
/// pairs, using the [`Animatable`] implementation of `f32` to interpolate between them. The
|
||||
/// invocation of [`AnimatableCurve::new`] with `FieldOfViewProperty` indicates that the `f32`
|
||||
/// output from that curve is to be used to animate the font size of a `PerspectiveProjection` component (as
|
||||
/// configured above).
|
||||
///
|
||||
/// [`AnimationClip`]: crate::AnimationClip
|
||||
pub trait AnimatableProperty: Send + Sync + 'static {
|
||||
/// The animated property type.
|
||||
type Property: Animatable;
|
||||
|
Loading…
Reference in New Issue
Block a user