Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/AquariumCameraController.cs
2026-02-21 16:45:37 +08:00

199 lines
5.1 KiB
C#

using Rewired;
using UnityEngine;
public class AquariumCameraController : MonoBehaviour, IAquariumCamera
{
[SerializeField]
private Transform _cameraParent;
[SerializeField]
private Camera _camera;
[SerializeField]
private float _zoomDistance = 0.5f;
[SerializeField]
private float _minFishDistance = 0.1f;
[SerializeField]
private float _defaultDistance = 0.5f;
[SerializeField]
private float _fishCameraFOV = 60f;
[SerializeField]
private float _cameraShiftSpeedMultiplier = 0.5f;
[SerializeField]
private float _obstacleMinCameraDistance = 0.1f;
[SerializeField]
private float _cameraZoomSpeed = 1f;
[SerializeField]
private float _cameraZoomSmoothTime = 0.5f;
[SerializeField]
private float _cameraPositionSmoothTime = 0.5f;
[SerializeField]
private float _cameraRotationSpeed = 1f;
[SerializeField]
private float _cameraRotationSmoothTime = 0.5f;
[SerializeField]
private bool _rotateHorizontal = true;
[SerializeField]
private bool _rotateVertical = true;
[SerializeField]
private LayerMask _cameraRaycastLayer;
private Vector3 _defaultPosition;
private Quaternion _defaultRotation;
private Vector3 _defaultCameraLocalPosition;
private float _defaultFOV;
private SchoolChild _currentFish;
private float _targetCameraDistance;
private float _currentCameraDistance;
private float _cameraDistanceVelocity;
private Vector3 _currentCameraPosition;
private Vector3 _cameraPositionVelocity;
private Vector3 _targetCameraRotation;
private Vector3 _currentCameraRotation;
private Vector3 _cameraRotationVelocity;
private Player _rewiredPlayer;
private Transform _cameraTransform;
private float _minDistance = 0.5f;
private float _maxDistance = 2f;
public Camera Camera
{
get
{
return _camera;
}
}
private Vector3 _targetCameraPosition
{
get
{
return _currentFish._cacheTransform.position + _currentFish._cacheTransform.forward * _currentFish._targetSpeed * _cameraShiftSpeedMultiplier;
}
}
GameObject IAquariumCamera.gameObject
{
get
{
return base.gameObject;
}
}
private void Start()
{
_cameraTransform = _camera.transform;
_rewiredPlayer = ReInput.players.GetPlayer(0);
_defaultPosition = _cameraParent.position;
_defaultRotation = _cameraParent.rotation;
_defaultCameraLocalPosition = _cameraTransform.localPosition;
_defaultFOV = _camera.fieldOfView;
DetachFromFish();
}
private void Update()
{
if (_currentFish == null)
{
return;
}
float axis = _rewiredPlayer.GetAxis("DRAG_CHANGE");
_targetCameraDistance = Mathf.Clamp(_targetCameraDistance - axis * _cameraZoomSpeed, _minDistance, _maxDistance);
_currentCameraDistance = Mathf.SmoothDamp(_currentCameraDistance, ClampCameraDistance(_targetCameraDistance), ref _cameraDistanceVelocity, _cameraZoomSmoothTime);
_currentCameraPosition = Vector3.SmoothDamp(_currentCameraPosition, _targetCameraPosition, ref _cameraPositionVelocity, _cameraPositionSmoothTime);
if (_rewiredPlayer.GetButton("PUMP"))
{
if (_rotateHorizontal)
{
float axis2 = _rewiredPlayer.GetAxis("LOOK_HORIZONTAL");
_targetCameraRotation.y += axis2 * _cameraRotationSpeed;
}
if (_rotateVertical)
{
float axis3 = _rewiredPlayer.GetAxis("LOOK_VERTICAL");
_targetCameraRotation.x -= axis3 * _cameraRotationSpeed;
}
}
_currentCameraRotation = Vector3.SmoothDamp(_currentCameraRotation, _targetCameraRotation, ref _cameraRotationVelocity, _cameraRotationSmoothTime);
}
private float ClampCameraDistance(float targetDistance)
{
RaycastHit hitInfo;
if (Physics.Raycast(_targetCameraPosition, -base.transform.forward, out hitInfo, 100f, _cameraRaycastLayer) && hitInfo.collider.tag != "IgnoreCamera")
{
float max = Vector3.Distance(_targetCameraPosition, hitInfo.point);
return Mathf.Clamp(targetDistance, _minDistance, max);
}
return targetDistance;
}
private void LateUpdate()
{
if (!(_currentFish == null))
{
_cameraParent.position = _currentCameraPosition;
_cameraParent.eulerAngles = _currentCameraRotation;
_cameraTransform.localPosition = Vector3.back * _currentCameraDistance;
}
}
public void AttachToFish(SchoolChild fish)
{
float minDistance = 0.5f;
SkinnedMeshRenderer componentInChildren = fish._cacheTransform.GetComponentInChildren<SkinnedMeshRenderer>();
if ((bool)componentInChildren)
{
Vector3 extents = componentInChildren.bounds.extents;
minDistance = Mathf.Max(extents.x, extents.y, extents.z) + _minFishDistance;
}
_minDistance = minDistance;
_maxDistance = _minDistance + _zoomDistance;
_currentFish = fish;
_camera.fieldOfView = _fishCameraFOV;
_targetCameraDistance = (_currentCameraDistance = Mathf.Lerp(_minDistance, _maxDistance, _defaultDistance));
_currentCameraPosition = _targetCameraPosition;
_currentCameraRotation = (_targetCameraRotation = _cameraParent.eulerAngles);
base.enabled = true;
}
public void DetachFromFish()
{
base.enabled = false;
_currentFish = null;
_cameraParent.position = _defaultPosition;
_cameraParent.rotation = _defaultRotation;
_cameraTransform.localPosition = _defaultCameraLocalPosition;
_camera.fieldOfView = _defaultFOV;
}
}