gate open animation using new movables
This commit is contained in:
25
src/gates.rs
25
src/gates.rs
@@ -1,9 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use avian3d::math::PI;
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::tb_entities::NamedEntity;
|
||||
use crate::movables::TriggerMovableEvent;
|
||||
use bevy::{prelude::*, utils::hashbrown::HashSet};
|
||||
|
||||
#[derive(Resource)]
|
||||
enum GatesState {
|
||||
@@ -20,7 +16,6 @@ fn update(
|
||||
mut commands: Commands,
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
mut state: ResMut<GatesState>,
|
||||
mut names_entities: Query<(&NamedEntity, &mut Transform)>,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
if keyboard.just_pressed(KeyCode::Digit1) {
|
||||
@@ -38,18 +33,12 @@ fn update(
|
||||
PlaybackSettings::DESPAWN,
|
||||
));
|
||||
|
||||
let fences: HashMap<_, _> = vec![
|
||||
("fence_01", Quat::from_rotation_y(PI / -2.)),
|
||||
("fence_02", Quat::from_rotation_y(PI / 2.)),
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let entities: HashSet<_> = vec!["fence_01", "fence_02"]
|
||||
.into_iter()
|
||||
.map(|s| String::from(s))
|
||||
.collect();
|
||||
|
||||
for (named_entity, mut transform) in names_entities.iter_mut() {
|
||||
if let Some(fence) = fences.get(named_entity.name.as_str()) {
|
||||
transform.rotate(*fence);
|
||||
}
|
||||
}
|
||||
commands.trigger(TriggerMovableEvent(entities));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ mod camera;
|
||||
mod cash;
|
||||
mod gates;
|
||||
mod heads_ui;
|
||||
mod movables;
|
||||
mod platforms;
|
||||
mod player;
|
||||
mod tb_entities;
|
||||
@@ -70,6 +71,7 @@ fn main() {
|
||||
app.add_plugins(heads_ui::plugin);
|
||||
app.add_plugins(gates::plugin);
|
||||
app.add_plugins(platforms::plugin);
|
||||
app.add_plugins(movables::plugin);
|
||||
|
||||
app.insert_resource(AmbientLight {
|
||||
color: Color::WHITE,
|
||||
|
||||
83
src/movables.rs
Normal file
83
src/movables.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use crate::tb_entities::{Movable, MoveTarget};
|
||||
use bevy::{prelude::*, utils::HashSet};
|
||||
use bevy_trenchbroom::class::Target;
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct ActiveMovable {
|
||||
pub start: Transform,
|
||||
pub target: Transform,
|
||||
pub start_time: f32,
|
||||
pub duration: f32,
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct TriggerMovableEvent(pub HashSet<String>);
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.register_type::<ActiveMovable>();
|
||||
app.add_systems(Update, move_active);
|
||||
app.add_observer(trigger);
|
||||
}
|
||||
|
||||
fn trigger(
|
||||
trigger: Trigger<TriggerMovableEvent>,
|
||||
mut commands: Commands,
|
||||
uninit_movables: Query<
|
||||
(Entity, &Target, &Transform, &Movable),
|
||||
(Without<ActiveMovable>, With<Movable>),
|
||||
>,
|
||||
targets: Query<(&MoveTarget, &Transform)>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
info!("trigger: {:?}", trigger.0);
|
||||
|
||||
for (e, target, transform, movable) in uninit_movables.iter() {
|
||||
if !trigger.0.contains(&movable.name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let target_name = target.target.clone().unwrap_or_default();
|
||||
|
||||
let Some(target) = targets
|
||||
.iter()
|
||||
.find(|(t, _)| t.targetname == target_name)
|
||||
.map(|(_, t)| *t)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
info!("found target: {:?}", target_name);
|
||||
|
||||
let target: Transform =
|
||||
Transform::from_translation(transform.translation).with_rotation(target.rotation);
|
||||
|
||||
let platform = ActiveMovable {
|
||||
start: *transform,
|
||||
target,
|
||||
start_time: time.elapsed_secs(),
|
||||
//TODO: make this configurable
|
||||
duration: 1.,
|
||||
};
|
||||
|
||||
commands.entity(e).insert(platform);
|
||||
}
|
||||
}
|
||||
|
||||
fn move_active(
|
||||
mut commands: Commands,
|
||||
mut platforms: Query<(Entity, &mut Transform, &mut ActiveMovable)>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let elapsed = time.elapsed_secs();
|
||||
for (e, mut transform, active) in platforms.iter_mut() {
|
||||
if elapsed < active.start_time + active.duration {
|
||||
let t = (elapsed - active.start_time) / active.duration;
|
||||
transform.rotation = active.start.rotation.lerp(active.target.rotation, t);
|
||||
} else {
|
||||
*transform = active.target;
|
||||
|
||||
commands.entity(e).remove::<(ActiveMovable, Movable)>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,21 @@ pub struct PlatformTarget {
|
||||
pub targetname: String,
|
||||
}
|
||||
|
||||
#[derive(SolidClass, Component, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
#[require(Transform, Target)]
|
||||
#[geometry(GeometryProvider::new().trimesh_collider().render())]
|
||||
pub struct Movable {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(PointClass, Component, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
#[require(Transform)]
|
||||
pub struct MoveTarget {
|
||||
pub targetname: String,
|
||||
}
|
||||
|
||||
#[derive(PointClass, Component, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
#[require(Transform)]
|
||||
|
||||
Reference in New Issue
Block a user