diff --git a/splunk/player/Player.tscn b/splunk/player/Player.tscn index 042e334..6683e14 100644 --- a/splunk/player/Player.tscn +++ b/splunk/player/Player.tscn @@ -24,21 +24,27 @@ properties/0/replication_mode = 2 properties/1/path = NodePath(".:rotation") properties/1/spawn = true properties/1/replication_mode = 2 -properties/2/path = NodePath("Camera3D/head:rotation") +properties/2/path = NodePath("Neck:rotation") properties/2/spawn = true -properties/2/replication_mode = 1 +properties/2/replication_mode = 2 -[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("head")] +[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("camera", "neck", "body", "head")] collision_layer = 2 collision_mask = 3 script = ExtResource("1_ulp21") -head = NodePath("Camera3D/head") +camera = NodePath("Neck/Camera3D") +neck = NodePath("Neck") +body = NodePath("Mesh") +head = NodePath("Neck/head") -[node name="Camera3D" type="Camera3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.510896, 0.0644827) +[node name="Neck" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.266461, 0) -[node name="head" parent="Camera3D" instance=ExtResource("3_wnvi2")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.0645776) +[node name="Camera3D" type="Camera3D" parent="Neck"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.238996, 0) + +[node name="head" parent="Neck" instance=ExtResource("3_wnvi2")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.238996, 0) [node name="CollisionShape3D" type="CollisionShape3D" parent="."] shape = SubResource("CapsuleShape3D_ehsmr") diff --git a/splunk/player/player.gd b/splunk/player/player.gd index cc70cdb..aca273b 100644 --- a/splunk/player/player.gd +++ b/splunk/player/player.gd @@ -1,81 +1,106 @@ -extends CharacterBody3D -class_name Player +class_name Player extends CharacterBody3D -@export var speed = 5.0 -@export var jump_velocity = 4.5 -@export var mouse_sensitivity = 0.002 +@export_category("Player") +@export_range(1, 35, 1) var speed: float = 5.0 +@export_range(10, 400, 1) var acceleration: float = 100.0 + +@export_range(0.1, 3.0, 0.1) var jump_height: float = 1.0 +@export_range(0.1, 3.0, 0.1, "or_greater") var camera_sens: float = 1.0 +@export_range(0.1, 3.0, 0.1, "or_greater") var joystick_camera_sens_multiplier: float = 5.0 +@export var camera: Camera3D +@export var neck: Node3D +@export var body: Node3D @export var head: Node3D -var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") -var camera_node: Camera3D - +var jumping: bool = false +var is_using_joystick: bool = false +var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") +var move_dir: Vector2 # Input direction for movement +var look_dir: Vector2 # Input direction for look/aim +var walk_vel: Vector3 # Walking velocity +var grav_vel: Vector3 # Gravity velocity +var jump_vel: Vector3 # Jumping velocity func _ready(): if is_multiplayer_authority(): print("-> [%s] Authority granted. Setting up camera and input." % name) - camera_node = $Camera3D - camera_node.make_current() + camera.make_current() Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) $Mesh.hide() $Label3D.hide() head.hide() + func set_player_name(peer_id: String, player_name: String): name = peer_id $Label3D.text = player_name -#@rpc("any_peer", "call_local", "unreliable") -#func update_remote_transform(new_transform: Transform3D): - #global_transform = new_transform - - -func _physics_process(delta): - if is_multiplayer_authority(): - # Apply gravity - if not is_on_floor(): - velocity.y -= gravity * delta - - # Handle Jump - if Input.is_action_just_pressed("jump") and is_on_floor(): - velocity.y = jump_velocity - - # Get the input direction and apply movement - var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") - var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() - - if is_on_floor(): - if direction: - velocity.x = direction.x * speed - velocity.z = direction.z * speed - else: - velocity.x = move_toward(velocity.x, 0, speed) - velocity.z = move_toward(velocity.z, 0, speed) - else: - # Air control - velocity.x = lerp(velocity.x, direction.x * speed, delta * 5.0) - velocity.z = lerp(velocity.z, direction.z * speed, delta * 5.0) - move_and_slide() - - #update_remote_transform.rpc(global_transform) - - func _input(event): if is_multiplayer_authority(): - if event is InputEventMouseMotion: - # Rotate the CharacterBody3D around the Y-axis for horizontal look - rotate_y(-event.relative.x * mouse_sensitivity) + if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + if event is InputEventMouseMotion: + is_using_joystick = false + look_dir = event.relative * 0.001 + _rotate_camera() + elif event is InputEventJoypadMotion: + is_using_joystick = true + + if Input.is_action_just_pressed("jump"): + jumping = true - # Rotate the Camera3D around its local X-axis for vertical look - var change = -event.relative.y * mouse_sensitivity - var new_x_rotation = camera_node.rotation.x + change - camera_node.rotation.x = clamp(new_x_rotation, deg_to_rad(-90), deg_to_rad(90)) + +func _physics_process(delta: float) -> void: + if is_multiplayer_authority(): + velocity = walk(delta) + _gravity(delta) + _jump(delta) + + global_rotation.x = 0.0 + global_rotation.z = 0.0 - if event.is_action_pressed("ui_cancel"): # Typically Escape key - if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - else: - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + _handle_joypad_camera_rotation(delta) + move_and_slide() + + +func _rotate_camera(sens_mod: float = 1.0) -> void: + if is_multiplayer_authority(): + var camera_sens_final = camera_sens + if is_using_joystick: + camera_sens_final = camera_sens * joystick_camera_sens_multiplier + + rotation.y -= look_dir.x * camera_sens_final * sens_mod + neck.rotation.x = clamp(neck.rotation.x - look_dir.y * camera_sens_final * sens_mod, -1.5, 1.5) + + +func _handle_joypad_camera_rotation(delta: float, sens_mod: float = 1.0) -> void: + var joypad_dir: Vector2 = Input.get_vector("look_left","look_right","look_up","look_down") + if joypad_dir.length() > 0: + look_dir += joypad_dir * delta + _rotate_camera(sens_mod) + look_dir = Vector2.ZERO + + +func walk(delta: float) -> Vector3: + if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + move_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") + var _forward: Vector3 = neck.global_transform.basis * Vector3(move_dir.x, 0, move_dir.y) + var walk_dir: Vector3 = Vector3(_forward.x, 0, _forward.z).normalized() + walk_vel = walk_vel.move_toward(walk_dir * speed * move_dir.length(), acceleration * delta) + return walk_vel + + +func _gravity(delta: float) -> Vector3: + grav_vel = Vector3.ZERO if is_on_floor() else grav_vel.move_toward(Vector3(0, velocity.y - gravity, 0), gravity * delta) + return grav_vel + + +func _jump(delta: float) -> Vector3: + if jumping: + if is_on_floor(): jump_vel = Vector3(0, sqrt(4 * jump_height * gravity), 0) + jumping = false + return jump_vel + jump_vel = Vector3.ZERO if is_on_floor() else jump_vel.move_toward(Vector3.ZERO, gravity * delta) + return jump_vel diff --git a/splunk/project.godot b/splunk/project.godot index 2a11b0e..9ff1181 100644 --- a/splunk/project.godot +++ b/splunk/project.godot @@ -97,6 +97,26 @@ inv_slot_4={ "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":52,"key_label":0,"unicode":52,"location":0,"echo":false,"script":null) ] } +look_left={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +] +} +look_right={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +] +} +look_down={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +look_up={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +] +} [layer_names]