Files
2026-03-04 10:03:45 +08:00

230 lines
5.9 KiB
C#

using System;
using System.Collections;
using Cinemachine;
using UnityEngine;
namespace UFS2.Gameplay
{
public class GameCameraController : Singleton<GameCameraController>
{
[SerializeField]
private CinemachineVirtualCamera _CurrentVirtualCamera;
[SerializeField]
private CinemachineVirtualCamera _PlayerCamera;
private CinemachineBrain _CMBrain;
[SerializeField]
private float _ZoomFov = 10f;
[SerializeField]
private float _ZoomTweenTime = 0.15f;
[SerializeField]
private LayerMask underwaterLayersMask;
[SerializeField]
private LayerMask topwaterLayerMask;
private Animator rolnetkaAnimator;
private Camera cameraCmp;
private bool _IsInWater;
private bool _IsPhotoMode;
private bool _IsZoomPlaying;
private bool _IsCameraZoomIn;
public bool IsInWater => _IsInWater;
public bool IsZoomPlaying => _IsZoomPlaying;
public bool IsCameraZoomIn => _IsCameraZoomIn;
private float defaultFov => Singleton<SaveDataManager>.Instance.SettingsData.FOVValue;
public static event Action OnEnterInToWater;
public static event Action OnExitFromWater;
public static event Action OnPhotoModeEnable;
public static event Action OnPhotoModeDisable;
public static event Action OnZoomTweenEnd;
private void Start()
{
_CMBrain = GetComponent<CinemachineBrain>();
_CurrentVirtualCamera = _PlayerCamera;
_CMBrain.m_CameraActivatedEvent.AddListener(_Listener);
InitializeSettings();
SetCameraPivot();
cameraCmp = GetComponent<Camera>();
}
private void OnEnable()
{
SettingsManager.OnSettingApply += InitializeSettings;
PlayerManager.OnAfterSettingCharacter += SetCameraPivot;
OnEnterInToWater += ZoomCameraDisableInstant;
OnEnterInToWater += ChangeUnderwaterCullingMask;
OnExitFromWater += ChangeTopWaterCullingMask;
AnglerViewFish.OnAnglerViewStart += SetCameraPivotToAnglerView;
AnglerViewFish.OnAnglerViewEnd += SetCameraPivot;
}
private void OnDisable()
{
SettingsManager.OnSettingApply -= InitializeSettings;
PlayerManager.OnAfterSettingCharacter -= SetCameraPivot;
OnEnterInToWater -= ZoomCameraDisableInstant;
OnEnterInToWater -= ChangeUnderwaterCullingMask;
OnExitFromWater -= ChangeTopWaterCullingMask;
AnglerViewFish.OnAnglerViewStart -= SetCameraPivotToAnglerView;
AnglerViewFish.OnAnglerViewEnd -= SetCameraPivot;
}
private void ChangeUnderwaterCullingMask()
{
cameraCmp = ((cameraCmp == null) ? GetComponent<Camera>() : cameraCmp);
cameraCmp.cullingMask = underwaterLayersMask;
}
private void ChangeTopWaterCullingMask()
{
cameraCmp = ((cameraCmp == null) ? GetComponent<Camera>() : cameraCmp);
cameraCmp.cullingMask = topwaterLayerMask;
}
private void FixedUpdate()
{
bool flag = GameWaterSystem.IsPositionUnderWater(base.transform.position);
if (!_IsInWater && flag)
{
_IsInWater = true;
GameCameraController.OnEnterInToWater?.Invoke();
}
if (_IsInWater && !flag)
{
_IsInWater = false;
GameCameraController.OnExitFromWater?.Invoke();
}
}
private void Update()
{
ZoomCameraHandler();
PhotoCameraHandler();
}
private void PhotoCameraHandler()
{
}
private void ZoomCameraDisableInstant()
{
StopAllCoroutines();
_IsZoomPlaying = false;
if (rolnetkaAnimator != null)
{
rolnetkaAnimator.SetBool("Hide", value: true);
}
_PlayerCamera.m_Lens.FieldOfView = defaultFov;
}
private void ZoomCameraDisable()
{
StopAllCoroutines();
rolnetkaAnimator?.SetBool("Hide", value: true);
StartCoroutine(FieldViewTween(defaultFov));
}
private void ZoomCameraEnable()
{
if (rolnetkaAnimator == null)
{
rolnetkaAnimator = UnityEngine.Object.Instantiate(FScriptsHandler.Instance.lornetkaMaskPrefab, FScriptsHandler.Instance.m_Canvas.transform).GetComponent<Animator>();
rolnetkaAnimator.transform.SetAsFirstSibling();
}
rolnetkaAnimator.SetBool("Hide", value: false);
StopAllCoroutines();
StartCoroutine(FieldViewTween(_ZoomFov));
}
public static void SetCameraFov(float value)
{
Singleton<GameCameraController>.Instance._PlayerCamera.m_Lens.FieldOfView = value;
}
public static float GetCurrentFov()
{
return Singleton<GameCameraController>.Instance._PlayerCamera.m_Lens.FieldOfView;
}
private IEnumerator FieldViewTween(float fovTarget)
{
float tMax = _ZoomTweenTime;
float t = 0f;
float startFov = _PlayerCamera.m_Lens.FieldOfView;
_IsZoomPlaying = true;
while (t < tMax)
{
t += Time.deltaTime;
float fieldOfView = Mathf.Lerp(startFov, fovTarget, Mathf.Clamp01(t / tMax));
_PlayerCamera.m_Lens.FieldOfView = fieldOfView;
yield return null;
}
_IsZoomPlaying = false;
GameCameraController.OnZoomTweenEnd?.Invoke();
}
private void _Listener(ICinemachineCamera cinemachineCamera, ICinemachineCamera previousCamera)
{
_CurrentVirtualCamera = _CMBrain.ActiveVirtualCamera.VirtualCameraGameObject.GetComponent<CinemachineVirtualCamera>();
InitializeSettings();
}
private void ZoomCameraHandler()
{
if ((!(Singleton<ChatManager>.Instance != null) || !Singleton<ChatManager>.Instance.IsChatOpen) && !InputManager.isEagleEye && (!FScriptsHandler.Instance || !(FScriptsHandler.Instance.m_PlayerMain?.underWaterCamera)) && !_IsZoomPlaying && !_IsInWater && InputManager.isUnderwaterCameraFloatZoom)
{
_IsCameraZoomIn = !_IsCameraZoomIn;
if (_IsCameraZoomIn)
{
ZoomCameraEnable();
}
else
{
ZoomCameraDisable();
}
}
}
private void InitializeSettings()
{
_CurrentVirtualCamera.m_Lens.FieldOfView = defaultFov;
}
private void SetCameraPivot()
{
if ((bool)FScriptsHandler.Instance.m_PlayerMain)
{
_PlayerCamera.Follow = FScriptsHandler.Instance.m_PlayerMain.CameraPivot;
}
}
private void SetCameraPivotToAnglerView()
{
if ((bool)Singleton<AnglerViewFish>.Instance)
{
_PlayerCamera.Follow = Singleton<AnglerViewFish>.Instance.cameraPoint;
}
}
}
}