94 lines
3.8 KiB
GDScript
94 lines
3.8 KiB
GDScript
# PlayerController3D.gd
|
|
extends Node
|
|
class_name PlayerController3D
|
|
|
|
@onready var possessed_pawn: CharacterPawn3D = get_parent()
|
|
|
|
# --- Mouse Sensitivity ---
|
|
@export var mouse_sensitivity: float = 0.002 # Radians per pixel motion
|
|
var _mouse_motion_input: Vector2 = Vector2.ZERO
|
|
|
|
class KeyInput:
|
|
var pressed: bool = false
|
|
var held: bool = false
|
|
var released: bool = false
|
|
|
|
func _init(_p: bool, _h: bool, _r: bool):
|
|
pressed = _p
|
|
held = _h
|
|
released = _r
|
|
|
|
func _unhandled_input(event: InputEvent):
|
|
if not is_multiplayer_authority() or not is_instance_valid(possessed_pawn):
|
|
# print("Peer ID: %s, Node Authority: %s" % [multiplayer.get_unique_id(), get_multiplayer_authority()])
|
|
return
|
|
|
|
# Handle mouse motion input directly here
|
|
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
|
_mouse_motion_input += Vector2(event.relative.x, -event.relative.y)
|
|
|
|
func _physics_process(_delta):
|
|
if not is_multiplayer_authority() or not is_instance_valid(possessed_pawn):
|
|
return
|
|
|
|
if _mouse_motion_input != Vector2.ZERO:
|
|
# Calculate yaw and pitch based on mouse movement
|
|
var sensitivity_modified_mouse_input = Vector2(_mouse_motion_input.x, _mouse_motion_input.y) * mouse_sensitivity
|
|
|
|
# Send rotation input via RPC immediately
|
|
server_process_rotation_input.rpc_id(multiplayer.get_unique_id(), sensitivity_modified_mouse_input)
|
|
|
|
# Reset the buffer
|
|
_mouse_motion_input = Vector2.ZERO
|
|
|
|
|
|
var move_vec = Input.get_vector("move_left_3d", "move_right_3d", "move_backward_3d", "move_forward_3d")
|
|
var roll_input = Input.get_action_strength("roll_right_3d") - Input.get_action_strength("roll_left_3d")
|
|
var vertical_input = Input.get_action_strength("move_up_3d") - Input.get_action_strength("move_down_3d")
|
|
var interact_input = KeyInput.new(Input.is_action_just_pressed("spacebar_3d"), Input.is_action_pressed("spacebar_3d"), Input.is_action_just_released("spacebar_3d"))
|
|
|
|
var l_input = KeyInput.new(Input.is_action_just_pressed("left_click"), Input.is_action_pressed("left_click"), Input.is_action_just_released("left_click"))
|
|
var r_input = KeyInput.new(Input.is_action_just_pressed("right_click"), Input.is_action_pressed("right_click"), Input.is_action_just_released("right_click"))
|
|
|
|
server_process_movement_input.rpc_id(multiplayer.get_unique_id(), move_vec, roll_input, vertical_input)
|
|
server_process_interaction_input.rpc_id(multiplayer.get_unique_id(), interact_input)
|
|
server_process_clicks.rpc_id(multiplayer.get_unique_id(), l_input, r_input)
|
|
|
|
@rpc("authority", "call_local")
|
|
func server_process_movement_input(move: Vector2, roll: float, vertical: float):
|
|
if is_instance_valid(possessed_pawn):
|
|
possessed_pawn.set_movement_input(move, roll, vertical)
|
|
|
|
@rpc("authority", "call_local")
|
|
func server_process_interaction_input(interact_input: KeyInput):
|
|
if is_instance_valid(possessed_pawn):
|
|
possessed_pawn.set_interaction_input(interact_input)
|
|
|
|
@rpc("authority", "call_local")
|
|
func server_process_rotation_input(input: Vector2):
|
|
if is_instance_valid(possessed_pawn):
|
|
possessed_pawn.set_rotation_input(input)
|
|
|
|
@rpc("authority", "call_local")
|
|
func server_process_clicks(l_action: KeyInput, r_action: KeyInput):
|
|
if is_instance_valid(possessed_pawn):
|
|
possessed_pawn.set_click_input(l_action, r_action)
|
|
|
|
func possess(pawn_to_control: CharacterPawn3D):
|
|
possessed_pawn = pawn_to_control
|
|
|
|
#print("PlayerController3D %d possessed: %s" % [multiplayer.get_unique_id(), possessed_pawn.name])
|
|
|
|
# Optional: Release mouse when losing focus
|
|
func _notification(what):
|
|
match what:
|
|
NOTIFICATION_WM_WINDOW_FOCUS_OUT:
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
|
NOTIFICATION_WM_WINDOW_FOCUS_IN:
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
NOTIFICATION_EXIT_TREE:
|
|
print("PlayerController %s exited tree" % multiplayer.get_unique_id())
|
|
NOTIFICATION_ENTER_TREE:
|
|
print("PlayerController %s entered tree" % multiplayer.get_unique_id())
|
|
|