This commit is contained in:
2026-06-17 21:25:21 +07:00
parent 26a21f63bb
commit 922e2dcc98
34 changed files with 360 additions and 128 deletions

View File

@@ -135,6 +135,9 @@ namespace OnlyScove.Scripts
if (followTarget == null) return;
HandleViewTransition();
// If we are in transition, HandleViewTransition takes full control of the camera transform
if (_inTransition) return;
if (inputReader != null)
{
// Input-related updates are handled differently based on view mode
@@ -165,28 +168,28 @@ namespace OnlyScove.Scripts
targetDistance = collisionHandler.CheckCollision(focusPosition, rotationHandler.CurrentRotation, zoomHandler.CurrentDistance, zoomHandler.MinDistance);
characterFading.HandleCharacterFading(targetDistance);
occlusionTransparency.HandleTransparency(transform, focusPosition);
// Reset near clip plane for TPV if needed
if (_cam.nearClipPlane < 0.1f) _cam.nearClipPlane = 0.3f;
}
else // FirstPerson
{
// FPV specific calculations
// Player's horizontal rotation (body) follows mouse YAW
if (followTarget != null)
{
followTarget.rotation = rotationHandler.PlanarRotation; // Sync body to camera yaw
}
if (followTarget != null) followTarget.rotation = rotationHandler.PlanarRotation;
if (fpvTarget != null) fpvTarget.rotation = rotationHandler.CurrentRotation;
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)
transform.rotation = rotationHandler.CurrentRotation;
focusPosition = fpvTarget.position;
targetDistance = 0; // FPV has no distance to player
targetDistance = 0;
// Disable TPV-specific effects
characterFading.HandleCharacterFading(0); // Fully opaque character in FPV
occlusionTransparency.HandleTransparency(transform, fpvTarget.position); // Can still have occlusion transparency for environment in FPV
// AGGRESSIVE DEBUG FIX:
_cam.nearClipPlane = 0.01f;
_cam.farClipPlane = 2000f; // Ensure world isn't being cut off
_cam.cullingMask = -1; // Force camera to see EVERY LAYER
// Disable these temporarily to see if they are the cause
// characterFading.HandleCharacterFading(0.01f);
occlusionTransparency.ResetLastRenderer();
}
// Calculate target position using the currently set transform.rotation
@@ -203,6 +206,23 @@ namespace OnlyScove.Scripts
if (_inTransition) return; // Prevent multiple toggles during transition
_targetViewMode = (_currentViewMode == CameraViewMode.ThirdPerson) ? CameraViewMode.FirstPerson : CameraViewMode.ThirdPerson;
if (_targetViewMode == CameraViewMode.FirstPerson && fpvTarget == null)
{
Debug.LogWarning("[CameraController] Cannot switch to FPV: fpvTarget is not assigned!");
return;
}
// Initialize rotation handler immediately so PlanarRotation is correct during transition
if (_targetViewMode == CameraViewMode.FirstPerson)
{
rotationHandler.InitializeFPV(fpvTarget);
}
else
{
rotationHandler.Initialize(transform);
}
Debug.Log($"[CameraController] Toggling view from {_currentViewMode} to {_targetViewMode}");
_inTransition = true;
_transitionTimer = 0f;
@@ -217,11 +237,14 @@ namespace OnlyScove.Scripts
t = Mathf.Clamp01(t); // Clamp t between 0 and 1
// Smoothly interpolate parameters during transition
if (_currentViewMode == CameraViewMode.ThirdPerson && _targetViewMode == CameraViewMode.FirstPerson)
if (_targetViewMode == CameraViewMode.FirstPerson)
{
// TPV -> FPV transition
// Interpolate FOV
_cam.fieldOfView = Mathf.Lerp(dynamicFOV.CurrentTpvBaseFOV, fpvFOV, t);
// Adjust Near Clip Plane during transition to prevent blue screen (clipping)
_cam.nearClipPlane = Mathf.Lerp(0.3f, 0.01f, t);
// Rotate player body to match camera's intended horizontal look direction
if (followTarget != null)
@@ -230,14 +253,18 @@ namespace OnlyScove.Scripts
}
// Interpolate position and rotation
transform.position = Vector3.Lerp(transform.position, fpvTarget.position, t);
transform.rotation = Quaternion.Slerp(transform.rotation, fpvTarget.rotation, t);
if (fpvTarget != null)
{
transform.position = Vector3.Lerp(transform.position, fpvTarget.position, t);
transform.rotation = Quaternion.Slerp(transform.rotation, fpvTarget.rotation, t);
}
}
else if (_currentViewMode == CameraViewMode.FirstPerson && _targetViewMode == CameraViewMode.ThirdPerson)
else
{
// FPV -> TPV transition
// Interpolate FOV
_cam.fieldOfView = Mathf.Lerp(fpvFOV, dynamicFOV.CurrentTpvBaseFOV, t);
_cam.nearClipPlane = Mathf.Lerp(0.01f, 0.3f, t);
}
if (t >= 1f)
@@ -245,19 +272,10 @@ namespace OnlyScove.Scripts
_currentViewMode = _targetViewMode;
Debug.Log($"[CameraController] View transition complete. Current mode: {_currentViewMode}");
_inTransition = false;
// 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
// Ensure final values are set correctly
_cam.fieldOfView = (_currentViewMode == CameraViewMode.FirstPerson) ? fpvFOV : dynamicFOV.CurrentTpvBaseFOV;
_cam.nearClipPlane = (_currentViewMode == CameraViewMode.FirstPerson) ? 0.01f : 0.3f;
}
}

View File

@@ -23,6 +23,14 @@ namespace OnlyScove.Scripts
Vector3 direction = focusPosition - cameraTransform.position;
float distanceToPlayer = direction.magnitude;
// Prevent raycasting if we are too close (common in FPV)
if (distanceToPlayer < 0.1f)
{
ResetLastRenderer();
return;
}
RaycastHit hit;
if (Physics.Raycast(cameraTransform.position, direction.normalized, out hit, distanceToPlayer, transparencyLayers))
@@ -46,7 +54,7 @@ namespace OnlyScove.Scripts
}
}
private void ResetLastRenderer()
public void ResetLastRenderer()
{
if (_lastFadedRenderer != null)
{

View File

@@ -36,8 +36,14 @@ namespace OnlyScove.Scripts
// 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
Vector3 eulers = fpvTargetTransform.eulerAngles;
// Normalize angles to -180 to 180 range for clamping
_rotationX = eulers.x;
if (_rotationX > 180) _rotationX -= 360;
_rotationY = eulers.y;
_lastInputTime = Time.time;
CurrentRotation = fpvTargetTransform.rotation; // Camera starts matching fpvTarget rotation
}

View File

@@ -3,6 +3,8 @@ using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Hallucinate.UI
{

View File

@@ -3,6 +3,8 @@ using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Hallucinate.UI
{

View File

@@ -3,6 +3,8 @@ using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Hallucinate.UI
{

View File

@@ -3,6 +3,8 @@ using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Hallucinate.UI
{

View File

@@ -10,6 +10,8 @@ using DG.Tweening;
using OnlyScove.Scripts;
using Hallucinate.Audio;
using PrimeTween;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Hallucinate.UI
{

View File

@@ -5,6 +5,8 @@ using DG.Tweening;
using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
using OnlyScove.Scripts;
#if UNITY_EDITOR
using UnityEditor;