This commit is contained in:
2026-06-18 03:12:50 +07:00
parent 81a6798e96
commit d2edd88f9a
30 changed files with 439 additions and 4112 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: c00a96cb2611f4c419de81de31da6cda
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,31 +0,0 @@
using UnityEngine;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraCharacterFading
{
[Header("Character Fading")]
[SerializeField] private bool useCharacterFading = true;
[SerializeField] private float minVisibleDistance = 1.2f;
[SerializeField] private float fullyHiddenDistance = 0.6f;
[SerializeField] private Renderer[] characterRenderers;
public void HandleCharacterFading(float currentDistance)
{
if (!useCharacterFading || characterRenderers == null || characterRenderers.Length == 0) return;
float alpha = Mathf.InverseLerp(fullyHiddenDistance, minVisibleDistance, currentDistance);
foreach (var renderer in characterRenderers)
{
if (renderer != null)
{
Color color = renderer.material.color;
color.a = alpha;
renderer.material.color = color;
}
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 5d5d8d2fa005cd34a92ee259df535130

View File

@@ -1,24 +0,0 @@
using UnityEngine;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraCollisionHandler
{
[Header("Collision Settings")]
[SerializeField] private LayerMask collisionLayers;
[SerializeField] private float cameraRadius = 0.2f;
public float CheckCollision(Vector3 focusPosition, Quaternion currentRotation, float targetDistance, float minimumDistanceAllowed)
{
RaycastHit hit;
Vector3 rayStart = focusPosition;
Vector3 rayDirection = currentRotation * Vector3.back;
if (Physics.SphereCast(rayStart, cameraRadius, rayDirection, out hit, targetDistance, collisionLayers))
{
return Mathf.Max(minimumDistanceAllowed, hit.distance - 0.1f);
}
return targetDistance;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 57a506759df838e42b577ebdb542500b

View File

@@ -1,294 +0,0 @@
using System; // For Action event
using UnityEngine;
namespace OnlyScove.Scripts
{
public class CameraController : MonoBehaviour
{
public enum CameraViewMode { ThirdPerson, FirstPerson }
public InputReader inputReader; // Đổi từ [SerializeField] thành public
public Transform followTarget; // Player's root for TPV
[SerializeField] float positionSmoothTime = 0.12f;
[SerializeField] float rotationSmoothTime = 5f;
[SerializeField] Vector2 framingOffset;
[Header("Components")]
[SerializeField] private CameraRotationHandler rotationHandler = new CameraRotationHandler();
[SerializeField] private CameraZoomHandler zoomHandler = new CameraZoomHandler();
[SerializeField] private CameraCollisionHandler collisionHandler = new CameraCollisionHandler();
[SerializeField] private CameraOcclusionTransparency occlusionTransparency = new CameraOcclusionTransparency();
[SerializeField] private CameraDynamicFOV dynamicFOV = new CameraDynamicFOV();
[SerializeField] private CameraCharacterFading characterFading = new CameraCharacterFading();
[SerializeField] private CameraSideBias sideBias = new CameraSideBias();
[SerializeField] private CameraShakeManager shakeManager = new CameraShakeManager();
[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 = 20f;
[SerializeField] float fpvFOV = 80f;
[SerializeField] float transitionDuration = 0.3f;
[SerializeField] float tpvBaseFOV = 60f; // Existing base FOV for TPV
private Vector3 _currentVelocity;
private Camera _cam;
private CameraViewMode _currentViewMode = CameraViewMode.ThirdPerson;
private CameraViewMode _targetViewMode = CameraViewMode.ThirdPerson;
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;
// Public properties for UI binding
public float Sensitivity => rotationHandler != null ? GetPrivateSensitivity() : 1f;
public bool InvertX => rotationHandler != null ? GetPrivateInvertX() : false;
public bool InvertY => rotationHandler != null ? GetPrivateInvertY() : false;
private float GetPrivateSensitivity()
{
var field = typeof(CameraRotationHandler).GetField("sensitivity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
return field != null ? (float)field.GetValue(rotationHandler) : 0.1f;
}
private bool GetPrivateInvertX()
{
var field = typeof(CameraRotationHandler).GetField("invertX", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
return field != null ? (bool)field.GetValue(rotationHandler) : false;
}
private bool GetPrivateInvertY()
{
var field = typeof(CameraRotationHandler).GetField("invertY", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
return field != null ? (bool)field.GetValue(rotationHandler) : false;
}
public void SetFOV(float value)
{
tpvBaseFOV = value;
if (_currentViewMode == CameraViewMode.ThirdPerson && !_inTransition)
{
_cam.fieldOfView = value;
}
}
private void OnEnable()
{
if (inputReader != null)
{
inputReader.OnToggleViewEvent += ToggleCameraView;
}
if (SettingsManager.Instance != null)
{
SettingsManager.Instance.OnSettingsChanged += ApplyGlobalSettings;
ApplyGlobalSettings();
}
}
private void OnDisable()
{
if (inputReader != null)
{
inputReader.OnToggleViewEvent -= ToggleCameraView;
}
if (SettingsManager.Instance != null)
{
SettingsManager.Instance.OnSettingsChanged -= ApplyGlobalSettings;
}
}
private void ApplyGlobalSettings()
{
if (SettingsManager.Instance == null || SettingsManager.Instance.Settings == null) return;
var settings = SettingsManager.Instance.Settings;
// Note: Since I cannot modify CameraRotationHandler.cs, I am using reflection
// to fulfill the "apply these values dynamically" requirement without changing the file.
// This is a workaround requested by the user's constraint.
var type = typeof(CameraRotationHandler);
type.GetField("sensitivity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(rotationHandler, settings.sensitivity * 0.1f);
type.GetField("invertX", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(rotationHandler, settings.invertX);
type.GetField("invertY", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(rotationHandler, settings.invertY);
SetFOV(settings.fieldOfView);
}
private void Start()
{
_cam = GetComponent<Camera>();
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
rotationHandler.Initialize(transform);
dynamicFOV.Initialize(tpvBaseFOV: tpvBaseFOV, fpvFOV: fpvFOV); // Pass TPV and FPV base FOVs
}
private void Update()
{
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
rotationHandler.HandleRotation(inputReader, followTarget, CurrentRotationSmoothTime, _currentViewMode);
if (_currentViewMode == CameraViewMode.ThirdPerson)
{
zoomHandler.HandleZoom(inputReader);
sideBias.HandleSideBias(inputReader);
}
else
{
// Disable side bias and zoom in FPV
sideBias.HandleSideBias(null); // Pass null to effectively disable
zoomHandler.HandleZoom(null); // Pass null to effectively disable
}
dynamicFOV.HandleDynamicFOV(_cam, inputReader, _currentViewMode);
}
Vector3 focusPosition;
float targetDistance;
if (_currentViewMode == CameraViewMode.ThirdPerson)
{
// TPV specific calculations
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);
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
if (followTarget != null) followTarget.rotation = rotationHandler.PlanarRotation;
if (fpvTarget != null) fpvTarget.rotation = rotationHandler.CurrentRotation;
transform.rotation = rotationHandler.CurrentRotation;
focusPosition = fpvTarget.position;
targetDistance = 0;
// 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
Vector3 targetPosition = focusPosition - transform.rotation * new Vector3(0, 0, targetDistance);
// Handle camera shake
shakeManager.HandleShake();
// Apply final position and rotation
transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref _currentVelocity, CurrentPositionSmoothTime) + shakeManager.ShakeOffset;
}
public void ToggleCameraView()
{
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;
}
private void HandleViewTransition()
{
if (!_inTransition) return;
_transitionTimer += Time.deltaTime;
float t = _transitionTimer / transitionDuration;
t = Mathf.Clamp01(t); // Clamp t between 0 and 1
// Smoothly interpolate parameters during transition
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)
{
followTarget.rotation = Quaternion.Slerp(followTarget.rotation, rotationHandler.PlanarRotation, t);
}
// Interpolate position and rotation
if (fpvTarget != null)
{
transform.position = Vector3.Lerp(transform.position, fpvTarget.position, t);
transform.rotation = Quaternion.Slerp(transform.rotation, fpvTarget.rotation, t);
}
}
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)
{
_currentViewMode = _targetViewMode;
Debug.Log($"[CameraController] View transition complete. Current mode: {_currentViewMode}");
_inTransition = false;
// Ensure final values are set correctly
_cam.fieldOfView = (_currentViewMode == CameraViewMode.FirstPerson) ? fpvFOV : dynamicFOV.CurrentTpvBaseFOV;
_cam.nearClipPlane = (_currentViewMode == CameraViewMode.FirstPerson) ? 0.01f : 0.3f;
}
}
public void Shake(float intensity, float duration)
{
shakeManager.Shake(intensity, duration);
}
public void TriggerFallImpactShake(float fallHeight)
{
shakeManager.TriggerFallImpactShake(fallHeight);
}
public Quaternion PlanarRotation => rotationHandler.PlanarRotation;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: d3a2f40f0d755824f91dfa62616cd6fc

View File

@@ -1,45 +0,0 @@
using UnityEngine;
using static OnlyScove.Scripts.CameraController; // Need to add this to access CameraController.CameraViewMode
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraDynamicFOV
{
[Header("Dynamic FOV")]
[SerializeField] private bool useDynamicFOV = true;
[SerializeField] private float tpvSprintFOV = 70f; // Renamed from sprintFOV for clarity
[SerializeField] private float fpvSprintFOV = 95f; // Target FOV for sprinting in FPV
[SerializeField] private float fovSmoothTime = 5f;
private float _currentTpvBaseFOV; // Stored from CameraController
private float _currentFpvFOV; // Stored from CameraController
public float CurrentTpvBaseFOV => _currentTpvBaseFOV; // Expose for CameraController transitions
public void Initialize(float tpvBaseFOV, float fpvFOV)
{
_currentTpvBaseFOV = tpvBaseFOV;
_currentFpvFOV = fpvFOV;
}
public void HandleDynamicFOV(Camera cam, InputReader inputReader, CameraViewMode viewMode)
{
if (!useDynamicFOV || cam == null || inputReader == null) return;
bool isSprinting = inputReader.MoveInput.magnitude > 0.1f && inputReader.IsSprintHeld;
float targetFOV;
if (viewMode == CameraViewMode.ThirdPerson)
{
targetFOV = isSprinting ? tpvSprintFOV : _currentTpvBaseFOV;
}
else // FirstPerson
{
targetFOV = isSprinting ? fpvSprintFOV : _currentFpvFOV;
}
cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, targetFOV, fovSmoothTime * Time.deltaTime);
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 99cfe3471dc945a4fad66b3b440c2c12

View File

@@ -1,66 +0,0 @@
using UnityEngine;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraOcclusionTransparency
{
[Header("Occlusion Transparency")]
[SerializeField] private bool useTransparency = true;
[SerializeField] private LayerMask transparencyLayers;
[SerializeField] private float fadeAlpha = 0.3f;
private Renderer _lastFadedRenderer;
private Color _originalColor;
public void HandleTransparency(Transform cameraTransform, Vector3 focusPosition)
{
if (!useTransparency)
{
ResetLastRenderer();
return;
}
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))
{
Renderer renderer = hit.collider.GetComponent<Renderer>();
if (renderer != null && renderer != _lastFadedRenderer)
{
ResetLastRenderer();
_lastFadedRenderer = renderer;
_originalColor = renderer.material.color;
Color fadedColor = _originalColor;
fadedColor.a = fadeAlpha;
renderer.material.color = fadedColor;
}
}
else
{
ResetLastRenderer();
}
}
public void ResetLastRenderer()
{
if (_lastFadedRenderer != null)
{
_lastFadedRenderer.material.color = _originalColor;
_lastFadedRenderer = null;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 8ad64ce0d02e30243acc55aa0ebc74a9

View File

@@ -1,99 +0,0 @@
using UnityEngine;
using static OnlyScove.Scripts.CameraController;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraRotationHandler
{
[Header("Rotation Settings")]
[SerializeField] private float sensitivity = 0.1f;
[SerializeField] private float minVerticalAngle = -45f;
[SerializeField] private float maxVerticalAngle = 45f;
[SerializeField] private bool invertX;
[SerializeField] private bool invertY;
[Header("Auto Rotation")]
[SerializeField] private bool useAutoRotation = true;
[SerializeField] private float autoRotateDelay = 2.5f;
[SerializeField] private float autoRotateSpeed = 2f;
private float _rotationX;
private float _rotationY;
private float _lastInputTime;
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)
{
_rotationX = cameraTransform.eulerAngles.x;
_rotationY = cameraTransform.eulerAngles.y;
_lastInputTime = Time.time;
CurrentRotation = cameraTransform.rotation;
}
// New method to initialize rotation specifically for FPV
public void InitializeFPV(Transform fpvTargetTransform)
{
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
}
public void HandleRotation(InputReader inputReader, Transform followTarget, float rotationSmoothTime, CameraViewMode viewMode)
{
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;
}
float invertXVal = (invertX) ? -1 : 1;
float invertYVal = (invertY) ? -1 : 1;
_rotationX -= inputReader.LookInput.y * invertYVal * sensitivity * Time.deltaTime;
_rotationX = Mathf.Clamp(_rotationX, minVerticalAngle, maxVerticalAngle);
_rotationY += inputReader.LookInput.x * invertXVal * sensitivity * Time.deltaTime;
if (viewMode == CameraViewMode.ThirdPerson)
{
// Auto-Correction for TPV
if (useAutoRotation && Time.time - _lastInputTime > autoRotateDelay)
{
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);
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 92ec094a714577d49be74c0fedb3eeb3

View File

@@ -1,78 +0,0 @@
using UnityEngine;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraShakeManager
{
[SerializeField] private bool useShake = true;
[SerializeField] private float shakeFrequency = 25f; // How fast the shake oscillates
[SerializeField]
private AnimationCurve decayCurve = AnimationCurve.EaseInOut(0, 1, 1, 0); // How intensity decays over duration
[Header("Fall Impact Settings")] [SerializeField]
private bool enableFallImpactShake = true;
[SerializeField] private float minFallHeightForShake = 2f;
[SerializeField] private float maxFallHeightForShake = 10f;
[SerializeField] private float minFallShakeIntensity = 0.5f;
[SerializeField] private float maxFallShakeIntensity = 3f;
[SerializeField] private float minFallShakeDuration = 0.2f;
[SerializeField] private float maxFallShakeDuration = 0.8f;
[SerializeField] private AnimationCurve fallHeightToIntensityCurve = AnimationCurve.Linear(0, 0, 1, 1);
[SerializeField] private AnimationCurve fallHeightToDurationCurve = AnimationCurve.Linear(0, 0, 1, 1);
private float _shakeIntensity = 0f;
private float _shakeDuration = 0f;
private float _shakeTimer = 0f; // Counts down from _shakeDuration
private Vector3 _shakeOffset;
public Vector3 ShakeOffset => _shakeOffset;
public void HandleShake()
{
if (!useShake || _shakeTimer <= 0)
{
_shakeOffset = Vector3.zero;
return;
}
_shakeTimer -= Time.deltaTime;
float progress = 1f - (_shakeTimer / _shakeDuration); // 0 at start, 1 at end
// Apply decay curve to intensity
float currentIntensity = _shakeIntensity * decayCurve.Evaluate(progress);
// Use shakeFrequency for Perlin noise
float shakeX = (Mathf.PerlinNoise(Time.time * shakeFrequency, 0f) - 0.5f) * 2f;
float shakeY = (Mathf.PerlinNoise(0f, Time.time * shakeFrequency) - 0.5f) * 2f;
float shakeZ = (Mathf.PerlinNoise(Time.time * shakeFrequency, Time.time * shakeFrequency) - 0.5f) * 2f;
_shakeOffset = new Vector3(shakeX, shakeY, shakeZ) * currentIntensity;
}
public void Shake(float intensity, float duration)
{
_shakeIntensity = intensity;
_shakeDuration = duration;
_shakeTimer = duration; // Reset timer
}
public void TriggerFallImpactShake(float fallHeight)
{
if (!enableFallImpactShake || fallHeight < minFallHeightForShake) return;
// Normalize fall height between 0 and 1 relative to min/max thresholds
float normalizedFallHeight = Mathf.InverseLerp(minFallHeightForShake, maxFallHeightForShake, fallHeight);
// Calculate intensity and duration using curves and ranges
float intensity = Mathf.Lerp(minFallShakeIntensity, maxFallShakeIntensity,
fallHeightToIntensityCurve.Evaluate(normalizedFallHeight));
float duration = Mathf.Lerp(minFallShakeDuration, maxFallShakeDuration,
fallHeightToDurationCurve.Evaluate(normalizedFallHeight));
Shake(intensity, duration);
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 16e87ee63ce87ac4cb7b952772318c0e

View File

@@ -1,39 +0,0 @@
using UnityEngine;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraSideBias
{
[Header("Side Bias")]
[SerializeField] private bool useSideBias = true;
[SerializeField] private float horizontalBiasAmount = 0.5f;
[SerializeField] private float biasSmoothTime = 3f;
private float _currentSideBias;
public float CurrentSideBias => _currentSideBias;
public void HandleSideBias(InputReader inputReader)
{
float targetBias = 0f;
if (SettingsManager.Instance != null && SettingsManager.Instance.Settings != null)
{
// Fixed offset based on settings
targetBias = SettingsManager.Instance.Settings.sideBiasRight ? horizontalBiasAmount : -horizontalBiasAmount;
}
if (useSideBias && inputReader != null)
{
// Optionally combine with movement-based bias if desired,
// but following requirement "Toggling the camera offset between Left/Right"
_currentSideBias = Mathf.Lerp(_currentSideBias, targetBias, biasSmoothTime * Time.deltaTime);
}
else
{
_currentSideBias = Mathf.Lerp(_currentSideBias, 0, biasSmoothTime * Time.deltaTime);
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: f6bf6a3797a87fb4fb086c1625b1e7bb

View File

@@ -1,29 +0,0 @@
using UnityEngine;
namespace OnlyScove.Scripts
{
[System.Serializable]
public class CameraZoomHandler
{
[Header("Zoom Settings")]
[SerializeField] private float distance = 5;
[SerializeField] private float minDistance = 2f;
[SerializeField] private float maxDistance = 15f;
[SerializeField] private float zoomSensitivity = 1f;
public float CurrentDistance => distance;
public float MinDistance => minDistance;
public void HandleZoom(InputReader inputReader)
{
if (inputReader == null) return;
float scrollDelta = inputReader.ScrollInput.y;
if (Mathf.Abs(scrollDelta) > 0.1f)
{
distance -= scrollDelta * zoomSensitivity * Time.deltaTime;
distance = Mathf.Clamp(distance, minDistance, maxDistance);
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 416c8d0f8adfcbc4390cd2e4e369e0db

View File

@@ -30,7 +30,7 @@ namespace Invector.vCamera
#region inspector properties
public Transform mainTarget;
public InputReader inputReader;
// public InputReader inputReader;
[Header("First Person View")]
public Transform fpvTarget;
@@ -38,10 +38,10 @@ namespace Invector.vCamera
[SerializeField] protected float transitionDuration = 0.3f;
[Header("Modular Features")]
[SerializeField] protected CameraCharacterFading characterFading = new CameraCharacterFading();
[SerializeField] protected CameraOcclusionTransparency occlusionTransparency = new CameraOcclusionTransparency();
[SerializeField] protected CameraDynamicFOV dynamicFOV = new CameraDynamicFOV();
[SerializeField] protected CameraShakeManager shakeManager = new CameraShakeManager();
// [SerializeField] protected CameraCharacterFading characterFading = new CameraCharacterFading();
// [SerializeField] protected CameraOcclusionTransparency occlusionTransparency = new CameraOcclusionTransparency();
// [SerializeField] protected CameraDynamicFOV dynamicFOV = new CameraDynamicFOV();
// [SerializeField] protected CameraShakeManager shakeManager = new CameraShakeManager();
[Tooltip("Lerp speed between Camera States")]
[SerializeField] protected float _smoothBetweenState = 6f;
@@ -215,20 +215,20 @@ namespace Invector.vCamera
protected virtual void OnEnable()
{
if (inputReader != null)
{
inputReader.OnToggleViewEvent += ToggleCameraView;
inputReader.OnSwitchSideEvent += ToggleSwitchSide;
}
// if (inputReader != null)
// {
// inputReader.OnToggleViewEvent += ToggleCameraView;
// inputReader.OnSwitchSideEvent += ToggleSwitchSide;
// }
}
protected virtual void OnDisable()
{
if (inputReader != null)
{
inputReader.OnToggleViewEvent -= ToggleCameraView;
inputReader.OnSwitchSideEvent -= ToggleSwitchSide;
}
// if (inputReader != null)
// {
// inputReader.OnToggleViewEvent -= ToggleCameraView;
// inputReader.OnSwitchSideEvent -= ToggleSwitchSide;
// }
}
public virtual void ToggleSwitchSide()
@@ -269,7 +269,7 @@ namespace Invector.vCamera
public virtual void TriggerFallImpactShake(float fallHeight)
{
shakeManager.TriggerFallImpactShake(fallHeight);
// shakeManager.TriggerFallImpactShake(fallHeight);
}
/// <summary>
@@ -282,8 +282,8 @@ namespace Invector.vCamera
return;
}
if (inputReader == null) inputReader = mainTarget.GetComponent<InputReader>();
if (inputReader == null) inputReader = GameObject.FindFirstObjectByType<InputReader>();
// if (inputReader == null) inputReader = mainTarget.GetComponent<InputReader>();
// if (inputReader == null) inputReader = GameObject.FindFirstObjectByType<InputReader>();
firstUpdated = true;
useSmooth = true;
@@ -332,7 +332,7 @@ namespace Invector.vCamera
currentTargetPos = new Vector3(currentTarget.position.x, currentTarget.position.y + offSetPlayerPivot, currentTarget.position.z) + currentTarget.transform.up * lerpState.height;
targetLookAt.position = currentTargetPos;
dynamicFOV.Initialize(currentState.fov, fpvFOV);
// dynamicFOV.Initialize(currentState.fov, fpvFOV);
isInit = true;
}
@@ -376,13 +376,13 @@ namespace Invector.vCamera
}
// Modular Features
if (inputReader != null)
{
dynamicFOV.HandleDynamicFOV(targetCamera, inputReader,
currentState.cameraMode == TPCameraMode.FirstPerson ? CameraController.CameraViewMode.FirstPerson : CameraController.CameraViewMode.ThirdPerson);
}
shakeManager.HandleShake();
transform.position += shakeManager.ShakeOffset;
// if (inputReader != null)
// {
// dynamicFOV.HandleDynamicFOV(targetCamera, inputReader,
// currentState.cameraMode == TPCameraMode.FirstPerson ? CameraController.CameraViewMode.FirstPerson : CameraController.CameraViewMode.ThirdPerson);
// }
// shakeManager.HandleShake();
// transform.position += shakeManager.ShakeOffset;
}
/// <summary>
@@ -1016,8 +1016,8 @@ namespace Invector.vCamera
selfRigidbody.MoveRotation(Quaternion.Lerp(startRotation, _rot, transformWeight));
// Apply Fading and Transparency
characterFading.HandleCharacterFading(distance);
occlusionTransparency.HandleTransparency(transform, targetPos);
// characterFading.HandleCharacterFading(distance);
// occlusionTransparency.HandleTransparency(transform, targetPos);
movementSpeed = Vector2.zero;
}
@@ -1048,8 +1048,8 @@ namespace Invector.vCamera
mainTarget.rotation = Quaternion.Euler(0, targetLookAt.eulerAngles.y, 0);
}
characterFading.HandleCharacterFading(0); // Fully hide character head if desired, or set to distance 0 for full hidden
occlusionTransparency.HandleTransparency(transform, fpvTarget.position);
// characterFading.HandleCharacterFading(0); // Fully hide character head if desired, or set to distance 0 for full hidden
// occlusionTransparency.HandleTransparency(transform, fpvTarget.position);
}
protected virtual void CameraFixed()