Fix networked input
This commit is contained in:
@ -8,8 +8,15 @@
|
||||
properties/0/path = NodePath(".:position")
|
||||
properties/0/spawn = true
|
||||
properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath(".:linear_velocity")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
properties/2/path = NodePath(".:rotation")
|
||||
properties/2/spawn = true
|
||||
properties/2/replication_mode = 1
|
||||
|
||||
[node name="3dTestShip" type="RigidBody3D" unique_id=246037729]
|
||||
physics_interpolation_mode = 1
|
||||
script = ExtResource("1_ktv2t")
|
||||
physics_mode = 1
|
||||
base_mass = 10000.0
|
||||
|
||||
@ -17,8 +17,8 @@ var _pitch_yaw_input: Vector2 = Vector2.ZERO
|
||||
|
||||
## Rotation Variables
|
||||
@onready var camera_anchor: Marker3D = $CameraAnchor
|
||||
@onready var camera_pivot: Node3D = $CameraPivot
|
||||
@onready var camera: Camera3D = $CameraPivot/SpringArm/Camera3D
|
||||
@onready var camera_pivot: Node3D = $CameraAnchor/CameraPivot
|
||||
@onready var camera: Camera3D = $CameraAnchor/CameraPivot/SpringArm/Camera3D
|
||||
@export_range(0.1, PI / 2.0) var max_yaw_rad: float = deg_to_rad(80.0)
|
||||
@export_range(-PI / 2.0 + 0.01, 0) var min_pitch_rad: float = deg_to_rad(-75.0)
|
||||
@export_range(0, PI / 2.0 - 0.01) var max_pitch_rad: float = deg_to_rad(60.0)
|
||||
@ -52,10 +52,10 @@ func _ready():
|
||||
else:
|
||||
printerr("GripDetector Area3D node not found on CharacterPawn!")
|
||||
|
||||
if is_multiplayer_authority():
|
||||
if name == str(multiplayer.get_unique_id()):
|
||||
camera.make_current()
|
||||
camera.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
camera_pivot.global_transform = camera_anchor.get_global_transform_interpolated()
|
||||
@ -66,14 +66,25 @@ func _physics_process(_delta: float):
|
||||
|
||||
_reset_inputs()
|
||||
|
||||
|
||||
func _integrate_forces(state: PhysicsDirectBodyState3D):
|
||||
# Let the active movement controller apply its forces
|
||||
if not is_multiplayer_authority(): return
|
||||
super (state)
|
||||
|
||||
|
||||
# print("Integrating forces for pawn %s" % name)
|
||||
# print(" Move Input: %s, Vertical Input: %f, Roll Input: %f" % [_move_input, _vertical_input, _roll_input])
|
||||
|
||||
# Zero-G Movement
|
||||
if zero_g_movemement_component:
|
||||
# We pass the physics state
|
||||
zero_g_movemement_component.process_movement(state, _move_input, _vertical_input, _roll_input, _l_click_input, _r_click_input)
|
||||
|
||||
# EVA Suit Movement
|
||||
if eva_suit_component and zero_g_movemement_component.movement_state == ZeroGMovementComponent.MovementState.IDLE:
|
||||
eva_suit_component.process_eva_movement(state, _move_input, _vertical_input, _roll_input, _r_click_input)
|
||||
|
||||
|
||||
# --- Universal Rotation ---
|
||||
func _apply_mouse_rotation():
|
||||
if _pitch_yaw_input != Vector2.ZERO:
|
||||
@ -120,7 +131,8 @@ func _reset_head_yaw(delta: float):
|
||||
# Smoothly apply the reset target to the actual pivot rotation
|
||||
camera_anchor.rotation.y = lerpf(camera_anchor.rotation.y, 0.0, delta * head_turn_lerp_speed)
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
match what:
|
||||
NOTIFICATION_ENTER_TREE:
|
||||
set_multiplayer_authority(int(name))
|
||||
# TODO: Re-enable when multiplayer authority per pawn is functional
|
||||
# func _notification(what: int) -> void:
|
||||
# match what:
|
||||
# NOTIFICATION_ENTER_TREE:
|
||||
# set_multiplayer_authority(int(name))
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://7yc6a07xoccy"]
|
||||
[gd_scene load_steps=10 format=3 uid="uid://7yc6a07xoccy"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cdmmiixa75f3x" path="res://scenes/character/character_pawn_3d.gd" id="1_4frsu"]
|
||||
[ext_resource type="PackedScene" uid="uid://bm1rbv4tuppbc" path="res://scenes/character/eva_suit_controller.tscn" id="3_gnddn"]
|
||||
@ -9,6 +9,10 @@
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_6vm80"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_673rh"]
|
||||
radius = 0.1
|
||||
height = 1.0
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_gnddn"]
|
||||
radius = 1.0
|
||||
|
||||
@ -19,11 +23,18 @@ properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath(".:rotation")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
properties/2/path = NodePath("CameraPivot:rotation")
|
||||
properties/2/path = NodePath("CameraAnchor:rotation")
|
||||
properties/2/spawn = true
|
||||
properties/2/replication_mode = 2
|
||||
properties/2/replication_mode = 1
|
||||
properties/3/path = NodePath(".:linear_velocity")
|
||||
properties/3/spawn = false
|
||||
properties/3/replication_mode = 0
|
||||
properties/4/path = NodePath(".:angular_velocity")
|
||||
properties/4/spawn = false
|
||||
properties/4/replication_mode = 0
|
||||
|
||||
[node name="CharacterPawn3D" type="RigidBody3D" unique_id=288275840]
|
||||
physics_interpolation_mode = 1
|
||||
script = ExtResource("1_4frsu")
|
||||
metadata/_custom_type_script = "uid://cdmmiixa75f3x"
|
||||
|
||||
@ -34,16 +45,17 @@ shape = SubResource("CapsuleShape3D_6vm80")
|
||||
mesh = SubResource("CapsuleMesh_6vm80")
|
||||
|
||||
[node name="CameraAnchor" type="Marker3D" parent="." unique_id=462168232]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.7000000000000001, 0)
|
||||
|
||||
[node name="CameraPivot" type="Node3D" parent="." unique_id=794640520]
|
||||
[node name="CameraPivot" type="Node3D" parent="CameraAnchor" unique_id=794640520]
|
||||
physics_interpolation_mode = 1
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0)
|
||||
top_level = true
|
||||
|
||||
[node name="SpringArm" type="SpringArm3D" parent="CameraPivot" unique_id=1399441728]
|
||||
spring_length = 3.0
|
||||
[node name="SpringArm" type="SpringArm3D" parent="CameraAnchor/CameraPivot" unique_id=1399441728]
|
||||
shape = SubResource("CapsuleShape3D_673rh")
|
||||
spring_length = 2.0
|
||||
margin = 0.1
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="CameraPivot/SpringArm" unique_id=1779046272]
|
||||
[node name="Camera3D" type="Camera3D" parent="CameraAnchor/CameraPivot/SpringArm" unique_id=1779046272]
|
||||
far = 200000.0
|
||||
|
||||
[node name="GripDetector" type="Area3D" parent="." unique_id=734413990]
|
||||
@ -60,8 +72,9 @@ script = ExtResource("4_8jhjh")
|
||||
metadata/_custom_type_script = "uid://y3vo40i16ek3"
|
||||
|
||||
[node name="EVAMovementComponent" parent="." unique_id=1806288315 instance=ExtResource("3_gnddn")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.13939085347041424, 0.5148942200402955)
|
||||
|
||||
[node name="PlayerController3d" parent="." unique_id=1450011826 instance=ExtResource("4_bcy3l")]
|
||||
|
||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=732324183]
|
||||
replication_config = SubResource("SceneReplicationConfig_gnddn")
|
||||
|
||||
[node name="PlayerController3d" parent="." unique_id=1450011826 instance=ExtResource("4_bcy3l")]
|
||||
|
||||
@ -30,7 +30,7 @@ func _ready():
|
||||
|
||||
## Called by Pawn's _integrate_forces when suit equipped
|
||||
func process_eva_movement(state: PhysicsDirectBodyState3D, move_input: Vector2, vertical_input: float, roll_input: float, orienting_input: PlayerController3D.KeyInput):
|
||||
# --- 1. Handle Orient Input ---
|
||||
# --- 1. Handle Orient Input ---
|
||||
if orienting_input.pressed or orienting_input.held:
|
||||
_set_auto_orient_target(state)
|
||||
|
||||
@ -70,7 +70,6 @@ func _apply_floating_movement(state: PhysicsDirectBodyState3D, move_input: Vecto
|
||||
_is_auto_orienting = false # Cancel auto-orientation if rolling manually
|
||||
|
||||
var roll_acceleration = state.transform.basis.z * (-roll_input) * roll_torque_acceleration
|
||||
|
||||
# Apply the global torque vector using the pawn's helper function
|
||||
state.apply_torque(roll_acceleration)
|
||||
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bm1rbv4tuppbc"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bm1rbv4tuppbc"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d4jka2etva22s" path="res://scenes/character/eva_movement_component.gd" id="1_mb22m"]
|
||||
|
||||
[node name="EVASuitController" type="Node3D"]
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_rlk1u"]
|
||||
size = Vector3(1, 1, 0.4)
|
||||
|
||||
[node name="EVASuitController" type="Node3D" unique_id=241443807]
|
||||
script = ExtResource("1_mb22m")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1434211019]
|
||||
mesh = SubResource("BoxMesh_rlk1u")
|
||||
|
||||
@ -8,6 +8,7 @@ class_name PlayerController3D
|
||||
@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
|
||||
@ -18,9 +19,26 @@ class KeyInput:
|
||||
held = _h
|
||||
released = _r
|
||||
|
||||
func _to_dict():
|
||||
return {
|
||||
"pressed": pressed,
|
||||
"held": held,
|
||||
"released": released
|
||||
}
|
||||
|
||||
static func from_dict(dict: Dictionary) -> KeyInput:
|
||||
return KeyInput.new(dict.get("pressed", false), dict.get("held", false), dict.get("released", false))
|
||||
|
||||
func _ready():
|
||||
# If we are spawned dynamically, the owner_id might be set by GameManager.
|
||||
# Fallback: assume the pawn's name is the player ID (common pattern).
|
||||
if get_parent().name.is_valid_int():
|
||||
set_multiplayer_authority(int(get_parent().name))
|
||||
|
||||
func _unhandled_input(event: InputEvent):
|
||||
|
||||
# Check if THIS client is the owner of this controller
|
||||
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
|
||||
@ -28,6 +46,7 @@ func _unhandled_input(event: InputEvent):
|
||||
_mouse_motion_input += Vector2(event.relative.x, -event.relative.y)
|
||||
|
||||
func _physics_process(_delta):
|
||||
# Check if THIS client is the owner
|
||||
if not is_multiplayer_authority() or not is_instance_valid(possessed_pawn):
|
||||
return
|
||||
|
||||
@ -36,7 +55,7 @@ func _physics_process(_delta):
|
||||
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)
|
||||
server_process_rotation_input.rpc_id(1, sensitivity_modified_mouse_input)
|
||||
|
||||
# Reset the buffer
|
||||
_mouse_motion_input = Vector2.ZERO
|
||||
@ -50,29 +69,29 @@ func _physics_process(_delta):
|
||||
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)
|
||||
server_process_movement_input.rpc_id(1, move_vec, roll_input, vertical_input)
|
||||
server_process_interaction_input.rpc_id(1, interact_input._to_dict())
|
||||
server_process_clicks.rpc_id(1, l_input._to_dict(), r_input._to_dict())
|
||||
|
||||
@rpc("authority", "call_local")
|
||||
@rpc("any_peer", "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):
|
||||
@rpc("any_peer", "call_local")
|
||||
func server_process_interaction_input(interact_input: Dictionary):
|
||||
if is_instance_valid(possessed_pawn):
|
||||
possessed_pawn.set_interaction_input(interact_input)
|
||||
possessed_pawn.set_interaction_input(KeyInput.from_dict(interact_input))
|
||||
|
||||
@rpc("authority", "call_local")
|
||||
@rpc("any_peer", "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):
|
||||
@rpc("any_peer", "call_local")
|
||||
func server_process_clicks(l_action: Dictionary, r_action: Dictionary):
|
||||
if is_instance_valid(possessed_pawn):
|
||||
possessed_pawn.set_click_input(l_action, r_action)
|
||||
possessed_pawn.set_click_input(KeyInput.from_dict(l_action), KeyInput.from_dict(r_action))
|
||||
|
||||
func possess(pawn_to_control: CharacterPawn3D):
|
||||
possessed_pawn = pawn_to_control
|
||||
|
||||
@ -86,7 +86,7 @@ func _update_mass_and_inertia():
|
||||
|
||||
|
||||
func _integrate_forces(state: PhysicsDirectBodyState3D):
|
||||
if not is_multiplayer_authority(): return
|
||||
# if not is_multiplayer_authority(): return
|
||||
# Safety Check for Division by Zero
|
||||
if mass <= 0.0:
|
||||
accumulated_force = Vector3.ZERO
|
||||
|
||||
@ -65,7 +65,7 @@ func _try_spawn_waiting_player():
|
||||
|
||||
var pawn = player_pawns[player_id]
|
||||
|
||||
pawn.set_multiplayer_authority(player_id)
|
||||
# pawn.set_multiplayer_authority(player_id)
|
||||
|
||||
spawn_point.add_child(pawn)
|
||||
|
||||
@ -96,7 +96,7 @@ func _spawn_player_pawn(player_id: int):
|
||||
|
||||
player_pawns[player_id] = pawn
|
||||
|
||||
pawn.set_multiplayer_authority(player_id)
|
||||
# pawn.set_multiplayer_authority(player_id)
|
||||
|
||||
print("GameManager: Spawned 3D Pawn for player %d" % player_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user