use observable collision events
to simplify key/head_drop collecting
This commit is contained in:
@@ -4,7 +4,10 @@ use crate::{
|
||||
squish_animation::SquishAnimation, tb_entities::SecretHead,
|
||||
};
|
||||
use avian3d::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
use bevy::{
|
||||
ecs::{relationship::RelatedSpawner, spawn::SpawnWith},
|
||||
prelude::*,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
#[derive(Event, Reflect)]
|
||||
@@ -44,7 +47,6 @@ struct SecretHeadMarker;
|
||||
pub struct HeadCollected(pub usize);
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.add_systems(Update, collect_head.run_if(in_state(GameState::Playing)));
|
||||
app.add_systems(OnEnter(GameState::Playing), spawn);
|
||||
|
||||
global_observer!(app, on_head_drop);
|
||||
@@ -85,6 +87,8 @@ fn on_head_drop(
|
||||
}
|
||||
.ok_or("asset not found")?;
|
||||
|
||||
let head_id = drop.head_id;
|
||||
|
||||
commands
|
||||
.spawn((
|
||||
Name::new("headdrop"),
|
||||
@@ -97,15 +101,18 @@ fn on_head_drop(
|
||||
GameLayer::CollectiblePhysics,
|
||||
LayerMask::ALL & !GameLayer::Player.to_bits(),
|
||||
),
|
||||
CollisionEventsEnabled,
|
||||
Restitution::new(0.6),
|
||||
children![(
|
||||
Collider::sphere(1.5),
|
||||
CollisionLayers::new(GameLayer::CollectibleSensors, GameLayer::Player),
|
||||
Sensor,
|
||||
CollisionEventsEnabled,
|
||||
HeadDrop(drop.head_id),
|
||||
)],
|
||||
Children::spawn(SpawnWith(move |parent: &mut RelatedSpawner<ChildOf>| {
|
||||
parent
|
||||
.spawn((
|
||||
Collider::sphere(1.5),
|
||||
CollisionLayers::new(GameLayer::CollectibleSensors, GameLayer::Player),
|
||||
Sensor,
|
||||
CollisionEventsEnabled,
|
||||
HeadDrop(head_id),
|
||||
))
|
||||
.observe(on_collect_head);
|
||||
})),
|
||||
))
|
||||
.insert_if(
|
||||
ExternalImpulse::new(spawn_dir * 180.).with_persistence(false),
|
||||
@@ -120,23 +127,18 @@ fn on_head_drop(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_head(
|
||||
fn on_collect_head(
|
||||
trigger: Trigger<OnCollisionStart>,
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
query_player: Query<&Player>,
|
||||
query_collectable: Query<(&HeadDrop, &ChildOf)>,
|
||||
query_secret: Query<&SecretHeadMarker>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
let collectable = if query_player.contains(*e1) && query_collectable.contains(*e2) {
|
||||
*e2
|
||||
} else if query_player.contains(*e2) && query_collectable.contains(*e1) {
|
||||
*e1
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let collectable = trigger.target();
|
||||
let collider = trigger.collider;
|
||||
|
||||
let (key, child_of) = query_collectable.get(collectable).unwrap();
|
||||
if query_player.contains(collider) {
|
||||
let (drop, child_of) = query_collectable.get(collectable).unwrap();
|
||||
|
||||
let is_secret = query_secret.contains(collectable);
|
||||
|
||||
@@ -145,7 +147,8 @@ fn collect_head(
|
||||
} else {
|
||||
commands.trigger(PlaySound::HeadCollect);
|
||||
}
|
||||
commands.trigger(HeadCollected(key.0));
|
||||
|
||||
commands.trigger(HeadCollected(drop.0));
|
||||
commands.entity(child_of.parent()).despawn();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user