diff --git a/Assets/Scenes/Game.unity b/Assets/Scenes/Game.unity index 0a958421e..3dbf13253 100644 --- a/Assets/Scenes/Game.unity +++ b/Assets/Scenes/Game.unity @@ -9476,14 +9476,15 @@ MonoBehaviour: m_EditorClassIdentifier: ProjectM.Client::ProjectM.Client.PrototypeCameraRig Pitch: 45 Yaw: 0 - Distance: 16 + Distance: 13 TargetHeight: 1 Orthographic: 0 FieldOfView: 55 OrthoSize: 10 FollowSharpness: 8 FallbackTarget: {x: 3, y: 0, z: 4} - AimLeadDistance: 2.5 + AimLeadDistance: 1 + LeadSharpness: 3 --- !u!1001 &331498972 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/_Project/Scripts/Client/Presentation/PrototypeCameraRig.cs b/Assets/_Project/Scripts/Client/Presentation/PrototypeCameraRig.cs index 2bc218b2f..31088e62f 100644 --- a/Assets/_Project/Scripts/Client/Presentation/PrototypeCameraRig.cs +++ b/Assets/_Project/Scripts/Client/Presentation/PrototypeCameraRig.cs @@ -63,7 +63,7 @@ namespace ProjectM.Client [Range(-180f, 180f)] public float Yaw = 0f; [Header("Framing")] - [Min(1f)] public float Distance = 16f; + [Min(1f)] public float Distance = 13f; [Tooltip("Raise the look-at point off the ground toward the character's centre of mass.")] public float TargetHeight = 1f; @@ -79,11 +79,16 @@ namespace ProjectM.Client public Vector3 FallbackTarget = new Vector3(3f, 0f, 4f); [Header("Movement look-ahead")] - [Tooltip("Shift the framed point this many world units toward where the player is aiming (0 = off). " + - "Leads the camera toward the cursor / stick so aiming feels grounded. Smoothed by FollowSharpness.")] - [Range(0f, 8f)] public float AimLeadDistance = 2.5f; + [Tooltip("Lead the framed point this many world units toward the player's MOVEMENT direction " + + "(0 = off, fully centred like Diablo / PoE). Kept subtle and eased in/out by LeadSharpness " + + "so starting, stopping, or reversing glides instead of bumping the view.")] + [Range(0f, 8f)] public float AimLeadDistance = 1f; + [Tooltip("How fast the look-ahead offset eases toward its target (lower = smoother/slower). " + + "Deliberately gentler than FollowSharpness so the lead glides instead of snapping with input.")] + [Min(0f)] public float LeadSharpness = 3f; Camera _cam; + Vector3 _leadOffset; // smoothed look-ahead offset (world units), eased toward the desired lead each frame void Awake() => _cam = GetComponent(); @@ -102,14 +107,19 @@ namespace ProjectM.Client Vector3 target = HasTarget ? (Vector3)TargetWorldPos : FallbackTarget; target.y += TargetHeight; - // Movement look-ahead: lead the framed point toward where the player is MOVING (not aiming). - // Leading toward AIM coupled the camera to the cursor: turning to face a near-cursor panned the cam, - // which re-projected the live mouse ray -> the aim swam (worst near the player). Smoothed by FollowSharpness. + // Movement look-ahead, smoothed INDEPENDENTLY of the follow. We lead toward MOVEMENT (not aim): + // leading toward AIM coupled the cam to the cursor and made the aim swim. The desired lead snaps + // with the raw input (full while held, zero when released); easing _leadOffset toward it at the + // gentle LeadSharpness rate is what removes the "bump" - start / stop / reverse glide, never pan. + Vector3 desiredLead = Vector3.zero; if (AimLeadDistance > 0f && HasTarget && math.lengthsq(TargetMoveDir) > 1e-6f) { float2 f = math.normalize(TargetMoveDir); - target += new Vector3(f.x, 0f, f.y) * AimLeadDistance; + desiredLead = new Vector3(f.x, 0f, f.y) * AimLeadDistance; } + float leadK = LeadSharpness <= 0f ? 1f : 1f - Mathf.Exp(-LeadSharpness * Time.deltaTime); + _leadOffset = Vector3.Lerp(_leadOffset, desiredLead, leadK); + target += _leadOffset; var rot = Quaternion.Euler(Pitch, Yaw, 0f); Vector3 desired = target - (rot * Vector3.forward) * Distance;