use godot::classes::{CharacterBody3D, ICharacterBody3D}; use godot::obj::WithBaseField; use godot::prelude::*; #[derive(GodotClass)] #[class(base=CharacterBody3D)] struct PlayerServerNode { base: Base, jumping: bool, input_direction: Vector2, } const JUMP_VELOCITY: f32 = 4.5; const SPEED: f32 = 5.0; #[godot_api] impl ICharacterBody3D for PlayerServerNode { fn init(base: Base) -> Self { Self { base, jumping: false, input_direction: Vector2::new(0.0, 0.0), } } fn ready(&mut self) {} fn physics_process(&mut self, delta: f64) { if !self.base().is_on_floor() { let new_gravity = self.base().get_gravity() * delta as f32; let new_velocity = self.base().get_velocity() + new_gravity; self.base_mut().set_velocity(new_velocity); } if self.base().is_on_floor() && self.jumping { let mut new_velocity = self.base().get_velocity(); new_velocity.y = JUMP_VELOCITY; self.base_mut().set_velocity(new_velocity); } self.jumping = false; if self.base().is_on_floor() { let direction = self.base().get_transform().basis * Vector3::new(self.input_direction.x, 0.0, self.input_direction.y); if direction.length() > 0.0 { let direction = direction.normalized(); let new_velocity = Vector3::new( direction.x * SPEED, self.base().get_velocity().y, direction.z * SPEED, ); self.base_mut().set_velocity(new_velocity); } else { let moved = self .base() .get_velocity() .clone() .move_toward(Vector3::new(0.0, 0.0, 0.0), SPEED); let new_velocity = Vector3::new(moved.x, self.base().get_velocity().y, moved.z); self.base_mut().set_velocity(new_velocity); } } self.base_mut().move_and_slide(); } } #[godot_api] impl PlayerServerNode { #[rpc(any_peer, call_local, unreliable_ordered)] fn jump(&mut self) { self.jumping = true } #[rpc(any_peer, call_local, unreliable_ordered)] fn set_input_direction(&mut self, new_input_direction: Vector2) { self.input_direction = new_input_direction; } #[rpc(any_peer, call_local, unreliable_ordered)] fn set_rotation_y(&mut self, y: f32) { let mut new_rotation = self.base().get_rotation(); new_rotation.y = y; self.base_mut().set_rotation(new_rotation); } #[rpc(any_peer, call_local, unreliable_ordered)] fn set_rotation_x(&mut self, x: f32) { let mut camera_mount = self.base().get_node_as::("BulletStartingPoint"); let mut new_rotation = camera_mount.get_rotation(); new_rotation.x = x; camera_mount.set_rotation(new_rotation); } #[rpc(any_peer, call_local, unreliable_ordered)] fn shoot(&mut self) { let bullet_starting_poing = match self.base().find_child("BulletStartingPoint") { Some(node) => node, None => return, }; let casted_bullet_node = bullet_starting_poing.cast::(); let mut map = match self.base().find_parent("Map") { Some(map) => map, None => return, }; let args = &[ casted_bullet_node.to_variant(), 10.to_variant(), 10.to_variant(), ]; map.call("spawn_bullet", args); } }