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(); 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; } }