199 lines
5.1 KiB
C#
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;
|
|
}
|
|
}
|