pub struct TnuaController<S: TnuaScheme> {
pub basis: S::Basis,
pub basis_config: Option<<S::Basis as TnuaBasis>::Config>,
pub basis_memory: <S::Basis as TnuaBasis>::Memory,
pub current_action: Option<S::ActionState>,
/* private fields */
}Expand description
The main component used for interaction with the controls and animation code (needs a
TnuaConfig)
Every frame, the game code should invoke
initiate_action_feeding and then feed input this component
on every controlled entity. What should be fed is:
-
A basis - this is the main movement command - usually
TnuaBuiltinWalk, but there can be others. The controller’s basis is takens from the scheme (the generic argument). Controlling it is done by modifying thebasisfield of the controller.Refer to the documentation of the implementors of
TnuaBasisfor more information. -
Zero or more actions - these are movements like jumping, dashing, crouching, etc. Multiple actions can be fed, but only one can be active at any given moment. Unlike basis, there is a smart mechanism for deciding which action to use and which to discard, so it is safe to feed many actions at the same frame. Actions are also defined in the scheme, and can be fed using the
actionmethod.Refer to the documentation of the implementors of
TnuaActionfor more information.
Without TnuaControllerPlugin of the same scheme this component will not do anything.
Fields§
§basis: S::BasisInput for the basis - the main movement command.
basis_config: Option<<S::Basis as TnuaBasis>::Config>A copy of the basis’ configuration from the asset.
basis_memory: <S::Basis as TnuaBasis>::MemoryKept by the basis itself - but user code may modify if it knows what it`s doing.
current_action: Option<S::ActionState>The full state of the currently running action.
Be careful when touching that:
- Changing the
inputand evenconfigis usually fine. - Only change the
stateif you know what you’re doing. - Never change the actual variant.
Implementations§
Source§impl<S: TnuaScheme> TnuaController<S>
impl<S: TnuaScheme> TnuaController<S>
Sourcepub fn basis_access(
&self,
) -> Result<TnuaBasisAccess<'_, S::Basis>, TnuaControllerHasNotPulledConfiguration>
pub fn basis_access( &self, ) -> Result<TnuaBasisAccess<'_, S::Basis>, TnuaControllerHasNotPulledConfiguration>
Access to the entire basis state. This is what the basis capabilities usually use.
Sourcepub fn initiate_action_feeding(&mut self)
pub fn initiate_action_feeding(&mut self)
Must be called each frame before feeding the actions (unless action)
is never used)
Sourcepub fn action(&mut self, action: S)
pub fn action(&mut self, action: S)
Feed an action.
This is used in pull fashion - a system (or set of systems) that checks the state of the
playter input (or of some NPC controller) and can feed the action every frame its still
on. This system must start by calling
initiate_action_feeding.
For pushing actions, use one of the other action_* methods.
Sourcepub fn action_trigger(&mut self, action: S)
pub fn action_trigger(&mut self, action: S)
Trigger an action in a push fashion. The action must be one that handles its own duration.
This means that actions like TnuaBuiltinCrouch
cannot be used with this method - the character will rise after one frame of starting to
crouch. Actions like ’TnuaBuiltinDash` are okay because
the dash will only end when the motion itself is finished.
Sourcepub fn action_interrupt(&mut self, action: S)
pub fn action_interrupt(&mut self, action: S)
Similar to action_trigger, but can override other action
contenders and other action feeding methods cannot override it.
Sourcepub fn action_start(&mut self, action: S)
pub fn action_start(&mut self, action: S)
Trigger an action in a push fashion. The action will continue until
action_end is called - or until the motion itself is finished.
Sourcepub fn action_end(&mut self, action: S::ActionDiscriminant)
pub fn action_end(&mut self, action: S::ActionDiscriminant)
End an action that started with action_start
Sourcepub fn prolong_action(&mut self)
pub fn prolong_action(&mut self)
Re-feed the same action that is currently active.
This is useful when matching on current_action and wanting to
continue feeding the exact same action with the exact same input without having to
Sourcepub fn action_discriminant(&self) -> Option<S::ActionDiscriminant>
pub fn action_discriminant(&self) -> Option<S::ActionDiscriminant>
The discriminant of the currently running action.
Sourcepub fn action_flow_status(&self) -> &TnuaActionFlowStatus<S::ActionDiscriminant>
pub fn action_flow_status(&self) -> &TnuaActionFlowStatus<S::ActionDiscriminant>
Indicator for the state and flow of movement actions.
Query this every frame to keep track of the actions. For air actions,
TnuaAirActionsTracker is easier to use
(and uses this behind the scenes)
The benefits of this over querying action_discriminant every
frame are:
action_flow_statuscan indicate when the same action has been fed again immediately after stopping or cancelled into itself.action_flow_statusshows anActionEndedwhen the action is no longer fed, even if the action is still active (termination sequence)
Sourcepub fn up_direction(&self) -> Option<Dir3>
pub fn up_direction(&self) -> Option<Dir3>
Returns the direction considered as up.
Note that the up direction is based on gravity, as reported by
TnuaRigidBodyTracker::gravity, and that it’d typically be one frame behind since it
gets updated in the same system that applies the controller logic. If this is unacceptable,
consider using TnuaRigidBodyTracker::gravity directly or deducing the up direction via
different means.
Source§impl<S: TnuaScheme> TnuaController<S>where
S::Basis: TnuaBasisWithGround,
impl<S: TnuaScheme> TnuaController<S>where
S::Basis: TnuaBasisWithGround,
Sourcepub fn is_airborne(
&self,
) -> Result<bool, TnuaControllerHasNotPulledConfiguration>
pub fn is_airborne( &self, ) -> Result<bool, TnuaControllerHasNotPulledConfiguration>
Checks if the character is currently airborne.
The check is done based on the basis, and is equivalent to getting the controller’s
basis_access and using TnuaBasisWithGround::is_airborne on it.
Trait Implementations§
Source§impl<S: TnuaScheme> Component for TnuaController<S>
Required Components: TnuaMotor, TnuaRigidBodyTracker.
impl<S: TnuaScheme> Component for TnuaController<S>
Required Components: TnuaMotor, TnuaRigidBodyTracker.
A component’s Required Components are inserted whenever it is inserted. Note that this will also insert the required components of the required components, recursively, in depth-first order.
Source§const STORAGE_TYPE: StorageType = ::bevy::ecs::component::StorageType::Table
const STORAGE_TYPE: StorageType = ::bevy::ecs::component::StorageType::Table
Source§type Mutability = Mutable
type Mutability = Mutable
Component<Mutability = Mutable>,
while immutable components will instead have Component<Mutability = Immutable>. Read moreSource§fn register_required_components(
_requiree: ComponentId,
required_components: &mut RequiredComponentsRegistrator<'_, '_>,
)
fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )
Source§fn clone_behavior() -> ComponentCloneBehavior
fn clone_behavior() -> ComponentCloneBehavior
Source§fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
Source§fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
EntityMapper. This is used to remap entities in contexts like scenes and entity cloning.
When deriving Component, this is populated by annotating fields containing entities with #[entities] Read moreSource§impl<S: TnuaScheme> Default for TnuaController<S>
impl<S: TnuaScheme> Default for TnuaController<S>
Auto Trait Implementations§
impl<S> Freeze for TnuaController<S>where
<S as TnuaScheme>::Basis: Freeze,
<<S as TnuaScheme>::Basis as TnuaBasis>::Memory: Freeze,
<<S as TnuaScheme>::Basis as TnuaBasis>::Config: Freeze,
<S as TnuaScheme>::ActionDiscriminant: Freeze,
<S as TnuaScheme>::ActionState: Freeze,
S: Freeze,
impl<S> RefUnwindSafe for TnuaController<S>where
<S as TnuaScheme>::Basis: RefUnwindSafe,
<<S as TnuaScheme>::Basis as TnuaBasis>::Memory: RefUnwindSafe,
<<S as TnuaScheme>::Basis as TnuaBasis>::Config: RefUnwindSafe,
<S as TnuaScheme>::ActionDiscriminant: RefUnwindSafe,
<S as TnuaScheme>::ActionState: RefUnwindSafe,
S: RefUnwindSafe,
impl<S> Send for TnuaController<S>
impl<S> Sync for TnuaController<S>
impl<S> Unpin for TnuaController<S>where
<S as TnuaScheme>::Basis: Unpin,
<<S as TnuaScheme>::Basis as TnuaBasis>::Memory: Unpin,
<<S as TnuaScheme>::Basis as TnuaBasis>::Config: Unpin,
<S as TnuaScheme>::ActionDiscriminant: Unpin,
<S as TnuaScheme>::ActionState: Unpin,
S: Unpin,
impl<S> UnwindSafe for TnuaController<S>where
<S as TnuaScheme>::Basis: UnwindSafe,
<<S as TnuaScheme>::Basis as TnuaBasis>::Memory: UnwindSafe,
<<S as TnuaScheme>::Basis as TnuaBasis>::Config: UnwindSafe,
<S as TnuaScheme>::ActionDiscriminant: UnwindSafe,
<S as TnuaScheme>::ActionState: UnwindSafe,
S: UnwindSafe,
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T ShaderType for self. When used in AsBindGroup
derives, it is safe to assume that all images in self exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut ComponentsRegistrator<'_>, ids: &mut impl FnMut(ComponentId), )
Source§fn get_component_ids(
components: &Components,
ids: &mut impl FnMut(Option<ComponentId>),
)
fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>), )
Source§impl<C> BundleFromComponents for Cwhere
C: Component,
impl<C> BundleFromComponents for Cwhere
C: Component,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
Source§unsafe fn get_components(
ptr: MovingPtr<'_, C>,
func: &mut impl FnMut(StorageType, OwningPtr<'_>),
) -> <C as DynamicBundle>::Effect
unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect
Source§unsafe fn apply_effect(
_ptr: MovingPtr<'_, MaybeUninit<C>>,
_entity: &mut EntityWorldMut<'_>,
)
unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more