Fixed some camera jittering
This commit is contained in:
@@ -8,7 +8,7 @@ const COLLISION_MARGIN:float = 0.3
|
|||||||
|
|
||||||
@export_category("Orbit")
|
@export_category("Orbit")
|
||||||
@export var distance:float = 7.0
|
@export var distance:float = 7.0
|
||||||
@export var minDistance:float = 5.0
|
@export var minDistance:float = 2.0
|
||||||
@export var orbitSensitivity:float = 144.0
|
@export var orbitSensitivity:float = 144.0
|
||||||
@export var orbitAcceleration:float = 600.0
|
@export var orbitAcceleration:float = 600.0
|
||||||
@export var pitchMin:float = -80.0
|
@export var pitchMin:float = -80.0
|
||||||
@@ -106,10 +106,15 @@ func _process(delta:float) -> void:
|
|||||||
global_transform.origin = finalPos
|
global_transform.origin = finalPos
|
||||||
look_at(pivot, Vector3.UP)
|
look_at(pivot, Vector3.UP)
|
||||||
|
|
||||||
# Feed actual position back so camera input resumes from where it really is
|
# Lerp _yaw/_pitch toward the actual constrained position so input resumes
|
||||||
|
# smoothly, and small per-frame raycast variations don't oscillate.
|
||||||
var actualDir:Vector3 = (finalPos - pivot).normalized()
|
var actualDir:Vector3 = (finalPos - pivot).normalized()
|
||||||
_pitch = rad_to_deg(asin(clamp(actualDir.y, -1.0, 1.0)))
|
var targetPitch:float = rad_to_deg(asin(clamp(actualDir.y, -1.0, 1.0)))
|
||||||
_yaw = rad_to_deg(atan2(actualDir.x, actualDir.z))
|
var targetYaw:float = rad_to_deg(atan2(actualDir.x, actualDir.z))
|
||||||
|
var feedbackRate:float = minf(20.0 * delta, 1.0)
|
||||||
|
_pitch = lerpf(_pitch, targetPitch, feedbackRate)
|
||||||
|
var yawDiff:float = fposmod(targetYaw - _yaw + 180.0, 360.0) - 180.0
|
||||||
|
_yaw += lerpf(0.0, yawDiff, feedbackRate)
|
||||||
|
|
||||||
# Returns the camera world position, respecting both minDistance and terrain.
|
# Returns the camera world position, respecting both minDistance and terrain.
|
||||||
func _resolvePosition(pivot:Vector3, dir:Vector3) -> Vector3:
|
func _resolvePosition(pivot:Vector3, dir:Vector3) -> Vector3:
|
||||||
@@ -125,17 +130,14 @@ func _resolvePosition(pivot:Vector3, dir:Vector3) -> Vector3:
|
|||||||
var hitNormal:Vector3 = hit["normal"]
|
var hitNormal:Vector3 = hit["normal"]
|
||||||
var hitDist:float = (hit["position"] - pivot).length() - COLLISION_MARGIN
|
var hitDist:float = (hit["position"] - pivot).length() - COLLISION_MARGIN
|
||||||
|
|
||||||
if hitDist >= minDistance:
|
|
||||||
# Terrain is beyond minDistance — simple pull-back along the ray
|
|
||||||
return pivot + dir * hitDist
|
|
||||||
|
|
||||||
# Terrain is closer than minDistance.
|
|
||||||
# Find the closest point on the circle formed by intersecting:
|
# Find the closest point on the circle formed by intersecting:
|
||||||
# • the minDistance sphere centred on pivot
|
# • a sphere of radius max(hitDist, minDistance) centred on pivot
|
||||||
# • the terrain surface plane (inset by COLLISION_MARGIN along its normal)
|
# • the terrain surface plane (inset by COLLISION_MARGIN along its normal)
|
||||||
# That point is exactly minDistance from the pivot and flush with the surface.
|
# Using max() makes both cases meet exactly at hitDist == minDistance,
|
||||||
|
# eliminating the branch discontinuity that causes jitter at the boundary.
|
||||||
|
var targetDist:float = maxf(hitDist, minDistance)
|
||||||
var d:float = hitNormal.dot(pivot - hit["position"]) - COLLISION_MARGIN
|
var d:float = hitNormal.dot(pivot - hit["position"]) - COLLISION_MARGIN
|
||||||
var rSq:float = minDistance * minDistance - d * d
|
var rSq:float = targetDist * targetDist - d * d
|
||||||
if rSq <= 0.0:
|
if rSq <= 0.0:
|
||||||
# Pivot is itself nearly on the terrain — sit at the tangent point
|
# Pivot is itself nearly on the terrain — sit at the tangent point
|
||||||
return pivot - hitNormal * d
|
return pivot - hitNormal * d
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ size = Vector3(0.689728, 0.52002, 0.796997)
|
|||||||
size = Vector3(1.3, 1.3, 1.3)
|
size = Vector3(1.3, 1.3, 1.3)
|
||||||
|
|
||||||
[node name="Entity" type="CharacterBody3D"]
|
[node name="Entity" type="CharacterBody3D"]
|
||||||
|
collision_layer = 2
|
||||||
script = ExtResource("1_8e8ef")
|
script = ExtResource("1_8e8ef")
|
||||||
entityId = "35ce980f-3df9-4e09-b365-1a228948cf78"
|
entityId = "35ce980f-3df9-4e09-b365-1a228948cf78"
|
||||||
metadata/_custom_type_script = "uid://c8146flooxeue"
|
metadata/_custom_type_script = "uid://c8146flooxeue"
|
||||||
|
|||||||
Reference in New Issue
Block a user