From ed67b8258d016bb8769795a8d05ac6eacd348d17 Mon Sep 17 00:00:00 2001 From: Scove <104053980+Scove-Metalreal@users.noreply.github.com> Date: Fri, 27 Mar 2026 20:20:06 +0700 Subject: [PATCH] Update --- .idea/.idea.HALLUCINATE/.idea/workspace.xml | 8 ++- .../Camera Controller/CameraController.cs | 50 +++++++++++++------ .../CameraRotationHandler.cs | 49 ++++++++++++++---- .../Player Controller/PlayerMoveState.cs | 5 ++ 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/.idea/.idea.HALLUCINATE/.idea/workspace.xml b/.idea/.idea.HALLUCINATE/.idea/workspace.xml index 733f2115..b8c8ca80 100644 --- a/.idea/.idea.HALLUCINATE/.idea/workspace.xml +++ b/.idea/.idea.HALLUCINATE/.idea/workspace.xml @@ -6,11 +6,9 @@ - - - + - @@ -103,7 +101,7 @@ 1774531360140 - + diff --git a/Assets/Scripts/Camera Controller/CameraController.cs b/Assets/Scripts/Camera Controller/CameraController.cs index a34581ea..da7690c9 100644 --- a/Assets/Scripts/Camera Controller/CameraController.cs +++ b/Assets/Scripts/Camera Controller/CameraController.cs @@ -26,7 +26,7 @@ namespace OnlyScove.Scripts [Header("First Person View Settings")] [SerializeField] Transform fpvTarget; // Specific transform on the player (e.g., eye level) [SerializeField] float fpvPositionSmoothTime = 0.05f; - [SerializeField] float fpvRotationSmoothTime = 0.05f; + [SerializeField] float fpvRotationSmoothTime = 20f; [SerializeField] float fpvFOV = 80f; [SerializeField] float transitionDuration = 0.3f; [SerializeField] float tpvBaseFOV = 60f; // Existing base FOV for TPV @@ -38,6 +38,8 @@ namespace OnlyScove.Scripts private float _transitionTimer = 0f; private bool _inTransition = false; + public CameraViewMode CurrentViewMode => _currentViewMode; + // Properties to get current smoothing values based on view mode private float CurrentPositionSmoothTime => _currentViewMode == CameraViewMode.FirstPerson ? fpvPositionSmoothTime : positionSmoothTime; private float CurrentRotationSmoothTime => _currentViewMode == CameraViewMode.FirstPerson ? fpvRotationSmoothTime : rotationSmoothTime; @@ -97,7 +99,7 @@ namespace OnlyScove.Scripts if (_currentViewMode == CameraViewMode.ThirdPerson) { // TPV specific calculations - transform.rotation = rotationHandler.CurrentRotation; // Set rotation from handler + transform.rotation = rotationHandler.CurrentRotation; // Set camera rotation from handler focusPosition = followTarget.position + rotationHandler.CurrentRotation * new Vector3(framingOffset.x + sideBias.CurrentSideBias, framingOffset.y, 0); targetDistance = collisionHandler.CheckCollision(focusPosition, rotationHandler.CurrentRotation, zoomHandler.CurrentDistance, zoomHandler.MinDistance); characterFading.HandleCharacterFading(targetDistance); @@ -106,8 +108,18 @@ namespace OnlyScove.Scripts else // FirstPerson { // FPV specific calculations - // Rotation is derived from fpvTarget, not input from rotationHandler - transform.rotation = fpvTarget.rotation; // Directly set FPV rotation + // Player's horizontal rotation (body) follows mouse YAW + if (followTarget != null) + { + followTarget.rotation = rotationHandler.PlanarRotation; // Sync body to camera yaw + } + + if (fpvTarget != null) + { + fpvTarget.rotation = rotationHandler.CurrentRotation; // Sync head/eyes to full camera rotation + } + + transform.rotation = rotationHandler.CurrentRotation; // Set camera rotation from handler (which includes vertical) focusPosition = fpvTarget.position; targetDistance = 0; // FPV has no distance to player @@ -117,8 +129,7 @@ namespace OnlyScove.Scripts } // Calculate target position using the currently set transform.rotation - Vector3 targetPosition = focusPosition - transform.rotation * new Vector3(0, 0, targetDistance); - + Vector3 targetPosition = focusPosition - transform.rotation * new Vector3(0, 0, targetDistance); // Handle camera shake shakeManager.HandleShake(); @@ -131,6 +142,7 @@ namespace OnlyScove.Scripts if (_inTransition) return; // Prevent multiple toggles during transition _targetViewMode = (_currentViewMode == CameraViewMode.ThirdPerson) ? CameraViewMode.FirstPerson : CameraViewMode.ThirdPerson; + Debug.Log($"[CameraController] Toggling view from {_currentViewMode} to {_targetViewMode}"); _inTransition = true; _transitionTimer = 0f; } @@ -149,6 +161,13 @@ namespace OnlyScove.Scripts // TPV -> FPV transition // Interpolate FOV _cam.fieldOfView = Mathf.Lerp(dynamicFOV.CurrentTpvBaseFOV, fpvFOV, t); + + // Rotate player body to match camera's intended horizontal look direction + if (followTarget != null) + { + followTarget.rotation = Quaternion.Slerp(followTarget.rotation, rotationHandler.PlanarRotation, t); + } + // Interpolate position and rotation transform.position = Vector3.Lerp(transform.position, fpvTarget.position, t); transform.rotation = Quaternion.Slerp(transform.rotation, fpvTarget.rotation, t); @@ -158,23 +177,26 @@ namespace OnlyScove.Scripts // FPV -> TPV transition // Interpolate FOV _cam.fieldOfView = Mathf.Lerp(fpvFOV, dynamicFOV.CurrentTpvBaseFOV, t); - // For position and rotation, we'll let the TPV logic take over after transition. - // If a smooth exit from FPV to TPV is desired for position/rotation, - // more complex calculations would be needed here to store TPV target position/rotation at the start. } if (t >= 1f) { _currentViewMode = _targetViewMode; + Debug.Log($"[CameraController] View transition complete. Current mode: {_currentViewMode}"); _inTransition = false; - // Re-initialize rotation handler for new view mode context - rotationHandler.Initialize(transform); + + // Initialize rotation handler based on new view mode + if (_currentViewMode == CameraViewMode.FirstPerson && fpvTarget != null) + { + rotationHandler.InitializeFPV(fpvTarget); // Initialize FPV rotation handler + } + else + { + rotationHandler.Initialize(transform); // Initialize TPV rotation handler + } // Ensure FOV is set correctly at the end of transition _cam.fieldOfView = (_currentViewMode == CameraViewMode.FirstPerson) ? fpvFOV : dynamicFOV.CurrentTpvBaseFOV; - - // For FPV, ensure camera matches fpvTarget immediately after transition - // This is already handled by the `transform.position = Vector3.SmoothDamp...` and `transform.rotation = fpvTarget.rotation` in Update } } diff --git a/Assets/Scripts/Camera Controller/CameraRotationHandler.cs b/Assets/Scripts/Camera Controller/CameraRotationHandler.cs index 473ba957..55f847be 100644 --- a/Assets/Scripts/Camera Controller/CameraRotationHandler.cs +++ b/Assets/Scripts/Camera Controller/CameraRotationHandler.cs @@ -1,5 +1,5 @@ using UnityEngine; -using static OnlyScove.Scripts.CameraController; +using static OnlyScove.Scripts.CameraController; namespace OnlyScove.Scripts { @@ -22,8 +22,8 @@ namespace OnlyScove.Scripts private float _rotationY; private float _lastInputTime; - public Quaternion CurrentRotation { get; private set; } - public Quaternion PlanarRotation => Quaternion.Euler(0f, _rotationY, 0f); + public Quaternion CurrentRotation { get; private set; } // Camera's actual rotation + public Quaternion PlanarRotation => Quaternion.Euler(0f, _rotationY, 0f); // Horizontal rotation (for player body in FPV) public void Initialize(Transform cameraTransform) { @@ -33,10 +33,27 @@ namespace OnlyScove.Scripts CurrentRotation = cameraTransform.rotation; } + // New method to initialize rotation specifically for FPV + public void InitializeFPV(Transform fpvTargetTransform) + { + _rotationX = fpvTargetTransform.localEulerAngles.x; // Use local rotation for vertical angle in FPV + _rotationY = fpvTargetTransform.eulerAngles.y; // Use world rotation for horizontal angle + _lastInputTime = Time.time; + CurrentRotation = fpvTargetTransform.rotation; // Camera starts matching fpvTarget rotation + } + + public void HandleRotation(InputReader inputReader, Transform followTarget, float rotationSmoothTime, CameraViewMode viewMode) { - if (inputReader == null || viewMode == CameraViewMode.FirstPerson) return; // Only process input in TPV + if (inputReader == null) return; + // Debug for rotation + if (inputReader.LookInput.sqrMagnitude > 0.001f) + { + Debug.Log($"[CameraRotationHandler] LookInput: {inputReader.LookInput}, _rotationX: {_rotationX}, _rotationY: {_rotationY}, ViewMode: {viewMode}"); + } + + // Update _lastInputTime regardless of view mode if there's look input if (inputReader.LookInput.magnitude > 0.01f) { _lastInputTime = Time.time; @@ -50,17 +67,27 @@ namespace OnlyScove.Scripts _rotationY += inputReader.LookInput.x * invertXVal * sensitivity * Time.deltaTime; - // Auto-Correction - if (useAutoRotation && Time.time - _lastInputTime > autoRotateDelay) + if (viewMode == CameraViewMode.ThirdPerson) { - if (inputReader.MoveInput.magnitude > 0.1f) + // Auto-Correction for TPV + if (useAutoRotation && Time.time - _lastInputTime > autoRotateDelay) { - float targetYaw = followTarget.eulerAngles.y; - _rotationY = Mathf.LerpAngle(_rotationY, targetYaw, autoRotateSpeed * Time.deltaTime); + if (inputReader.MoveInput.magnitude > 0.1f) + { + float targetYaw = followTarget.eulerAngles.y; + _rotationY = Mathf.LerpAngle(_rotationY, targetYaw, autoRotateSpeed * Time.deltaTime); + } } + Quaternion targetRotation = Quaternion.Euler(_rotationX, _rotationY, 0f); + CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, rotationSmoothTime * Time.deltaTime); + } + else // FirstPerson + { + // In FPV, CurrentRotation *is* the camera's rotation (head rotation) + // The horizontal part of this (_rotationY) will also be used to rotate the player's body. + Quaternion targetRotation = Quaternion.Euler(_rotationX, _rotationY, 0f); + CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, rotationSmoothTime * Time.deltaTime); } - Quaternion targetRotation = Quaternion.Euler(_rotationX, _rotationY, 0f); - CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, rotationSmoothTime * Time.deltaTime); } } } diff --git a/Assets/Scripts/Player Controller/PlayerMoveState.cs b/Assets/Scripts/Player Controller/PlayerMoveState.cs index 01d8d195..4040fa2a 100644 --- a/Assets/Scripts/Player Controller/PlayerMoveState.cs +++ b/Assets/Scripts/Player Controller/PlayerMoveState.cs @@ -36,6 +36,11 @@ namespace OnlyScove.Scripts Vector3 inputDir = new Vector3(input.x, 0, input.y).normalized; Vector3 moveDirection = stateMachine.Cam != null ? stateMachine.Cam.PlanarRotation * inputDir : inputDir; + if (stateMachine.Cam != null) + { + Debug.Log($"[PlayerMoveState] View: {(stateMachine.Cam.PlanarRotation.eulerAngles.y)}, InputDir: {inputDir}, MoveDir: {moveDirection}, PlayerRot: {stateMachine.transform.rotation.eulerAngles.y}"); + } + Vector3 velocity = moveDirection * stateMachine.RunSpeed; if (stateMachine.IsGrounded && stateMachine.VelocityY < 0)