Add input forces that don't work.
This commit is contained in:
parent
beb2298fe3
commit
5e4ef7d5de
4 changed files with 54 additions and 98 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -978,9 +978,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.3.1"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3"
|
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
133
src/action.rs
133
src/action.rs
|
@ -1,5 +1,5 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::{na::Vector3, prelude::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::{CyberBike, CyberSphere, PLANET_RADIUS},
|
geometry::{CyberBike, CyberSphere, PLANET_RADIUS},
|
||||||
|
@ -25,42 +25,6 @@ impl Default for MovementSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Default)]
|
|
||||||
pub(crate) struct CyberBikeState {
|
|
||||||
pub velocity: Vec3,
|
|
||||||
pub _colliding: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gravity(xform: Query<&Transform, With<CyberBike>>, mut config: ResMut<RapierConfiguration>) {
|
|
||||||
let gravity = xform.single().translation.normalize() * -10.0;
|
|
||||||
config.gravity = gravity.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn falling_cat(
|
|
||||||
time: Res<Time>,
|
|
||||||
mut bike_query: Query<(&Transform, &mut RigidBodyForcesComponent), With<CyberBike>>,
|
|
||||||
) {
|
|
||||||
let dt = time.delta_seconds();
|
|
||||||
|
|
||||||
let (bike_xform, mut forces) = bike_query.single_mut();
|
|
||||||
let up = bike_xform.translation.normalize();
|
|
||||||
let cam_up = bike_xform.up();
|
|
||||||
let cos = up.dot(cam_up);
|
|
||||||
|
|
||||||
let theta = cos.acos();
|
|
||||||
let rate = if !theta.is_normal() {
|
|
||||||
0.0
|
|
||||||
} else if theta.is_sign_negative() {
|
|
||||||
-0.4
|
|
||||||
} else {
|
|
||||||
0.4
|
|
||||||
} * dt;
|
|
||||||
|
|
||||||
let torque = cam_up.cross(up).normalize() * rate * 50.0;
|
|
||||||
|
|
||||||
forces.torque = torque.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_colliders(
|
fn setup_colliders(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
planet_query: Query<Entity, With<CyberSphere>>,
|
planet_query: Query<Entity, With<CyberSphere>>,
|
||||||
|
@ -98,77 +62,66 @@ fn setup_colliders(
|
||||||
.insert(ColliderPositionSync::Discrete);
|
.insert(ColliderPositionSync::Discrete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gravity(xform: Query<&Transform, With<CyberBike>>, mut config: ResMut<RapierConfiguration>) {
|
||||||
|
let gravity = xform.single().translation.normalize() * -10.0;
|
||||||
|
config.gravity = gravity.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn falling_cat(
|
||||||
|
time: Res<Time>,
|
||||||
|
mut bike_query: Query<(&Transform, &mut RigidBodyForcesComponent), With<CyberBike>>,
|
||||||
|
) {
|
||||||
|
let dt = time.delta_seconds();
|
||||||
|
|
||||||
|
let (bike_xform, mut forces) = bike_query.single_mut();
|
||||||
|
let up = bike_xform.translation.normalize();
|
||||||
|
let cam_up = bike_xform.up();
|
||||||
|
let cos = up.dot(cam_up);
|
||||||
|
|
||||||
|
let theta = cos.acos();
|
||||||
|
let force = if !theta.is_normal() { 0.0 } else { theta * dt };
|
||||||
|
let torque = cam_up.cross(up).normalize() * force * 50.0;
|
||||||
|
|
||||||
|
forces.torque = torque.into();
|
||||||
|
}
|
||||||
|
|
||||||
fn update_forces(
|
fn update_forces(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
settings: Res<MovementSettings>,
|
settings: Res<MovementSettings>,
|
||||||
input: Res<InputState>,
|
input: Res<InputState>,
|
||||||
mut query: Query<(&Transform, &mut CyberBikeState)>,
|
mut query: Query<
|
||||||
|
(
|
||||||
|
&Transform,
|
||||||
|
&mut RigidBodyForcesComponent,
|
||||||
|
&mut ColliderMaterialComponent,
|
||||||
|
),
|
||||||
|
With<CyberBike>,
|
||||||
|
>,
|
||||||
) {
|
) {
|
||||||
let dt = time.delta_seconds();
|
let dt = time.delta_seconds();
|
||||||
let (xform, mut state) = query.single_mut();
|
let (xform, mut forces, mut cmat) = query.single_mut();
|
||||||
|
|
||||||
// first gravity
|
// thrust
|
||||||
let down = -xform.translation.normalize();
|
let thrust: Vector3<f32> =
|
||||||
let dvel = down * settings.gravity * dt;
|
(xform.forward() * input.throttle * dt * settings.accel * 500.0).into();
|
||||||
let mut vel = if state.velocity.is_finite() {
|
forces.force += thrust;
|
||||||
state.velocity + dvel
|
|
||||||
} else {
|
|
||||||
dvel
|
|
||||||
};
|
|
||||||
|
|
||||||
// thrust or brake
|
|
||||||
vel += xform.forward() * input.throttle * dt * settings.accel;
|
|
||||||
|
|
||||||
// brake
|
// brake
|
||||||
if input.brake {
|
cmat.friction = if input.brake { 1.0 } else { 0.0 };
|
||||||
let s = vel.length_squared();
|
|
||||||
if s < 0.05 {
|
|
||||||
vel = Vec3::ZERO;
|
|
||||||
} else {
|
|
||||||
vel -= vel.normalize() * settings.accel * dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// drag
|
// steering
|
||||||
let v2 = vel.length_squared().min(100_000.0);
|
let torque: Vector3<f32> = (xform.up() * input.yaw * dt * settings.sensitivity * 500.0).into();
|
||||||
let drag = vel * settings.drag * v2 * dt;
|
forces.torque += torque;
|
||||||
vel -= drag;
|
|
||||||
|
|
||||||
if vel.length_squared() < 0.0001 {
|
|
||||||
vel = Vec3::ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.velocity = vel;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn steer_cyberbike(
|
|
||||||
settings: Res<MovementSettings>,
|
|
||||||
windows: Res<Windows>,
|
|
||||||
time: Res<Time>,
|
|
||||||
istate: Res<InputState>,
|
|
||||||
mut query: Query<&mut Transform, With<CyberBike>>,
|
|
||||||
) {
|
|
||||||
let window = windows.get_primary().unwrap();
|
|
||||||
let window_scale = window.height().min(window.width());
|
|
||||||
let dt = time.delta_seconds();
|
|
||||||
let mut transform = query.single_mut();
|
|
||||||
|
|
||||||
let d_yaw = (settings.sensitivity * dt * window_scale * istate.yaw).to_radians();
|
|
||||||
let rotation = Quat::from_axis_angle(transform.local_y(), d_yaw);
|
|
||||||
|
|
||||||
transform.rotate(rotation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CyberActionPlugin;
|
pub struct CyberActionPlugin;
|
||||||
impl Plugin for CyberActionPlugin {
|
impl Plugin for CyberActionPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<CyberBikeState>()
|
app.init_resource::<MovementSettings>()
|
||||||
.init_resource::<MovementSettings>()
|
|
||||||
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
||||||
.add_startup_system_to_stage(StartupStage::PostStartup, setup_colliders)
|
.add_startup_system_to_stage(StartupStage::PostStartup, setup_colliders)
|
||||||
.add_system(gravity)
|
.add_system(gravity)
|
||||||
.add_system(falling_cat)
|
.add_system(falling_cat)
|
||||||
//.add_system(update_forces)
|
.add_system(update_forces);
|
||||||
.add_system(steer_cyberbike);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{action::CyberBikeState, Label};
|
use crate::Label;
|
||||||
|
|
||||||
pub const PLANET_RADIUS: f32 = 360.0;
|
pub const PLANET_RADIUS: f32 = 360.0;
|
||||||
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 100.0;
|
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 100.0;
|
||||||
|
@ -50,8 +50,7 @@ fn spawn_cyberbike(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
.with_children(|rider| {
|
.with_children(|rider| {
|
||||||
rider.spawn_scene(asset_server.load("cyber-bike_no_y_up.glb#Scene0"));
|
rider.spawn_scene(asset_server.load("cyber-bike_no_y_up.glb#Scene0"));
|
||||||
})
|
})
|
||||||
.insert(CyberBike)
|
.insert(CyberBike);
|
||||||
.insert(CyberBikeState::default());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CyberGeomPlugin;
|
pub struct CyberGeomPlugin;
|
||||||
|
|
10
src/ui.rs
10
src/ui.rs
|
@ -1,6 +1,7 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy_rapier3d::prelude::*;
|
||||||
|
|
||||||
use crate::action::CyberBikeState;
|
use crate::geometry::CyberBike;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
struct UpText;
|
struct UpText;
|
||||||
|
@ -32,10 +33,13 @@ fn setup_ui(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
.insert(UpText);
|
.insert(UpText);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_ui(state_query: Query<&CyberBikeState>, mut text_query: Query<&mut Text, With<UpText>>) {
|
fn update_ui(
|
||||||
|
state_query: Query<&RigidBodyVelocityComponent, With<CyberBike>>,
|
||||||
|
mut text_query: Query<&mut Text, With<UpText>>,
|
||||||
|
) {
|
||||||
let mut text = text_query.single_mut();
|
let mut text = text_query.single_mut();
|
||||||
let state = state_query.single();
|
let state = state_query.single();
|
||||||
text.sections[0].value = format!("spd: {:.2}", state.velocity.length(),);
|
text.sections[0].value = format!("spd: {:.2}", state.linvel.magnitude());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CyberUIPlugin;
|
pub struct CyberUIPlugin;
|
||||||
|
|
Loading…
Reference in a new issue