From 7f106dbe46731fc9dde0786a22f37607a056ea3e Mon Sep 17 00:00:00 2001 From: CAtlas0784 Date: Sat, 31 Oct 2026 22:55:41 +0700 Subject: [PATCH] fix(camera): use Tab toggle only and remove camera snapping bounce --- scripts/freecam.lua | 61 +++++++++++++-------------------------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/scripts/freecam.lua b/scripts/freecam.lua index 69ccb5b..ced628d 100644 --- a/scripts/freecam.lua +++ b/scripts/freecam.lua @@ -352,48 +352,22 @@ local function update_facecam(cam, settings) show_ui('[FaceCam: ON] Distance: ' .. string.format('%.1f', distance) .. '') end - -- Target: Center of the face/eyes (~0.08m above neck pivot Head_M) - local eyeOffset = 0.08 - local faceCenter = head.position + Vector3(0, eyeOffset, 0) - - -- Rotate according to head bone in full 3D (user request: "ให้มันหมุนตามหัวเหมือนเดิม") - -- In HSR rigs, head.up points directly outward from the face (facial normal). - local fwd = head.up - if not fwd or fwd.sqrMagnitude < 0.001 then - fwd = root and root.forward or Vector3(0, 0, 1) - else - fwd = fwd.normalized + local target = head.position + local anchor = _G.__FC_FACE_ANCHOR + if not anchor or anchor.transform.parent ~= head then + if anchor then pcall(function() CS.UnityEngine.Object.Destroy(anchor) end) end + anchor = GameObject('GaC_FaceCamAnchor') + anchor.transform:SetParent(head, false) + _G.__FC_FACE_ANCHOR = anchor end - local desiredPos = faceCenter + fwd * distance - local lookDir = faceCenter - desiredPos + -- หมุนตามหัวเหมือนเดิม: ล็อคตรงหน้าหัวตัวละครแบบ 1:1 ไม่หน่วง ไม่ดีเลย์ และไม่มีการเด้งไปมา + local direction = head.up + anchor.transform.position = target + direction * distance + anchor.transform.rotation = CS.UnityEngine.Quaternion.LookRotation(target - anchor.transform.position, Vector3.up) - -- Prevent camera gimbal flip when head tilts steeply up or down - local upVector = Vector3.up - if math.abs(fwd.y) > 0.88 then - upVector = root and root.up or Vector3(0, 0, 1) - end - local desiredRot = CS.UnityEngine.Quaternion.LookRotation(lookDir, upVector) - - -- Dynamic snapping & smoothing: - -- If character dashed / teleported during an attack animation (gap > 3.0m), - -- snap immediately so the camera stays solidly glued to the head and never detaches! - local dt = Time.unscaledDeltaTime or 0.016 - if dt <= 0 or dt > 0.1 then dt = 0.016 end - - local currentCamPos = cam.transform.position - local distGap = (currentCamPos - desiredPos).magnitude - - if distGap > 3.0 or _G.__FC_LAST_TRACKED_ENTITY ~= _G.__FC_FACE_ENTITY or not _G.__FC_POS then - _G.__FC_LAST_TRACKED_ENTITY = _G.__FC_FACE_ENTITY - cam.transform.position = desiredPos - cam.transform.rotation = desiredRot - else - local smoothSpeed = 22.0 - local factor = math.min(1.0, dt * smoothSpeed) - cam.transform.position = Vector3.Lerp(currentCamPos, desiredPos, factor) - cam.transform.rotation = CS.UnityEngine.Quaternion.Slerp(cam.transform.rotation, desiredRot, factor) - end + cam.transform.position = anchor.transform.position + cam.transform.rotation = anchor.transform.rotation _G.__FC_POS = cam.transform.position _G.__FC_EULER = cam.transform.eulerAngles @@ -555,9 +529,8 @@ function _G.__FREECAM_TICK() _G.__FC_INPUT_FRAME = frame -- Hotkey Handling: - -- Tab: Main toggle (as set by user) - -- F8 / Insert: Alternate toggles - if Input.GetKeyDown(KeyCode.Tab) or Input.GetKeyDown(KeyCode.F8) or Input.GetKeyDown(KeyCode.Insert) then + -- Tab: Toggle (as set by user) + if Input.GetKeyDown(KeyCode.Tab) then _G.__FREECAM_ENABLED = not _G.__FREECAM_ENABLED _G.__FC_LAST_TIME = nil local cam = get_active_cam() @@ -701,11 +674,11 @@ function _G.__FREECAM_TICK() local cameraAdjusted = false if Input.GetKeyDown(KeyCode.Equals) or Input.GetKeyDown(KeyCode.KeypadPlus) then _G.__FREECAM_SPEED = math.min(300.0, _G.__FREECAM_SPEED * 1.5) - show_ui("[FreeCam: ON] Speed: " .. string.format("%.1f", _G.__FREECAM_SPEED) .. " | Arrows: Fly | PgUp/PgDn: Height | RMB: Look | F8/Insert: Close | F7: FaceCam") + show_ui("[FreeCam: ON] Speed: " .. string.format("%.1f", _G.__FREECAM_SPEED) .. " | Arrows: Fly | PgUp/PgDn: Height | RMB: Look | Tab: Close") end if Input.GetKeyDown(KeyCode.Minus) or Input.GetKeyDown(KeyCode.KeypadMinus) then _G.__FREECAM_SPEED = math.max(0.5, _G.__FREECAM_SPEED / 1.5) - show_ui("[FreeCam: ON] Speed: " .. string.format("%.1f", _G.__FREECAM_SPEED) .. " | Arrows: Fly | PgUp/PgDn: Height | RMB: Look | F8/Insert: Close | F7: FaceCam") + show_ui("[FreeCam: ON] Speed: " .. string.format("%.1f", _G.__FREECAM_SPEED) .. " | Arrows: Fly | PgUp/PgDn: Height | RMB: Look | Tab: Close") end -- Raw Unity mouse input remains available to the camera while