145 lines
4.6 KiB
Rust
145 lines
4.6 KiB
Rust
use fyrox::{
|
|
core::{
|
|
algebra::{UnitQuaternion, UnitVector3, Vector3},
|
|
pool::Handle,
|
|
reflect::prelude::*,
|
|
visitor::prelude::*,
|
|
variable::InheritableVariable,
|
|
type_traits::prelude::*
|
|
},
|
|
event::{DeviceEvent, ElementState, MouseButton, WindowEvent, Event},
|
|
script::{ScriptContext, ScriptDeinitContext, ScriptTrait},
|
|
graph::SceneGraph,
|
|
keyboard::{KeyCode, PhysicalKey},
|
|
scene::{node::Node, rigidbody::RigidBody},
|
|
};
|
|
|
|
#[derive(Visit, Reflect, Default, Debug, Clone, TypeUuidProvider, ComponentProvider)]
|
|
#[type_uuid(id = "d14f7a07-1ea0-4d20-ad74-017b2497c88e")]
|
|
#[visit(optional)]
|
|
pub struct Player {
|
|
#[reflect(hidden)]
|
|
move_forward: bool,
|
|
|
|
#[reflect(hidden)]
|
|
move_backward: bool,
|
|
|
|
#[reflect(hidden)]
|
|
move_left: bool,
|
|
|
|
#[reflect(hidden)]
|
|
move_right: bool,
|
|
|
|
#[reflect(hidden)]
|
|
yaw: f32,
|
|
|
|
#[reflect(hidden)]
|
|
pitch: f32,
|
|
|
|
camera: Handle<Node>,
|
|
}
|
|
|
|
impl ScriptTrait for Player {
|
|
fn on_init(&mut self, context: &mut ScriptContext) {
|
|
// Put initialization logic here.
|
|
}
|
|
|
|
fn on_start(&mut self, context: &mut ScriptContext) {
|
|
// There should be a logic that depends on other scripts in scene.
|
|
// It is called right after **all** scripts were initialized.
|
|
}
|
|
|
|
fn on_deinit(&mut self, context: &mut ScriptDeinitContext) {
|
|
// Put de-initialization logic here.
|
|
}
|
|
|
|
fn on_os_event(&mut self, event: &Event<()>, context: &mut ScriptContext) {
|
|
match event {
|
|
Event::DeviceEvent {
|
|
event:
|
|
DeviceEvent::MouseMotion {
|
|
delta: (dx, dy), ..
|
|
},
|
|
..
|
|
} => {
|
|
let mouse_speed = 0.35;
|
|
self.pitch = (self.pitch + *dy as f32 * mouse_speed).clamp(-89.9, 89.9);
|
|
self.yaw -= *dx as f32 * mouse_speed;
|
|
},
|
|
Event::WindowEvent {
|
|
event: WindowEvent::KeyboardInput { event, .. },
|
|
..
|
|
} => {
|
|
if let PhysicalKey::Code(code) = event.physical_key {
|
|
let is_pressed = event.state == ElementState::Pressed;
|
|
match code {
|
|
KeyCode::KeyW => {
|
|
self.move_forward = is_pressed;
|
|
},
|
|
KeyCode::KeyS => {
|
|
self.move_backward = is_pressed;
|
|
},
|
|
KeyCode::KeyA => {
|
|
self.move_left = is_pressed;
|
|
},
|
|
KeyCode::KeyD => {
|
|
self.move_right = is_pressed;
|
|
},
|
|
_ => (),
|
|
}
|
|
}
|
|
},
|
|
_ => (),
|
|
}
|
|
}
|
|
|
|
fn on_update(&mut self, context: &mut ScriptContext) {
|
|
let mut look_vector = Vector3::default();
|
|
let mut side_vector = Vector3::default();
|
|
|
|
if let Some(camera) = context.scene.graph.try_get_mut(self.camera) {
|
|
look_vector = camera.look_vector();
|
|
side_vector = camera.side_vector();
|
|
|
|
let yaw = UnitQuaternion::from_axis_angle(
|
|
&Vector3::y_axis(), self.yaw.to_radians()
|
|
);
|
|
let transform = camera.local_transform_mut();
|
|
transform.set_rotation(
|
|
UnitQuaternion::from_axis_angle(
|
|
&UnitVector3::new_normalize(yaw * Vector3::x()),
|
|
self.pitch.to_radians(),
|
|
) * yaw,
|
|
);
|
|
}
|
|
|
|
if let Some(rigid_body) = context.scene.graph.try_get_mut_of_type::<RigidBody>(context.handle) {
|
|
let mut velocity = Vector3::new(0.0, 0.0, 0.0);
|
|
if self.move_forward {
|
|
velocity += look_vector;
|
|
}
|
|
if self.move_backward {
|
|
velocity -= look_vector;
|
|
}
|
|
if self.move_left {
|
|
velocity += side_vector;
|
|
}
|
|
if self.move_right {
|
|
velocity -= side_vector;
|
|
}
|
|
|
|
let y_vel = rigid_body.lin_vel().y;
|
|
if let Some(normalized_velocity) = velocity.try_normalize(f32::EPSILON) {
|
|
let movement_speed = 240.0 * context.dt;
|
|
rigid_body.set_lin_vel(Vector3::new(
|
|
normalized_velocity.x * movement_speed,
|
|
y_vel,
|
|
normalized_velocity.z * movement_speed,
|
|
));
|
|
} else {
|
|
rigid_body.set_lin_vel(Vector3::new(0.0, y_vel, 0.0));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|