trigger system
This commit is contained in:
@@ -10,6 +10,7 @@ pub mod noclip;
|
||||
pub mod physics;
|
||||
pub mod rotate;
|
||||
pub mod tree_instances;
|
||||
pub mod trigger;
|
||||
|
||||
pub use camera::CameraComponent;
|
||||
pub use dissolve::DissolveComponent;
|
||||
@@ -21,3 +22,4 @@ pub use movement::MovementComponent;
|
||||
pub use physics::PhysicsComponent;
|
||||
pub use rotate::RotateComponent;
|
||||
pub use tree_instances::TreeInstancesComponent;
|
||||
pub use trigger::{TriggerComponent, TriggerEvent, TriggerEventKind, TriggerFilter, TriggerShape, TriggerState};
|
||||
|
||||
37
src/components/trigger.rs
Normal file
37
src/components/trigger.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use crate::entity::EntityHandle;
|
||||
|
||||
pub enum TriggerShape
|
||||
{
|
||||
Sphere { radius: f32 },
|
||||
}
|
||||
|
||||
pub enum TriggerFilter
|
||||
{
|
||||
Player,
|
||||
}
|
||||
|
||||
pub enum TriggerState
|
||||
{
|
||||
Idle,
|
||||
Inside,
|
||||
}
|
||||
|
||||
pub struct TriggerComponent
|
||||
{
|
||||
pub shape: TriggerShape,
|
||||
pub filter: TriggerFilter,
|
||||
pub state: TriggerState,
|
||||
}
|
||||
|
||||
pub enum TriggerEventKind
|
||||
{
|
||||
Entered,
|
||||
Exited,
|
||||
}
|
||||
|
||||
pub struct TriggerEvent
|
||||
{
|
||||
pub trigger_entity: EntityHandle,
|
||||
pub activator_entity: EntityHandle,
|
||||
pub kind: TriggerEventKind,
|
||||
}
|
||||
@@ -41,6 +41,7 @@ use crate::systems::{
|
||||
camera_follow_system, camera_input_system, camera_view_matrix, physics_sync_system,
|
||||
player_input_system, render_system, rotate_system, snow_system, spotlight_sync_system,
|
||||
start_camera_following, state_machine_physics_system, state_machine_system,
|
||||
trigger_system,
|
||||
};
|
||||
use crate::systems::camera::stop_camera_following;
|
||||
use crate::utility::time::Time;
|
||||
@@ -283,6 +284,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
||||
PhysicsManager::physics_step();
|
||||
|
||||
physics_sync_system(&mut world);
|
||||
trigger_system(&mut world);
|
||||
|
||||
physics_accumulator -= FIXED_TIMESTEP;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ pub mod snow;
|
||||
pub mod spotlight_sync;
|
||||
pub mod state_machine;
|
||||
pub mod tree_dissolve;
|
||||
pub mod trigger;
|
||||
|
||||
pub use camera::{
|
||||
camera_follow_system, camera_input_system, camera_noclip_system, camera_view_matrix,
|
||||
@@ -21,3 +22,7 @@ pub use rotate::rotate_system;
|
||||
pub use snow::snow_system;
|
||||
pub use spotlight_sync::spotlight_sync_system;
|
||||
pub use state_machine::{state_machine_physics_system, state_machine_system};
|
||||
pub use tree_dissolve::{
|
||||
tree_dissolve_update_system, tree_instance_buffer_update_system, tree_occlusion_system,
|
||||
};
|
||||
pub use trigger::trigger_system;
|
||||
|
||||
82
src/systems/trigger.rs
Normal file
82
src/systems/trigger.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::components::trigger::{TriggerEvent, TriggerEventKind, TriggerFilter, TriggerShape, TriggerState};
|
||||
use crate::entity::EntityHandle;
|
||||
use crate::world::World;
|
||||
|
||||
pub fn trigger_system(world: &mut World)
|
||||
{
|
||||
world.trigger_events.clear();
|
||||
|
||||
let trigger_entities: Vec<EntityHandle> = world.triggers.all();
|
||||
let mut pending_events: Vec<TriggerEvent> = Vec::new();
|
||||
|
||||
for trigger_entity in trigger_entities
|
||||
{
|
||||
let trigger_pos = match world.transforms.get(trigger_entity)
|
||||
{
|
||||
Some(t) => t.position,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let candidate_entities: Vec<EntityHandle> = match world.triggers.get(trigger_entity)
|
||||
{
|
||||
Some(trigger) => match &trigger.filter
|
||||
{
|
||||
TriggerFilter::Player => world.player_tags.all(),
|
||||
},
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let activator_positions: Vec<(EntityHandle, Vec3)> = candidate_entities
|
||||
.into_iter()
|
||||
.filter_map(|e| world.transforms.get(e).map(|t| (e, t.position)))
|
||||
.collect();
|
||||
|
||||
let overlapping = match world.triggers.get(trigger_entity)
|
||||
{
|
||||
Some(trigger) => activator_positions.iter().any(|(_, pos)| match &trigger.shape
|
||||
{
|
||||
TriggerShape::Sphere { radius } => (trigger_pos - *pos).length() < *radius,
|
||||
}),
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let first_activator = activator_positions.first().map(|(e, _)| *e);
|
||||
|
||||
if let Some(trigger) = world.triggers.get_mut(trigger_entity)
|
||||
{
|
||||
match (&trigger.state, overlapping)
|
||||
{
|
||||
(TriggerState::Idle, true) =>
|
||||
{
|
||||
trigger.state = TriggerState::Inside;
|
||||
if let Some(activator_entity) = first_activator
|
||||
{
|
||||
pending_events.push(TriggerEvent {
|
||||
trigger_entity,
|
||||
activator_entity,
|
||||
kind: TriggerEventKind::Entered,
|
||||
});
|
||||
}
|
||||
}
|
||||
(TriggerState::Inside, false) =>
|
||||
{
|
||||
trigger.state = TriggerState::Idle;
|
||||
if let Some(activator_entity) = first_activator
|
||||
{
|
||||
pending_events.push(TriggerEvent {
|
||||
trigger_entity,
|
||||
activator_entity,
|
||||
kind: TriggerEventKind::Exited,
|
||||
});
|
||||
}
|
||||
}
|
||||
_ =>
|
||||
{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
world.trigger_events.extend(pending_events);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ use crate::components::dissolve::DissolveComponent;
|
||||
use crate::components::follow::FollowComponent;
|
||||
use crate::components::lights::spot::SpotlightComponent;
|
||||
use crate::components::tree_instances::TreeInstancesComponent;
|
||||
use crate::components::trigger::{TriggerComponent, TriggerEvent};
|
||||
use crate::components::{
|
||||
CameraComponent, InputComponent, JumpComponent, MeshComponent, MovementComponent,
|
||||
PhysicsComponent, RotateComponent,
|
||||
@@ -86,6 +87,8 @@ pub struct World
|
||||
pub rotates: Storage<RotateComponent>,
|
||||
pub tree_instances: Storage<TreeInstancesComponent>,
|
||||
pub names: Storage<String>,
|
||||
pub triggers: Storage<TriggerComponent>,
|
||||
pub trigger_events: Vec<TriggerEvent>,
|
||||
}
|
||||
|
||||
impl World
|
||||
@@ -110,6 +113,8 @@ impl World
|
||||
rotates: Storage::new(),
|
||||
tree_instances: Storage::new(),
|
||||
names: Storage::new(),
|
||||
triggers: Storage::new(),
|
||||
trigger_events: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +141,7 @@ impl World
|
||||
self.rotates.remove(entity);
|
||||
self.tree_instances.remove(entity);
|
||||
self.names.remove(entity);
|
||||
self.triggers.remove(entity);
|
||||
self.entities.despawn(entity);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user