Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/SmoothFollowUnderwater.cs
2026-03-04 10:03:45 +08:00

315 lines
8.1 KiB
C#

using System;
using LuxWater;
using UFS2.Gameplay;
using UltimateWater;
using UnityEngine;
using UnityEngine.AzureSky;
using UnityEngine.Rendering.PostProcessing;
public class SmoothFollowUnderwater : MonoBehaviour
{
public enum ViewType
{
FloatView = 0,
BaitView = 1,
Null = 2
}
private static ViewType LastViewType = ViewType.Null;
[SerializeField]
private ViewType viewType = ViewType.BaitView;
[SerializeField]
public Transform target;
[HideInInspector]
public FRod currentRod;
private static float currentDistance = 3f;
[SerializeField]
[Tooltip("The height we want the camera to be above the target")]
private float height = 5f;
[SerializeField]
private float orgHeight = 0.5f;
[SerializeField]
private float rotationDamping;
[SerializeField]
private float heightDamping;
private float currentFieldOfView;
public float startZoom = 1f;
public float startZoomFloat = 1f;
public float minZoom;
public float maxZoom = 10f;
public float minZoomFloat;
public float maxZoomFloat = 10f;
private float speedZoom;
[SerializeField]
private Camera mCamera;
private static float rotation = 0f;
private LuxWater_WaterVolume waterUnderWaterVolume;
private WaterCamera uwsWaterCamera;
private float mouseSensitivity = 10.5f;
private AudioSource ownAudio;
private AudioSource[] audios;
private bool isCollide;
[SerializeField]
private LayerMask underwaterLayersMask;
[SerializeField]
private LayerMask topwaterLayersMask;
[SerializeField]
private LayerMask collisionMask;
[SerializeField]
private float rayDistanceFromGround = 0.05f;
[SerializeField]
private float heightFromWater = -0.05f;
[SerializeField]
private Transform _CameraTransform;
[SerializeField]
private Transform _CameraRoot;
private AzureFogScattering fog;
private RaycastHit rayHit;
private static Vector3 _cameraLastLocalPos;
private static Quaternion _cameraLastLocalRot;
private static Quaternion _rootLastLocalRot;
private int collideCount;
public static event Action<Transform> OnCameraTransformUpdate;
public static event Action OnExitFromCamera;
public static event Action OnEnterCamera;
public static event Action OnBaitViewChange;
public static event Action OnFloatViewChange;
private void Start()
{
ownAudio = GetComponentInChildren<AudioSource>();
mCamera = Camera.main;
EnableDisableAllAudioOnScene(val: false);
SmoothFollowUnderwater.OnBaitViewChange?.Invoke();
SmoothFollowUnderwater.OnEnterCamera?.Invoke();
PostProcessLayer component = mCamera.GetComponent<PostProcessLayer>();
if ((bool)component)
{
component.antialiasingMode = (PostProcessLayer.Antialiasing)Singleton<SaveDataManager>.Instance.SettingsData.AntiAliasingModeIndex;
}
mouseSensitivity = Singleton<SaveDataManager>.Instance.SettingsData.MouseSensitivityValue;
if (LastViewType == ViewType.Null)
{
viewType = ViewType.BaitView;
}
LastViewType = viewType;
UpdateUnderwaterVolume();
SetStartPosition();
}
private void UpdateUnderwaterVolume()
{
ownAudio.volume = Singleton<SaveDataManager>.Instance.SettingsData.UnderwaterVolume;
}
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
UpdateUnderwaterVolume();
}
}
private void Update()
{
ControllerHandler();
}
private void LateUpdate()
{
if (!(target == null))
{
base.transform.position = target.position;
_CameraRoot.transform.localRotation = Quaternion.Euler(0f, rotation, 0f);
SmoothFollowUnderwater.OnCameraTransformUpdate?.Invoke(_CameraTransform);
GameWaterSystem.FindWaterLevelAtLocation(base.transform.position, out var waterLevel);
Vector3 dir = target.position - _CameraTransform.position;
RaycastHandler(dir);
float b = (isCollide ? rayHit.distance : currentDistance);
currentDistance = Mathf.Lerp(_CameraTransform.localPosition.z, b, Time.deltaTime);
float value = target.position.y + height;
value = Mathf.Clamp(value, float.NegativeInfinity, heightFromWater + waterLevel);
if (viewType == ViewType.FloatView && (bool)currentRod.currentFloat)
{
value = height + orgHeight + waterLevel;
}
if (viewType == ViewType.FloatView && (bool)currentRod.currentLure && currentRod.currentLure.waterDisplacement.moveCharacteristic == FWaterDisplacement.MoveCharacteristic.TopWater)
{
value = height + orgHeight + waterLevel;
}
_CameraTransform.localPosition = new Vector3(0f, value, currentDistance);
_CameraTransform.position = new Vector3(_CameraTransform.position.x, value, _CameraTransform.position.z);
if (target.position.y > _CameraTransform.position.y)
{
_CameraTransform.LookAt(new Vector3(target.position.x, _CameraTransform.position.y, target.position.z));
}
else
{
_CameraTransform.LookAt(target);
}
SoundEnableHandler();
}
}
private void SetStartPosition()
{
_CameraTransform.localPosition = _cameraLastLocalPos;
_CameraTransform.localRotation = _cameraLastLocalRot;
_CameraRoot.localRotation = _cameraLastLocalRot;
}
private void OnDestroy()
{
if ((bool)waterUnderWaterVolume)
{
waterUnderWaterVolume.enabled = false;
}
EnableDisableAllAudioOnScene(val: true);
_cameraLastLocalPos = _CameraTransform.localPosition;
_cameraLastLocalRot = _CameraTransform.localRotation;
_rootLastLocalRot = _CameraRoot.localRotation;
SmoothFollowUnderwater.OnExitFromCamera?.Invoke();
}
private void RaycastHandler(Vector3 dir)
{
dir = (_CameraTransform.position - target.position).normalized;
bool flag = Physics.SphereCast(new Ray(target.position, dir.normalized), maxDistance: currentDistance + 0.05f, radius: 0.1f, hitInfo: out rayHit, layerMask: collisionMask);
isCollide = flag;
}
private void ControllerHandler()
{
_ = (bool)FishEntity.CurrentFishInFight;
if (InputManager.isUnderwaterCameraFloatZoom)
{
if ((bool)currentRod.currentFloat)
{
viewType = ((viewType != ViewType.BaitView) ? ViewType.BaitView : ViewType.FloatView);
}
if ((bool)currentRod.currentLure)
{
if (currentRod.currentLure.waterDisplacement.moveCharacteristic == FWaterDisplacement.MoveCharacteristic.TopWater)
{
viewType = ((viewType != ViewType.BaitView) ? ViewType.BaitView : ViewType.FloatView);
}
else
{
viewType = ViewType.BaitView;
}
}
}
switch (viewType)
{
case ViewType.FloatView:
target = (currentRod.currentFloat ? currentRod.currentFloat.transform : target);
SmoothFollowUnderwater.OnFloatViewChange?.Invoke();
break;
case ViewType.BaitView:
target = (currentRod.currentBait ? currentRod.currentBait.transform : target);
SmoothFollowUnderwater.OnBaitViewChange?.Invoke();
break;
}
if (target == null)
{
target = currentRod.LureHookWaterDisplacement.transform;
}
rotation += Mathf.Clamp(GameManager.Instance.player.GetAxis("cameraHorizontal") * mouseSensitivity * Time.deltaTime + GameManager.Instance.player.GetAxis("cameraHorizontalGamepad") * 50f * Time.deltaTime, -17.5f, 17.5f);
if (isCollide)
{
return;
}
float num = Time.deltaTime * 120f;
if (InputManager.isUnderwaterCameraZoomDown)
{
currentDistance = Mathf.MoveTowards(currentDistance, maxZoom, Time.deltaTime * speedZoom);
if (currentDistance != maxZoom)
{
speedZoom += num;
}
}
else if (InputManager.isUnderwaterCameraZoomUp)
{
currentDistance = Mathf.MoveTowards(currentDistance, minZoom, Time.deltaTime * speedZoom);
if (currentDistance != minZoom)
{
speedZoom += num;
}
}
else
{
speedZoom = 0f;
}
}
private void SoundEnableHandler()
{
if (!ownAudio.enabled && GameWaterSystem.IsPositionUnderWater(_CameraTransform.position))
{
Debug.Log("Wylacz dzwieki otoczenia");
EnableDisableAllAudioOnScene(val: false);
ownAudio.enabled = true;
}
else if (ownAudio.enabled && !GameWaterSystem.IsPositionUnderWater(_CameraTransform.position))
{
Debug.Log("Wlacz dzwieki otoczenia");
EnableDisableAllAudioOnScene(val: true);
ownAudio.enabled = false;
}
}
private void EnableDisableAllAudioOnScene(bool val)
{
audios = UnityEngine.Object.FindObjectsOfType<AudioSource>();
for (int i = 0; i < audios.Length; i++)
{
if (ownAudio != audios[i])
{
audios[i].mute = !val;
}
}
}
}