Add mouse look

This commit is contained in:
Sofia 2026-07-18 00:12:40 +03:00
parent 51d0093807
commit 93809e7fd6
6 changed files with 130 additions and 0 deletions

View File

@ -40,6 +40,7 @@ toggle_cli={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":167,"key_label":0,"unicode":167,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194332,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194343,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}

25
godot/scenes/map0.tscn Normal file
View File

@ -0,0 +1,25 @@
[gd_scene format=3 uid="uid://7iooamjot1tg"]
[ext_resource type="PackedScene" uid="uid://ct70bpbca8one" path="res://scenes/player.tscn" id="1_y4ph1"]
[sub_resource type="PlaneMesh" id="PlaneMesh_1cgct"]
[node name="map_0" type="Node3D" unique_id=1710628675]
[node name="net_stats_label" type="NetStatsLabel" parent="." unique_id=1821474986]
offset_left = 1.0
offset_top = 497.0
offset_right = 370.0
offset_bottom = 649.0
vertical_alignment = 2
[node name="terrain" type="MeshInstance3D" parent="." unique_id=1474127252]
transform = Transform3D(100, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0)
mesh = SubResource("PlaneMesh_1cgct")
[node name="player" parent="." unique_id=1910472598 instance=ExtResource("1_y4ph1")]
look_sensitivity = 2.0
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.002088, 0)
[node name="directional_light_3d" type="DirectionalLight3D" parent="." unique_id=793524416]
transform = Transform3D(1, 0, 0, 0, 0.7274598, 0.6861503, 0, -0.6861503, 0.7274598, -5.1267624, 3.3997262, 3.715582)

18
godot/scenes/player.tscn Normal file
View File

@ -0,0 +1,18 @@
[gd_scene format=3 uid="uid://ct70bpbca8one"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_1cgct"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
[node name="player" type="Player" unique_id=1910472598 node_paths=PackedStringArray("camera")]
look_sensitivity = 1.0
camera = NodePath("camera_3d")
[node name="mesh_instance_3d" type="MeshInstance3D" parent="." unique_id=700336478]
mesh = SubResource("CapsuleMesh_1cgct")
[node name="collision_shape_3d" type="CollisionShape3D" parent="." unique_id=1110995513]
shape = SubResource("CapsuleShape3D_1cgct")
[node name="camera_3d" type="Camera3D" parent="." unique_id=1773137418]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5391109, 0)

View File

@ -5,6 +5,7 @@ use godot::prelude::*;
pub mod game_manager;
pub mod map_resource;
pub mod net;
pub mod player;
pub mod ui;
struct MyExtension;

76
rust/src/player.rs Normal file
View File

@ -0,0 +1,76 @@
use std::f32::consts::PI;
use godot::{
classes::{
Camera3D, CharacterBody3D, ICharacterBody3D, Input, InputEvent, InputEventMouseMotion,
input::MouseMode,
},
prelude::*,
};
use crate::ui::cli::CommandLinePanel;
#[derive(GodotClass)]
#[class(base=CharacterBody3D, init)]
pub struct Player {
#[export]
look_sensitivity: f32,
#[export]
camera: Option<Gd<Camera3D>>,
locked: bool,
base: Base<CharacterBody3D>,
}
#[godot_api]
impl ICharacterBody3D for Player {
fn ready(&mut self) {
if !CommandLinePanel::singleton().bind().opened {
self.set_lock(true);
}
CommandLinePanel::singleton()
.signals()
.on_open()
.connect_other(self, |s| s.set_lock(false));
CommandLinePanel::singleton()
.signals()
.on_close()
.connect_other(self, |s| {
s.set_lock(true);
});
}
fn process(&mut self, delta: f64) {}
fn input(&mut self, event: Gd<InputEvent>) {
if self.locked {
if let Ok(event) = event.try_cast::<InputEventMouseMotion>() {
let x = event.get_relative().x * 0.001 * self.look_sensitivity;
let y = event.get_relative().y * 0.001 * self.look_sensitivity;
if let Some(camera) = self.camera.as_mut() {
let curr_rotation = camera.get_rotation();
let x_rot =
(curr_rotation.x - y * self.look_sensitivity).clamp(-PI / 2., PI / 2.);
camera.set_rotation(Vector3::RIGHT * x_rot);
}
let y_rot = -x * self.look_sensitivity;
self.base_mut().rotate_y(y_rot);
}
}
}
}
impl Player {
fn set_lock(&mut self, locked: bool) {
self.locked = locked;
if self.locked {
Input::singleton().set_mouse_mode(MouseMode::CAPTURED);
} else {
Input::singleton().set_mouse_mode(MouseMode::VISIBLE);
}
}
}

View File

@ -109,6 +109,11 @@ impl IPanel for CommandLinePanel {
fn input(&mut self, event: Gd<InputEvent>) {
if event.is_action_pressed("toggle_cli") {
self.opened = !self.opened;
if self.opened {
self.signals().on_open().emit();
} else {
self.signals().on_close().emit();
}
if let Some(input_field) = &mut self.input_field {
if self.opened {
input_field.grab_focus();
@ -131,6 +136,10 @@ impl CommandLinePanel {
pub fn on_join(port: String);
#[signal]
pub fn on_disconnect();
#[signal]
pub fn on_open();
#[signal]
pub fn on_close();
pub fn singleton() -> Gd<CommandLinePanel> {
get_autoload_by_name::<CanvasLayer>(CLI_GLOBAL_NAME)