Compare commits
22 commits
c618c0e1c1
...
0f33b6e88e
Author | SHA1 | Date | |
---|---|---|---|
yuni | 0f33b6e88e | ||
yuni | 04825f467d | ||
yuni | 14991879c9 | ||
yuni | d4c8ca231a | ||
yuni | 0ea4c00151 | ||
yuni | bb95469f44 | ||
yuni | 35d9f0b4fd | ||
yuni | 6a82c185f2 | ||
yuni | a3f1f4bd73 | ||
yuni | 3a7ab8c9ac | ||
yuni | 2e35f90a19 | ||
yuni | 3cef44c4b2 | ||
yuni | 51059a2856 | ||
yuni | 86999574d1 | ||
yuni | 8fcb702623 | ||
yuni | 94bf21b340 | ||
yuni | 06c2d90228 | ||
yuni | e8e81e8e52 | ||
yuni | 8ea2d1fb21 | ||
yuni | d329d35396 | ||
yuni | 3ffcfcf522 | ||
yuni | 495a45d8c4 |
Binary file not shown.
|
@ -45,6 +45,20 @@
|
|||
"metallicFactor":0.5158730149269104,
|
||||
"roughnessFactor":0.841269850730896
|
||||
}
|
||||
},
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Black",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.016740795224905014,
|
||||
0.016740795224905014,
|
||||
0.016740795224905014,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0.8086956739425659,
|
||||
"roughnessFactor":0.917391300201416
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
|
@ -59,6 +73,15 @@
|
|||
},
|
||||
"indices":3,
|
||||
"material":0
|
||||
},
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":4,
|
||||
"NORMAL":5,
|
||||
"TEXCOORD_0":6
|
||||
},
|
||||
"indices":7,
|
||||
"material":1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -80,15 +103,15 @@
|
|||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":2761,
|
||||
"count":1826,
|
||||
"max":[
|
||||
0.44324639439582825,
|
||||
0.14108650386333466,
|
||||
0.4957937002182007
|
||||
0.4851364195346832
|
||||
],
|
||||
"min":[
|
||||
-0.44725117087364197,
|
||||
-0.3539474904537201,
|
||||
-0.34535348415374756,
|
||||
-0.2795291841030121
|
||||
],
|
||||
"type":"VEC3"
|
||||
|
@ -96,45 +119,103 @@
|
|||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":2761,
|
||||
"count":1826,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5126,
|
||||
"count":2761,
|
||||
"count":1826,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"componentType":5123,
|
||||
"count":15360,
|
||||
"count":9984,
|
||||
"type":"SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView":4,
|
||||
"componentType":5126,
|
||||
"count":939,
|
||||
"max":[
|
||||
0.44324639439582825,
|
||||
0.08284013718366623,
|
||||
0.4957937002182007
|
||||
],
|
||||
"min":[
|
||||
-0.44700509309768677,
|
||||
-0.3539474904537201,
|
||||
-0.20792187750339508
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":5,
|
||||
"componentType":5126,
|
||||
"count":939,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":6,
|
||||
"componentType":5126,
|
||||
"count":939,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":7,
|
||||
"componentType":5123,
|
||||
"count":5376,
|
||||
"type":"SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":33132,
|
||||
"byteLength":21912,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":33132,
|
||||
"byteOffset":33132,
|
||||
"byteLength":21912,
|
||||
"byteOffset":21912,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":22088,
|
||||
"byteOffset":66264,
|
||||
"byteLength":14608,
|
||||
"byteOffset":43824,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":30720,
|
||||
"byteOffset":88352,
|
||||
"byteLength":19968,
|
||||
"byteOffset":58432,
|
||||
"target":34963
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":11268,
|
||||
"byteOffset":78400,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":11268,
|
||||
"byteOffset":89668,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":7512,
|
||||
"byteOffset":100936,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":10752,
|
||||
"byteOffset":108448,
|
||||
"target":34963
|
||||
}
|
||||
],
|
||||
|
@ -146,7 +227,7 @@
|
|||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":119072,
|
||||
"byteLength":119200,
|
||||
"uri":"ar_skirt_tartan.bin"
|
||||
}
|
||||
]
|
||||
|
|
293
src/actor.rs
293
src/actor.rs
|
@ -17,6 +17,7 @@
|
|||
use crate::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
use bevy_xpbd_3d::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub const ENGINE_SPEED_FACTOR: f32 = 30.0;
|
||||
const MAX_TRANSMISSION_DISTANCE: f32 = 100.0;
|
||||
|
@ -38,6 +39,7 @@ impl Plugin for ActorPlugin {
|
|||
update_physics_lifeforms.run_if(game_running),
|
||||
update_power.run_if(game_running),
|
||||
handle_gravity.run_if(game_running),
|
||||
handle_wants_rotation_change.run_if(game_running),
|
||||
handle_wants_maxrotation.run_if(game_running),
|
||||
handle_wants_maxvelocity
|
||||
.run_if(game_running)
|
||||
|
@ -45,12 +47,23 @@ impl Plugin for ActorPlugin {
|
|||
handle_wants_lookat.run_if(game_running).run_if(alive),
|
||||
),
|
||||
);
|
||||
app.add_systems(
|
||||
PreUpdate,
|
||||
handle_wants_acceleration
|
||||
.run_if(game_running)
|
||||
.run_if(alive)
|
||||
.after(PhysicsSet::Sync)
|
||||
.after(sync::position_to_transform),
|
||||
);
|
||||
|
||||
app.add_systems(
|
||||
PostUpdate,
|
||||
handle_gforce
|
||||
.run_if(game_running)
|
||||
.run_if(alive)
|
||||
.after(PhysicsSet::Sync)
|
||||
.after(sync::position_to_transform),
|
||||
.after(sync::position_to_transform)
|
||||
.after(handle_wants_acceleration),
|
||||
);
|
||||
app.add_systems(
|
||||
Update,
|
||||
|
@ -149,6 +162,12 @@ impl Default for ExperiencesGForce {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct WantsAcceleration {
|
||||
pub direction: DVec3,
|
||||
pub brake: bool,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Player; // Attached to the suit of the player
|
||||
#[derive(Component)]
|
||||
|
@ -164,6 +183,8 @@ pub struct ActorEnteringVehicle;
|
|||
#[derive(Component)]
|
||||
pub struct ActorVehicleBeingEntered;
|
||||
#[derive(Component)]
|
||||
pub struct HiddenInsideVehicle;
|
||||
#[derive(Component)]
|
||||
pub struct MessageOnVehicleEntry(pub String);
|
||||
#[derive(Component)]
|
||||
pub struct PlayersFlashLight;
|
||||
|
@ -176,6 +197,8 @@ pub struct WantsMaxVelocity(pub f64);
|
|||
#[derive(Component)]
|
||||
pub struct WantsToLookAt(pub String);
|
||||
#[derive(Component)]
|
||||
pub struct WantsRotationChange(pub Vec3); // Vec3 = (pitch, yaw, rot)
|
||||
#[derive(Component)]
|
||||
pub struct WantsMatchVelocityWith(pub String);
|
||||
#[derive(Component)]
|
||||
pub struct Identifier(pub String);
|
||||
|
@ -220,7 +243,7 @@ pub enum EngineType {
|
|||
Ion,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
#[derive(Component, Copy, Clone)]
|
||||
pub struct Engine {
|
||||
pub thrust_forward: f32,
|
||||
pub thrust_back: f32,
|
||||
|
@ -575,11 +598,18 @@ pub fn handle_vehicle_enter_exit(
|
|||
*driver_vis = Visibility::Hidden; //seems to have no effect...
|
||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::EnterVehicle));
|
||||
commands.entity(driver).remove::<PlayerCamera>();
|
||||
commands.entity(driver).remove::<WantsRotationChange>();
|
||||
commands.entity(driver).remove::<Collider>();
|
||||
commands.entity(driver).remove::<WantsAcceleration>();
|
||||
commands.entity(driver).insert(JustNowEnteredVehicle);
|
||||
commands.entity(driver).insert(HiddenInsideVehicle);
|
||||
commands
|
||||
.entity(vehicle)
|
||||
.insert(WantsAcceleration::default());
|
||||
commands.entity(vehicle).remove::<hud::IsTargeted>();
|
||||
commands.entity(vehicle).insert(PlayerCamera);
|
||||
commands.entity(vehicle).insert(PlayerDrivesThis);
|
||||
commands.entity(vehicle).insert(WantsMaxRotation(0.0));
|
||||
if let Ok(mut flashlight_trans) = q_playerflashlight.get_single_mut() {
|
||||
flashlight_trans.rotation = Quat::from_rotation_y(0f32);
|
||||
flashlight_trans.translation = Vec3::new(0.0, 0.0, 0.0);
|
||||
|
@ -599,11 +629,16 @@ pub fn handle_vehicle_enter_exit(
|
|||
Quat::from_rotation_y(180f32.to_radians());
|
||||
flashlight_trans.translation = Vec3::new(0.0, 0.0, 1.0);
|
||||
}
|
||||
commands.entity(driver).remove::<HiddenInsideVehicle>();
|
||||
commands.entity(driver).insert(WantsAcceleration::default());
|
||||
commands.entity(driver).insert(RigidBody::Dynamic);
|
||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::ExitVehicle));
|
||||
commands.entity(vehicle).remove::<WantsMaxRotation>();
|
||||
commands.entity(vehicle).remove::<PlayerCamera>();
|
||||
commands.entity(driver).insert(PlayerCamera);
|
||||
commands.entity(vehicle).remove::<PlayerDrivesThis>();
|
||||
commands.entity(vehicle).remove::<WantsAcceleration>();
|
||||
commands.entity(vehicle).remove::<WantsRotationChange>();
|
||||
*vehicle_vis = Visibility::Visible;
|
||||
}
|
||||
}
|
||||
|
@ -703,6 +738,260 @@ fn handle_wants_maxvelocity(
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_wants_rotation_change(mut q_actor: Query<(&mut Rotation, &mut WantsRotationChange)>) {
|
||||
for (mut rot, mut change_rot) in &mut q_actor {
|
||||
if change_rot.0 == Vec3::ZERO {
|
||||
continue;
|
||||
}
|
||||
|
||||
let actual_change_rot = change_rot.0.clamp_length_max(0.10);
|
||||
for axis in 0..3 {
|
||||
let original = change_rot.0[axis];
|
||||
change_rot.0[axis] = 0.90 * change_rot.0[axis] - actual_change_rot[axis];
|
||||
if original.signum() != change_rot.0[axis].signum() {
|
||||
change_rot.0[axis] = 0.0;
|
||||
}
|
||||
}
|
||||
let change = DQuat::from_euler(
|
||||
EulerRot::XYZ,
|
||||
actual_change_rot[0] as f64,
|
||||
actual_change_rot[1] as f64,
|
||||
actual_change_rot[2] as f64,
|
||||
);
|
||||
**rot = **rot * change;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_wants_acceleration(
|
||||
time: Res<Time>,
|
||||
settings: Res<var::Settings>,
|
||||
jupiter_pos: Res<game::JupiterPos>,
|
||||
q_audiosinks: Query<(&audio::Sfx, &AudioSink)>,
|
||||
mut q_actor: Query<
|
||||
(
|
||||
Entity,
|
||||
&Transform,
|
||||
&Position,
|
||||
&mut LinearVelocity,
|
||||
Option<&mut Engine>,
|
||||
Option<&WantsAcceleration>,
|
||||
Option<&hud::IsTargeted>,
|
||||
Option<&PlayerCamera>,
|
||||
),
|
||||
(Without<visual::IsEffect>, Without<HiddenInsideVehicle>),
|
||||
>,
|
||||
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
|
||||
) {
|
||||
let dt = time.delta_seconds();
|
||||
|
||||
// Vector elements: (Entity, is_player, pos)
|
||||
let mut request_closest: Vec<(Entity, bool, DVec3)> = vec![];
|
||||
let mut closest_map: HashMap<Entity, DVec3> = HashMap::new();
|
||||
|
||||
// First, determine whether any actor wants to brake (=match velocity)
|
||||
for (entity, _, pos, _, _, accel, _, is_player) in &mut q_actor {
|
||||
if accel.is_some() && accel.unwrap().brake {
|
||||
request_closest.push((entity, is_player.is_some(), pos.0.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
// If an actor is braking, find out relative to what it wants to brake
|
||||
for (entity, is_player, pos) in &request_closest {
|
||||
let mut target_v: Option<DVec3> = None;
|
||||
|
||||
// First, if this is the player, check whether they targeted anything
|
||||
// so we can match velocity to the target.
|
||||
if *is_player {
|
||||
for (_, _, _, v, _, _, is_target, _) in &q_actor {
|
||||
if is_target.is_some() {
|
||||
target_v = Some(v.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If not, simply look for the closest object and match velocity to that.
|
||||
if target_v.is_none() {
|
||||
let mut closest_distance = camera::MAX_DIST_FOR_MATCH_VELOCITY;
|
||||
for (testentity, _, testpos, v, _, _, _, _) in &q_actor {
|
||||
if *entity != testentity {
|
||||
let distance = (*pos - testpos.0).length();
|
||||
if distance < closest_distance {
|
||||
target_v = Some(v.0);
|
||||
closest_distance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Last resort: Match velocity to the orbital velocity around Jupiter
|
||||
if target_v.is_none() {
|
||||
let relative_pos = *pos - jupiter_pos.0;
|
||||
target_v = Some(nature::orbital_velocity(relative_pos, nature::JUPITER_MASS));
|
||||
}
|
||||
|
||||
if let Some(target_v) = target_v {
|
||||
closest_map.insert(*entity, target_v);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, apply the requested acceleration to the actor's velocity
|
||||
let mut play_thruster_sound = false;
|
||||
let mut players_engine: Option<Engine> = None;
|
||||
for (entity, trans, pos, mut v, engine, accel, _, is_player) in &mut q_actor {
|
||||
let mut thruster_on = false;
|
||||
if let (Some(mut engine), Some(accel)) = (engine, accel) {
|
||||
let mut delta_v = DVec3::ZERO;
|
||||
let mut allow_fullstop = false;
|
||||
let boost = engine.current_boost_factor;
|
||||
engine.currently_matching_velocity = false;
|
||||
|
||||
if accel.brake {
|
||||
if let Some(target_v) = closest_map.get(&entity) {
|
||||
let stop_direction = (*target_v - v.0).as_vec3();
|
||||
if stop_direction.length_squared() > 0.003 {
|
||||
delta_v =
|
||||
(trans.rotation.inverse() * stop_direction.normalize()).as_dvec3();
|
||||
engine.currently_matching_velocity = true;
|
||||
thruster_on = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if accel.direction != DVec3::ZERO {
|
||||
// Player is pressing AWSD keys
|
||||
let brake_factor = if accel.brake { 1.10 } else { 1.0 };
|
||||
delta_v += accel.direction.normalize() * brake_factor;
|
||||
} else if accel.brake {
|
||||
// Player is only pressing space
|
||||
allow_fullstop = true;
|
||||
}
|
||||
|
||||
if delta_v.length_squared() > 0.003 {
|
||||
// Engine is firing!
|
||||
thruster_on = true;
|
||||
engine.current_warmup =
|
||||
(engine.current_warmup + dt / engine.warmup_seconds).clamp(0.0, 1.0);
|
||||
|
||||
delta_v = delta_v.clamp(DVec3::splat(-1.0), DVec3::splat(1.0));
|
||||
|
||||
// Adjust acceleration to what the engine can actually provide
|
||||
let factor_forward = if accel.direction.z > 0.0 {
|
||||
engine.thrust_forward
|
||||
} else {
|
||||
engine.thrust_back
|
||||
};
|
||||
let factor_right = engine.thrust_sideways;
|
||||
let factor_up = engine.thrust_sideways;
|
||||
let engine_factor = Vec3::new(factor_right, factor_up, factor_forward).as_dvec3()
|
||||
* engine.current_warmup as f64
|
||||
* ENGINE_SPEED_FACTOR as f64
|
||||
* engine.current_boost_factor;
|
||||
|
||||
let final_accel =
|
||||
(trans.rotation * (delta_v * engine_factor).as_vec3() * dt).as_dvec3();
|
||||
|
||||
// Apply acceleration to velocity
|
||||
if allow_fullstop {
|
||||
if let Some(target_v) = closest_map.get(&entity) {
|
||||
// Prevent overshooting when matching velocity, which
|
||||
// would result in oscillating acceleration back and forth
|
||||
for axis in 0..3 {
|
||||
let original = v[axis];
|
||||
let target = target_v[axis];
|
||||
v[axis] += final_accel[axis];
|
||||
if (original - target).signum() != (v[axis] - target).signum() {
|
||||
v[axis] = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
**v += final_accel;
|
||||
}
|
||||
|
||||
// Visual effect
|
||||
if engine.engine_type == EngineType::Monopropellant {
|
||||
let thruster_direction = final_accel.normalize();
|
||||
let thruster_pos = pos.0 - 0.3 * thruster_direction;
|
||||
let thruster_v = v.0 - boost * 5.0 * thruster_direction;
|
||||
ew_effect.send(visual::SpawnEffectEvent {
|
||||
duration: 2.0,
|
||||
class: visual::Effects::ThrusterParticle(
|
||||
Position::from(thruster_pos),
|
||||
LinearVelocity::from(thruster_v),
|
||||
),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Engine is not firing
|
||||
engine.current_warmup =
|
||||
(engine.current_warmup - dt / engine.warmup_seconds).clamp(0.0, 1.0);
|
||||
}
|
||||
|
||||
if is_player.is_some() {
|
||||
play_thruster_sound = thruster_on;
|
||||
players_engine = Some((*engine).clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Play sound effects for player acceleration
|
||||
let engine = if let Some(engine) = players_engine {
|
||||
engine
|
||||
} else {
|
||||
warn!("Failed to retrieve player's engine type for playing SFX");
|
||||
Engine::default()
|
||||
};
|
||||
|
||||
let mut sinks: HashMap<audio::Sfx, &AudioSink> = HashMap::new();
|
||||
for (sfx, sink) in &q_audiosinks {
|
||||
sinks.insert(*sfx, sink);
|
||||
}
|
||||
let sinks = vec![
|
||||
(
|
||||
1.0,
|
||||
engine.current_boost_factor as f32,
|
||||
actor::EngineType::Monopropellant,
|
||||
sinks.get(&audio::Sfx::Thruster),
|
||||
),
|
||||
(
|
||||
1.0,
|
||||
1.0,
|
||||
actor::EngineType::Ion,
|
||||
sinks.get(&audio::Sfx::Ion),
|
||||
),
|
||||
];
|
||||
|
||||
let seconds_to_max_vol = 0.05;
|
||||
let seconds_to_min_vol = 0.05;
|
||||
for sink_data in sinks {
|
||||
if let (vol_boost, speed, engine_type, Some(sink)) = sink_data {
|
||||
if settings.mute_sfx {
|
||||
sink.pause();
|
||||
} else {
|
||||
let volume = sink.volume();
|
||||
let maxvol = settings.volume_sfx * vol_boost;
|
||||
if engine.engine_type == engine_type {
|
||||
if play_thruster_sound {
|
||||
sink.set_speed(speed);
|
||||
sink.play();
|
||||
if volume < maxvol {
|
||||
sink.set_volume((volume + dt / seconds_to_max_vol).clamp(0.0, maxvol));
|
||||
}
|
||||
} else {
|
||||
sink.set_volume((volume - dt / seconds_to_min_vol).clamp(0.0, maxvol));
|
||||
}
|
||||
} else if volume > 0.0 {
|
||||
sink.set_volume((volume - dt / seconds_to_min_vol).clamp(0.0, maxvol));
|
||||
}
|
||||
if volume < 0.0001 {
|
||||
sink.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_wants_lookat(
|
||||
mut query: Query<
|
||||
(
|
||||
|
|
Binary file not shown.
102
src/camera.rs
102
src/camera.rs
|
@ -80,7 +80,10 @@ impl Plugin for CameraPlugin {
|
|||
app.add_systems(
|
||||
PostUpdate,
|
||||
position_to_transform
|
||||
.run_if(game_running)
|
||||
// The if(game_running) condition should be there, but
|
||||
// somehow everything apart of AR avatars ends up becoming
|
||||
// invisible if I leave it in, so for now, we leave it out.
|
||||
//.run_if(game_running)
|
||||
.after(sync::position_to_transform)
|
||||
.in_set(sync::SyncSet::PositionToTransform),
|
||||
);
|
||||
|
@ -440,8 +443,103 @@ fn manage_player_actor(
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn apply_input_to_player(
|
||||
mut commands: Commands,
|
||||
settings: Res<var::Settings>,
|
||||
mut q_player: Query<
|
||||
(
|
||||
Entity,
|
||||
&mut actor::WantsAcceleration,
|
||||
Option<&mut actor::WantsRotationChange>,
|
||||
),
|
||||
With<actor::PlayerCamera>,
|
||||
>,
|
||||
mut mouse_events: EventReader<MouseMotion>,
|
||||
key_input: Res<ButtonInput<KeyCode>>,
|
||||
q_windows: Query<&Window, With<PrimaryWindow>>,
|
||||
) {
|
||||
let player = q_player.get_single_mut();
|
||||
if player.is_err() {
|
||||
return;
|
||||
}
|
||||
let (entity, mut accel, rot_change) = player.unwrap();
|
||||
|
||||
let (win_res_x, win_res_y): (f32, f32);
|
||||
if let Ok(window) = &q_windows.get_single() {
|
||||
win_res_x = window.resolution.width();
|
||||
win_res_y = window.resolution.height();
|
||||
} else {
|
||||
win_res_x = 1920.0;
|
||||
win_res_y = 1050.0;
|
||||
}
|
||||
|
||||
// Determine rotation delta
|
||||
let mut pitch_yaw_rot = Vec3::ZERO;
|
||||
let mut mouse_delta = Vec2::ZERO;
|
||||
for mouse_event in mouse_events.read() {
|
||||
mouse_delta += mouse_event.delta;
|
||||
}
|
||||
if mouse_delta != Vec2::ZERO {
|
||||
if key_input.pressed(settings.key_rotate) {
|
||||
pitch_yaw_rot[2] += mouse_delta.x / win_res_x;
|
||||
} else {
|
||||
pitch_yaw_rot[0] += mouse_delta.y / win_res_y;
|
||||
pitch_yaw_rot[1] -= mouse_delta.x / win_res_x;
|
||||
}
|
||||
}
|
||||
pitch_yaw_rot *= 2.0
|
||||
* if settings.is_zooming {
|
||||
settings.zoom_sensitivity_factor
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
|
||||
// Apply rotation to player
|
||||
if pitch_yaw_rot != Vec3::ZERO {
|
||||
let rot_change_current = if let Some(rot_change) = &rot_change {
|
||||
rot_change.0
|
||||
} else {
|
||||
Vec3::ZERO
|
||||
};
|
||||
let rot_target = rot_change_current + pitch_yaw_rot;
|
||||
if let Some(mut rot_change) = rot_change {
|
||||
rot_change.0 = rot_target;
|
||||
} else {
|
||||
commands
|
||||
.entity(entity)
|
||||
.try_insert(actor::WantsRotationChange(rot_target));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine acceleration
|
||||
let mut axis_input: DVec3 = DVec3::ZERO;
|
||||
if key_input.pressed(settings.key_forward) || settings.cruise_control_active {
|
||||
axis_input.z += 1.0;
|
||||
}
|
||||
if key_input.pressed(settings.key_back) {
|
||||
axis_input.z -= 1.0;
|
||||
}
|
||||
if key_input.pressed(settings.key_right) {
|
||||
axis_input.x -= 1.0;
|
||||
}
|
||||
if key_input.pressed(settings.key_left) {
|
||||
axis_input.x += 1.0;
|
||||
}
|
||||
if key_input.pressed(settings.key_up) {
|
||||
axis_input.y += 1.0;
|
||||
}
|
||||
if key_input.pressed(settings.key_down) {
|
||||
axis_input.y -= 1.0;
|
||||
}
|
||||
//axis_input = axis_input.clamp(DVec3::splat(-1.0), DVec3::splat(1.0));
|
||||
|
||||
// Apply acceleration to player
|
||||
accel.direction = axis_input;
|
||||
accel.brake = key_input.pressed(settings.key_stop);
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn apply_input_to_player_old(
|
||||
time: Res<Time>,
|
||||
mut commands: Commands,
|
||||
settings: Res<var::Settings>,
|
||||
|
|
|
@ -1126,7 +1126,7 @@
|
|||
- Nothing native, anyway.
|
||||
- That's all, thanks!:
|
||||
- Cool, anything else you wanted?
|
||||
- goto: pig_node_main
|
||||
- goto: entrypoint
|
||||
- goto: pig_node_geo
|
||||
- if: $pig
|
||||
You're pork! Yummy! I'm starving!:
|
||||
|
|
|
@ -1134,7 +1134,9 @@ fn spawn_entities(
|
|||
if state.is_player {
|
||||
actor.insert(actor::Player);
|
||||
actor.insert(actor::PlayerCamera);
|
||||
actor.insert(actor::WantsAcceleration::default());
|
||||
actor.insert(hud::AugmentedRealityOverlayBroadcaster);
|
||||
//actor.insert(actor::WantsRotation(Quat::IDENTITY));
|
||||
ew_updateavatar.send(hud::UpdateAvatarEvent);
|
||||
}
|
||||
if state.is_sun {
|
||||
|
@ -1313,7 +1315,6 @@ fn spawn_entities(
|
|||
..default()
|
||||
},
|
||||
NotShadowCaster,
|
||||
NotShadowReceiver,
|
||||
));
|
||||
load_asset(ar_asset_name.as_str(), &mut entitycmd, &*asset_server);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue