implement preferred looking direction for NPCs

This commit is contained in:
yuni 2024-05-23 00:31:31 +02:00
parent 8a07e9cfb7
commit 91d19e94a0
4 changed files with 43 additions and 0 deletions

View file

@ -32,6 +32,7 @@ impl Plugin for ActorPlugin {
update_power,
handle_wants_maxrotation,
handle_wants_maxvelocity,
handle_wants_lookat,
),
);
app.add_systems(
@ -153,6 +154,8 @@ pub struct WantsMaxRotation(pub f64);
#[derive(Component)]
pub struct WantsMaxVelocity(pub f64);
#[derive(Component)]
pub struct WantsToLookAt(pub String);
#[derive(Component)]
pub struct Identifier(pub String);
#[derive(Component)]
@ -556,6 +559,22 @@ fn handle_wants_maxvelocity(
}
}
fn handle_wants_lookat(
mut query: Query<(
&Position,
&mut Rotation,
&mut ExternalTorque,
&WantsToLookAt,
)>,
id2pos: Res<game::Id2Pos>,
) {
for (pos, mut rot, mut _torque, target_id) in &mut query {
if let Some(target_pos) = id2pos.0.get(&target_id.0) {
rot.0 = look_at_quat(**pos, *target_pos, DVec3::Y);
}
}
}
fn handle_damage(
mut ew_playerdies: EventWriter<game::PlayerDiesEvent>,
mut q_hp: Query<(&mut HitPoints, Option<&Player>), Changed<HitPoints>>,

View file

@ -84,6 +84,7 @@ struct ParserState {
has_ring: bool,
wants_maxrotation: Option<f64>,
wants_maxvelocity: Option<f64>,
wants_tolookat_id: Option<String>,
collider_is_mesh: bool,
collider_is_one_mesh_of_scene: bool,
thrust_forward: f32,
@ -140,6 +141,7 @@ impl Default for ParserState {
has_ring: false,
wants_maxrotation: None,
wants_maxvelocity: None,
wants_tolookat_id: None,
collider_is_mesh: false,
collider_is_one_mesh_of_scene: false,
thrust_forward: default_engine.thrust_forward,
@ -503,6 +505,10 @@ pub fn load_defs(mut ew_spawn: EventWriter<SpawnEvent>) {
continue;
}
}
["wants", "lookat", id] => {
// NOTE: Will not work if the actor has no engine
state.wants_tolookat_id = Some(id.to_string());
}
["armodel", asset_name] => {
state.ar_model = Some(asset_name.to_string());
}
@ -714,6 +720,9 @@ fn spawn_entities(
if let Some(value) = state.wants_maxvelocity {
actor.insert(actor::WantsMaxVelocity(value));
}
if let Some(value) = &state.wants_tolookat_id {
actor.insert(actor::WantsToLookAt(value.clone()));
}
if let Some(color) = state.light_color {
actor.insert((
PointLight {

View file

@ -107,3 +107,13 @@ pub fn in_shadow(
return closest_vector.length() < max_distance;
}
pub fn look_at_quat(from: DVec3, to: DVec3, up: DVec3) -> DQuat {
let direction = (to - from).normalize();
let right = up.cross(direction).normalize();
let corrected_up = direction.cross(right);
let mat3 = bevy::math::DMat3::from_cols(right, corrected_up, direction);
DQuat::from_mat3(&mat3)
}

View file

@ -459,6 +459,7 @@ actor -3300 10 0 pizzeria
angularmomentum 0 0 0
wants maxrotation 0
wants maxvelocity 0
wants lookat player
thrust 15 6 3 400 0.5
rotationy -126
scale 3
@ -475,6 +476,7 @@ actor -3300 10 0 pizzeria
thrust 1.2 1 1 20 1.5
wants maxrotation 0
wants maxvelocity 0
wants lookat player
rotationy -90
angularmomentum 0 0 0
pronoun he
@ -533,6 +535,7 @@ actor 100 -18000 2000 clippy
angularmomentum 0 0 0
wants maxrotation 0
wants maxvelocity 0
wants lookat player
thrust 15 6 3 400 0.5
pointofinterest yes
rotationy -90
@ -684,6 +687,7 @@ actor -184971e3 149410e3 -134273e3 clippy
angularmomentum 0 0 0
wants maxrotation 0
wants maxvelocity 0
wants lookat player
thrust 15 6 3 400 0.5
pointofinterest yes
rotationy -90
@ -828,6 +832,7 @@ actor 0 -44e3 0 clippy
angularmomentum 0 0 0
wants maxrotation 0
wants maxvelocity 0
wants lookat player
thrust 15 6 3 400 0.5
pointofinterest yes
rotationy -90