TnuaBasis

Trait TnuaBasis 

Source
pub trait TnuaBasis:
    Default
    + 'static
    + Send
    + Sync {
    type Config: Send + Sync + Clone + Serialize + for<'de> Deserialize<'de>;
    type Memory: Send + Sync + Default;
    type Sensors<'a>: TnuaSensors<'a>;

    // Required methods
    fn apply(
        &self,
        config: &Self::Config,
        memory: &mut Self::Memory,
        sensors: &Self::Sensors<'_>,
        ctx: TnuaBasisContext<'_>,
        motor: &mut TnuaMotor,
    );
    fn get_or_create_sensors<'a: 'b, 'b>(
        up_direction: Dir3,
        config: &'a Self::Config,
        memory: &Self::Memory,
        entities: &'a mut <Self::Sensors<'static> as TnuaSensors<'static>>::Entities,
        proximity_sensors_query: &'b Query<'_, '_, (&TnuaProximitySensor, Has<TnuaGhostSensor>)>,
        controller_entity: Entity,
        commands: &mut Commands<'_, '_>,
        has_ghost_overwrites: bool,
    ) -> Option<Self::Sensors<'b>>;
    fn ghost_sensor_overwrites<'a>(
        ghost_overwrites: &'a mut <Self::Sensors<'static> as TnuaSensors<'static>>::GhostOverwrites,
        entities: &<Self::Sensors<'static> as TnuaSensors<'static>>::Entities,
    ) -> impl Iterator<Item = (&'a mut TnuaGhostOverwrite, Entity)>;
}
Expand description

The main movement command of a character.

A basis handles the character’s motion when the user is not feeding it any input, or when it just moves around without doing anything special. A simple game would only need one basis - TnuaBuiltinWalk - but more complex games can have bases for things like swimming or driving.

The type that implements this trait is called the basis input, and is expected to be overwritten each frame by the controller system of the game code. Configuration is considered as part of the input. Configuration is stored in an asset, as part of a struct implementing TnuaSchemeConfig which also holds the configuration for all the actions. If the basis needs to persist data between frames it must keep it in its memory.

Required Associated Types§

Required Methods§

Source

fn apply( &self, config: &Self::Config, memory: &mut Self::Memory, sensors: &Self::Sensors<'_>, ctx: TnuaBasisContext<'_>, motor: &mut TnuaMotor, )

This is where the basis affects the character’s motion.

This method gets called each frame to let the basis control the TnuaMotor that will later move the character.

Note that after the motor is set in this method, if there is an action going on, the action’s apply will also run and typically change some of the things the basis did to the motor.

It can also update the memory.

Source

fn get_or_create_sensors<'a: 'b, 'b>( up_direction: Dir3, config: &'a Self::Config, memory: &Self::Memory, entities: &'a mut <Self::Sensors<'static> as TnuaSensors<'static>>::Entities, proximity_sensors_query: &'b Query<'_, '_, (&TnuaProximitySensor, Has<TnuaGhostSensor>)>, controller_entity: Entity, commands: &mut Commands<'_, '_>, has_ghost_overwrites: bool, ) -> Option<Self::Sensors<'b>>

This is where the basis initiates its sensors.

  • Use the helper ProximitySensorPreparationHelper to create the sensors.

  • Return None if - and only if - some essential sensors are missing, because it’ll cause the controller to skip frames until it returns Some.

    An example of non-essential sensor is the headroom sensor in TnuaBuiltinWalkSensors - the controller can function without it (it just won’t be able to do crouch enforcement) so if it’s absence does not cause prevent the controller from running (unlike the ground sensor, which is essential)

  • Even if some essential sensors are missing, make sure to prepare all the sensors that need preparation before returning None. No point preparing one sensor per frame.

  • If a sensor exists but wrongly configured - launch the command to reconfigure it and return the existing sensor. Unless the configuration is totally off (e.g. - sensor points in a very wrong direction) it’s probably better to use the misconfigured one than to skip a frame.

Source

fn ghost_sensor_overwrites<'a>( ghost_overwrites: &'a mut <Self::Sensors<'static> as TnuaSensors<'static>>::GhostOverwrites, entities: &<Self::Sensors<'static> as TnuaSensors<'static>>::Entities, ) -> impl Iterator<Item = (&'a mut TnuaGhostOverwrite, Entity)>

Iterate over each ghost overwrite and the sensor entity of the relevant sensor.

Note that not all sensors need to have ghost overwrites.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§