bevy_event_chain
| bevy | bevy_event_chain |
|---|---|
| 0.17 | 0.1 |
| 0.18 | 0.2 |
Easy trait-like behavior using observers and relations.
Relationship targets ("parents") initiate a chain of events that go one-by-one through their relationships ("children") before returning to the target. This is useful for acting as one mutable event, like equipment progressively modifying stats of attacks when they happen.
Sample
pub use *;
pub use *;
;
;
;
;
Usage
[ChainEvent]
The basic, manual version of the event chain.
Derive [ChainEvent] (and Clone)
on an event. It impls Event and EntityEvent. Similarly to
EntityEvent, it needs a field of type [EventChain]
that is either named chain or has the #[event_target] attribute.
Also similarly to EntityEvent, it uses EntityTrigger,
but this can be changed with #[chain_event(trigger = ...)].
The [EventChain] is constructed from a Vec<Entity> representing the entities in the order to send the event to,
or optionally with new_with_end which just appends another entity (typically the parent or relationship target
between them) to the end of the list.
Spawn your entities, usually using a relationship.
let parent = commands.spawn_empty.id;
let child = commands.spawn.id;
Observe the chain event on each of the entities. Each entity should trigger ChainEvent::next(&self) -> Self to pass the event forward.
commands.entity.observe;
Finally, consume the event with the last entity if need be.
commands.entity.observe;
You can now trigger events!
let related = relationships
.get?
.collection
.clone;
commands.trigger;
[RelatedChainEvent]
The version of the event chain that's way easier to use, using relationships.
Start by creating your relationship as normal.
;
;
Derive [RelatedChainEvent] (and Clone) on an event. It impls Event and
EntityEvent. Similarly to EntityEvent,
it needs a field of type [RelatedEventChain] that is either named chain or has the #[event_target] attribute.
The relationship must be specified in the #[related_chain_event] attribute, using either relationship_target = ...
or relationship = ... or both. (Personally, I think relationship_target = Children looks better than relationship = ChildOf.)
The event uses EntityComponentTrigger
(NOT EntityComponentsTrigger) and can't be changed.
The RelatedEventChain is constructed by requesting [ChainEventRelation<MyEvent>] as a SystemParam
and calling ChainEventRelation::new_chain(relationship_target: Entity).
Spawn your entities and their relationship.
let parent = commands.spawn_empty.id;
let child = commands.spawn.id;
Observe the chain event on each of the entities. Each entity should trigger RelatedChainEvent::next(&self) -> Self
and, from the next event, RelatedChainEvent::get_trigger(&self) -> EntityComponentTrigger to pass the event forward.
For simplicity, you can also use RelatedChainEvent::trigger(self, commands: &mut Commands) from the next event or
RelatedChainEvent::trigger_next(&self, commands: &mut Commands) (which just triggers
next() and next.get_trigger())
from the source event.
commands.entity.observe;
Finally, consume the event with the relationship target if need be.
commands.entity.observe;
Also for simplicity, the relationship type and its target type are passed into the event trigger
(hence the EntityComponentTrigger),
so you can specify a type into the On to use a global observer instead. This is useful for globally consuming the final output of
an event, or for using a global observer to pass along an event that should always be passed along and shouldn't be mutated (eg. if it
only contains entity references but not their mutable components), so you don't have to worry about passing it along in each of the
entity observers.
app.add_observer;
You can now trigger events!