-
Notifications
You must be signed in to change notification settings - Fork 68
Events
The event is a concept that we use a lot in game dev, since it's a lot useful when something occurs: A character walks into a campfire and takes damage.
To implement a campfire we would use an Area and we would bind a function to the OverlapStart
event of that area: Each time a character walks in, such function is called. In Godex instead, on the Area we can specify the OverlapStart
event emitter name: in this case we would set Campfire.
We can fetch the events directly from a system, using the EventReceiver
.
GDScript
extends System
func _prepare():
with_event_receiver(ECS.OverlapStart, "Campfire") # <--- Notice
var query = DynamicQuery.new()
query.with_component(ECS.Health, MUTABLE)
with_query(query)
func _execute(campfire_overlaps, health_query):
for event in campfire_overlaps.fetch():
if health_query.has(event.other_body):
# This is a damageable Entity.
health_query.fetch(event.other_body)
health_query["Health"].health -= 10
C++
void process_campfire_damage(EventReceiver<OverlapStart, EMITTER(Campfire)> &p_campfire_overlaps, Query<Health> &p_health_query){
for(const OverlapStart* overlap : p_campfire_overlaps) {
if (p_health_query.has(everlaps.other_body)) {
// This is a damageable Entity.
auto [health] = p_health_query[everlaps.other_body];
health.health -= 10;
}
}
}
Let's suppose you need to add the Death event, emitted when the character reaches 0 health.
First, you need to create the event, and you can use the following code:
GDScript
[WIP]
C++
struct DeathEvent {
EVENT(DeathEvent)
EntityID character;
};
📝 Notice: In C++ you need to register the event using:
ECS::register_event<DeathEvent>();
. Usually this line goes inside register_types.cpp of your module.
Now it's time to emit this event, and you can do it using the following code:
GDScript
extends System
func _prepare():
with_event_emitter(ECS.DeathEvent)
var query = DynamicQuery.new()
query.with_component(ECS.Health, IMMUTABLE)
with_query(query)
func _execute(death_event_emitter, query):
while query.next():
if query["Health"].health <= 0:
death_event_emitter.emit("All", {'character': query.get_current_entity()})
C++
void detect_death(EventEmitter<DeathEvent> &p_death_event_emitter, Query<EntityID, Health> &p_query) {
for( auto [entity, health] : p_query ) {
if (health.health <= 0){
p_death_event_emitter.emit("All", DeathEvent(entity));
}
}
}
In Godex, the events are emitted by the EventEmitter
and received by the EventReceiver
. Those can be used directly by a system, to emit or receive events.
Thanks to this concept, it's much simpler code event base mechanisms, but still in full ECS style!
Community & Support
- Open an issue
- Join the Discord Community
- Start a new discussion
- Home
- Getting Started
- Concepts
- Godot & Godex communication
- Godex Importer
- Bullet Physics Engine
- Classes
Support
Useful links