Fix camera jitter with disabled v-sync
This commit is contained in:
@ -22,6 +22,10 @@ GameManager="*res://scripts/singletons/game_manager.gd"
|
||||
Constants="*res://scripts/singletons/constants.gd"
|
||||
NetworkHandler="*res://scripts/network/network_handler.gd"
|
||||
|
||||
[display]
|
||||
|
||||
window/vsync/vsync_mode=0
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="space_simulation"
|
||||
@ -166,12 +170,14 @@ left_click={
|
||||
|
||||
[physics]
|
||||
|
||||
common/physics_jitter_fix=0.0
|
||||
3d/default_linear_damp=0.0
|
||||
3d/sleep_threshold_linear=0.0
|
||||
2d/default_gravity=0.0
|
||||
2d/default_gravity_vector=Vector2(0, 0)
|
||||
2d/default_linear_damp=0.0
|
||||
2d/sleep_threshold_linear=0.0
|
||||
common/physics_interpolation=true
|
||||
|
||||
[plugins]
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ var _r_click_input: PlayerController3D.KeyInput = PlayerController3D.KeyInput.ne
|
||||
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
|
||||
@export_range(0.1, PI / 2.0) var max_yaw_rad: float = deg_to_rad(80.0)
|
||||
@ -54,7 +55,12 @@ func _ready():
|
||||
|
||||
if is_multiplayer_authority():
|
||||
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()
|
||||
|
||||
|
||||
func _physics_process(delta: float):
|
||||
# 1. Apply Mouse Rotation (Universal head look)
|
||||
@ -86,15 +92,15 @@ func _physics_process(delta: float):
|
||||
# --- Universal Rotation ---
|
||||
func _apply_mouse_rotation():
|
||||
if _pitch_yaw_input != Vector2.ZERO:
|
||||
camera_pivot.rotate_y(-_pitch_yaw_input.x)
|
||||
camera_anchor.rotate_y(-_pitch_yaw_input.x)
|
||||
|
||||
# Apply Pitch LOCALLY to pivot
|
||||
camera_pivot.rotate_object_local(Vector3.RIGHT, _pitch_yaw_input.y)
|
||||
camera_pivot.rotation.x = clamp(camera_pivot.rotation.x, min_pitch_rad, max_pitch_rad)
|
||||
camera_anchor.rotate_object_local(Vector3.RIGHT, _pitch_yaw_input.y)
|
||||
camera_anchor.rotation.x = clamp(camera_anchor.rotation.x, min_pitch_rad, max_pitch_rad)
|
||||
|
||||
_pitch_yaw_input = Vector2.ZERO
|
||||
|
||||
camera_pivot.rotation.z = 0.0
|
||||
camera_anchor.rotation.z = 0.0
|
||||
|
||||
# --- Universal Integration & Collision ---
|
||||
func _integrate_angular_velocity(delta: float):
|
||||
@ -149,7 +155,7 @@ func _on_ladder_area_entered(area: Area3D): if area.is_in_group("Ladders"): over
|
||||
func _on_ladder_area_exited(area: Area3D): if area == overlapping_ladder_area: overlapping_ladder_area = null
|
||||
func _reset_head_yaw(delta: float):
|
||||
# Smoothly apply the reset target to the actual pivot rotation
|
||||
camera_pivot.rotation.y = lerpf(camera_pivot.rotation.y, 0.0, delta * head_turn_lerp_speed)
|
||||
camera_anchor.rotation.y = lerpf(camera_anchor.rotation.y, 0.0, delta * head_turn_lerp_speed)
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
match what:
|
||||
|
||||
@ -19,18 +19,9 @@ properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath(".:rotation")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
properties/2/path = NodePath("CameraPivot/SpringArm/Camera3D:position")
|
||||
properties/2/path = NodePath("CameraPivot:rotation")
|
||||
properties/2/spawn = true
|
||||
properties/2/replication_mode = 1
|
||||
properties/3/path = NodePath("CameraPivot/SpringArm/Camera3D:rotation")
|
||||
properties/3/spawn = true
|
||||
properties/3/replication_mode = 1
|
||||
properties/4/path = NodePath("CameraPivot:position")
|
||||
properties/4/spawn = true
|
||||
properties/4/replication_mode = 1
|
||||
properties/5/path = NodePath("CameraPivot:rotation")
|
||||
properties/5/spawn = true
|
||||
properties/5/replication_mode = 1
|
||||
properties/2/replication_mode = 2
|
||||
|
||||
[node name="CharacterPawn3D" type="CharacterBody3D"]
|
||||
script = ExtResource("1_4frsu")
|
||||
@ -42,8 +33,12 @@ shape = SubResource("CapsuleShape3D_6vm80")
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("CapsuleMesh_6vm80")
|
||||
|
||||
[node name="CameraAnchor" type="Marker3D" parent="."]
|
||||
|
||||
[node name="CameraPivot" type="Node3D" parent="."]
|
||||
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"]
|
||||
spring_length = 3.0
|
||||
|
||||
@ -3,9 +3,7 @@ extends Node # Or Node3D if thrusters need specific positions later
|
||||
class_name EVAMovementComponent
|
||||
|
||||
## References (Set automatically in _ready)
|
||||
var pawn: CharacterBody3D
|
||||
var camera_pivot: Node3D
|
||||
var camera: Camera3D
|
||||
var pawn: CharacterPawn3D
|
||||
|
||||
## EVA Parameters (Moved from ZeroGPawn)
|
||||
@export var orientation_speed: float = 2.0 # Used for orienting body to camera
|
||||
@ -21,24 +19,23 @@ var stabilization_target: Node3D = null
|
||||
var stabilization_enabled: bool = false
|
||||
|
||||
func _ready():
|
||||
pawn = get_parent() as CharacterBody3D
|
||||
pawn = get_parent() as CharacterPawn3D
|
||||
if not pawn:
|
||||
printerr("EVAMovementComponent must be a child of a CharacterBody3D pawn.")
|
||||
return
|
||||
# Make sure the paths match your CharacterPawn scene structure
|
||||
camera_pivot = pawn.get_node_or_null("CameraPivot")
|
||||
if camera_pivot:
|
||||
camera = camera_pivot.get_node_or_null("SpringArm/Camera3D") # Adjusted path for SpringArm
|
||||
# if camera_anchor:
|
||||
# camera = camera_anchor.get_node_or_null("SpringArm/Camera3D") # Adjusted path for SpringArm
|
||||
|
||||
if not camera_pivot or not camera:
|
||||
printerr("EVAMovementComponent could not find CameraPivot/SpringArm/Camera3D on pawn.")
|
||||
# if not camera_anchor or not camera:
|
||||
# printerr("EVAMovementComponent could not find CameraPivot/SpringArm/Camera3D on pawn.")
|
||||
|
||||
# --- Standardized Movement API ---
|
||||
|
||||
## Called by Pawn's _physics_process when in FLOATING state with suit equipped
|
||||
func process_movement(delta: float, move_input: Vector2, vertical_input: float, roll_input: float, orienting_input: PlayerController3D.KeyInput):
|
||||
var orienting = orienting_input.held
|
||||
if not is_instance_valid(pawn) or not camera: return
|
||||
if not is_instance_valid(pawn): return
|
||||
if orienting:
|
||||
_orient_pawn(delta)
|
||||
|
||||
@ -109,14 +106,14 @@ func _apply_floating_movement(delta: float, move_input: Vector2, vertical_input:
|
||||
# --- Auto-Orientation Logic ---
|
||||
func _orient_pawn(delta: float):
|
||||
# 1. Determine Target Orientation Basis
|
||||
var initial_cam_basis = camera_pivot.global_basis
|
||||
var target_forward = -camera_pivot.global_basis.z # Look where camera looks
|
||||
var initial_cam_basis = pawn.camera_anchor.global_basis
|
||||
var target_forward = -pawn.camera_anchor.global_basis.z # Look where camera looks
|
||||
var target_up = Vector3.UP # Default up initially
|
||||
|
||||
# --- THE FIX: Adjust how target_up is calculated ---
|
||||
# Calculate velocity components relative to camera orientation
|
||||
var _forward_velocity_component = pawn.velocity.dot(target_forward)
|
||||
var _right_velocity_component = pawn.velocity.dot(camera_pivot.global_basis.x)
|
||||
var _right_velocity_component = pawn.velocity.dot(pawn.camera_anchor.global_basis.x)
|
||||
|
||||
# Only apply strong "feet trailing" if significant forward/backward movement dominates
|
||||
# and we are actually moving.
|
||||
@ -154,7 +151,7 @@ func _orient_pawn(delta: float):
|
||||
pawn.global_basis = new_basis
|
||||
|
||||
# 4. Reset camera pivot to rotation to what it was before we rotated the parent
|
||||
camera_pivot.global_basis = initial_cam_basis
|
||||
pawn.camera_anchor.global_basis = initial_cam_basis
|
||||
|
||||
# --- Add new function placeholder ---
|
||||
# TODO: Implement Rotation Stabilization Logic
|
||||
|
||||
@ -49,22 +49,22 @@ func _physics_process(_delta):
|
||||
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("any_peer", "call_local")
|
||||
@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("any_peer", "call_local")
|
||||
@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("any_peer", "call_local")
|
||||
func server_process_rotation_input(input: Vector2):
|
||||
@rpc("authority", "call_local")
|
||||
func server_process_rotation_input(input: Vector2):
|
||||
if is_instance_valid(possessed_pawn):
|
||||
possessed_pawn.set_rotation_input(input)
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
@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)
|
||||
|
||||
Reference in New Issue
Block a user