support cutscene camera

This commit is contained in:
2025-03-13 23:50:39 +01:00
parent 7281a46521
commit f8207f69b3
6 changed files with 83 additions and 1 deletions

View File

@@ -906,3 +906,10 @@
"angles" "0 90 0"
"head" "green grocer"
}
// entity 25
{
"classname" "cutscene_camera"
"origin" "-56 -648 248"
"angles" "0 45 0"
"name" "fence_01"
}

60
src/cutscene.rs Normal file
View File

@@ -0,0 +1,60 @@
use crate::{DebugVisuals, tb_entities::CutsceneCamera};
use bevy::prelude::*;
#[derive(Event, Debug)]
pub struct StartCutscene(pub String);
#[derive(Resource, Debug, Default)]
enum CutsceneState {
#[default]
None,
Playing {
timer: Timer,
},
}
pub fn plugin(app: &mut App) {
app.init_resource::<CutsceneState>();
app.add_systems(Update, update);
app.add_observer(on_start_cutscene);
}
fn on_start_cutscene(
trigger: Trigger<StartCutscene>,
cutscenes: Query<(&Transform, &CutsceneCamera), Without<Camera>>,
mut res: ResMut<DebugVisuals>,
mut cutscene_state: ResMut<CutsceneState>,
mut cam: Query<&mut Transform, With<Camera>>,
) {
let cutscene = trigger.event().0.clone();
let Some((t, _)) = cutscenes
.iter()
.find(|(_, cutscene_camera)| cutscene == cutscene_camera.name)
else {
return;
};
res.cam_follow = false;
*cam.single_mut() = *t;
*cutscene_state = CutsceneState::Playing {
timer: Timer::from_seconds(2.0, TimerMode::Once),
};
}
fn update(
mut res: ResMut<DebugVisuals>,
mut cutscene_state: ResMut<CutsceneState>,
time: Res<Time>,
) {
if let CutsceneState::Playing { timer, .. } = &mut *cutscene_state {
timer.tick(time.delta());
if timer.finished() {
res.cam_follow = true;
*cutscene_state = CutsceneState::None;
}
}
}

View File

@@ -1,4 +1,4 @@
use crate::{keys::KeyCollected, movables::TriggerMovableEvent};
use crate::{cutscene::StartCutscene, keys::KeyCollected, movables::TriggerMovableEvent};
use bevy::{prelude::*, utils::hashbrown::HashSet};
#[derive(Resource)]
@@ -20,6 +20,7 @@ fn on_key(
) {
if matches!(*state, GatesState::Init) {
*state = GatesState::GateOpen1;
commands.trigger(StartCutscene("fence_01".to_string()));
//TODO: put into a sound effects system
commands.spawn((

View File

@@ -3,6 +3,7 @@ mod alien;
mod billboards;
mod camera;
mod cash;
mod cutscene;
mod gates;
mod heads_ui;
mod keys;
@@ -86,6 +87,7 @@ fn main() {
app.add_plugins(npc::plugin);
app.add_plugins(keys::plugin);
app.add_plugins(squish_animation::plugin);
app.add_plugins(cutscene::plugin);
app.insert_resource(AmbientLight {
color: Color::WHITE,

View File

@@ -78,6 +78,13 @@ pub struct MoveTarget {
pub targetname: String,
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]
pub struct CutsceneCamera {
pub name: String,
}
#[derive(PointClass, Component, Reflect, Default)]
#[reflect(Component)]
#[require(Transform)]

View File

@@ -64,6 +64,11 @@
[
]
@PointClass base(transform) = cutscene_camera
[
name(string) : "name" : "" : ""
]
@PointClass base(transform) model({ "path": "models/alien_naked.glb" }) = enemy_spawn
[
head(string) : "head" : "" : ""