750 lines
30 KiB
C#
750 lines
30 KiB
C#
using UnityEngine;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace RTG
|
|
{
|
|
public delegate void CameraCanProcessInputHandler(YesNoAnswer answer);
|
|
public delegate void CameraCanUseScrollWheelHandler(YesNoAnswer answer);
|
|
|
|
public class RTFocusCamera : MonoSingleton<RTFocusCamera>
|
|
{
|
|
public event CameraProjectionSwitchBeginHandler PrjSwitchTransitionBegin;
|
|
public event CameraProjectionSwitchUpdateHandler PrjSwitchTransitionUpdate;
|
|
public event CameraProjectionSwitchBeginHandler PrjSwitchTransitionEnd;
|
|
public event CameraCanProcessInputHandler CanProcessInput;
|
|
public event CameraCanUseScrollWheelHandler CanUseScrollWheel;
|
|
|
|
private enum MoveDirection
|
|
{
|
|
Left = 0,
|
|
Right,
|
|
Up,
|
|
Down,
|
|
Forward,
|
|
Backwards
|
|
}
|
|
|
|
[SerializeField]
|
|
private Camera _targetCamera;
|
|
private Transform _targetTransform;
|
|
|
|
[SerializeField]
|
|
private float _fieldOfView;
|
|
|
|
private WorldTransformSnapshot _worldTransformSnapshot = new WorldTransformSnapshot();
|
|
private CameraPrjSwitchTransition _prjSwitchTranstion = new CameraPrjSwitchTransition();
|
|
private bool _isDoingFocus;
|
|
private IEnumerator _focusCrtn;
|
|
private bool _isDoingRotationSwitch;
|
|
private IEnumerator _genricCamTransformCrtn;
|
|
|
|
private bool _isObjectVisibilityDirty = true;
|
|
private List<GameObject> _visibleObjects = new List<GameObject>();
|
|
private float _focusPointOffset = 5.0f;
|
|
private Vector3 _lastFocusPoint;
|
|
|
|
private bool[] _moveDirFlags = new bool[Enum.GetValues(typeof(MoveDirection)).Length];
|
|
private float _currentAcceleration = 0.0f;
|
|
|
|
[SerializeField]
|
|
private CameraSettings _settings = new CameraSettings();
|
|
[SerializeField]
|
|
private CameraMoveSettings _moveSettings = new CameraMoveSettings();
|
|
[SerializeField]
|
|
private CameraPanSettings _panSettings = new CameraPanSettings();
|
|
[SerializeField]
|
|
private CameraLookAroundSettings _lookAroundSettings = new CameraLookAroundSettings();
|
|
[SerializeField]
|
|
private CameraOrbitSettings _orbitSettings = new CameraOrbitSettings();
|
|
[SerializeField]
|
|
private CameraZoomSettings _zoomSettings = new CameraZoomSettings();
|
|
[SerializeField]
|
|
private CameraFocusSettings _focusSettings = new CameraFocusSettings();
|
|
[SerializeField]
|
|
private CameraRotationSwitchSettings _rotationSwitchSettings = new CameraRotationSwitchSettings();
|
|
[SerializeField]
|
|
private CameraProjectionSwitchSettings _projectionSwitchSettings = new CameraProjectionSwitchSettings();
|
|
[SerializeField]
|
|
private CameraHotkeys _hotkeys = new CameraHotkeys();
|
|
|
|
public Camera TargetCamera { get { return _targetCamera; } }
|
|
public bool IsDoingProjectionSwitch { get { return _prjSwitchTranstion.IsActive; } }
|
|
public CameraPrjSwitchTransition.Type PrjSwitchTransitionType { get { return _prjSwitchTranstion.TransitionType; } }
|
|
public bool IsDoingRotationSwitch { get { return _isDoingRotationSwitch; } }
|
|
public float PrjSwitchProgress { get { return _prjSwitchTranstion.Progress; } }
|
|
public float PrjSwitchDurationInSeconds { get { return _projectionSwitchSettings.TransitionDurationInSeconds; } }
|
|
public bool IsDoingFocus { get { return _isDoingFocus; } }
|
|
public Vector3 WorldPosition
|
|
{
|
|
get { return _targetTransform.position; }
|
|
set
|
|
{
|
|
Vector3 focusPt = GetFocusPoint();
|
|
_targetTransform.position = value;
|
|
SetFocusPoint(focusPt);
|
|
}
|
|
}
|
|
public Quaternion WorldRotation
|
|
{
|
|
get { return _targetTransform.rotation; }
|
|
set
|
|
{
|
|
_targetTransform.rotation = value;
|
|
}
|
|
}
|
|
public Vector3 Right { get { return _targetTransform.right; } }
|
|
public Vector3 Up { get { return _targetTransform.up; } }
|
|
public Vector3 Look { get { return _targetTransform.forward; } }
|
|
public bool IsMovingForward { get { return _moveDirFlags[(int)MoveDirection.Forward]; } }
|
|
public bool IsMovingBackwards { get { return _moveDirFlags[(int)MoveDirection.Backwards]; } }
|
|
public bool IsMovingLeft { get { return _moveDirFlags[(int)MoveDirection.Left]; } }
|
|
public bool IsMovingRight { get { return _moveDirFlags[(int)MoveDirection.Right]; } }
|
|
public bool IsMovingUp { get { return _moveDirFlags[(int)MoveDirection.Up]; } }
|
|
public bool IsMovingDown { get { return _moveDirFlags[(int)MoveDirection.Down]; } }
|
|
|
|
public CameraSettings Settings { get { return _settings; } }
|
|
public CameraMoveSettings MoveSettings { get { return _moveSettings; } }
|
|
public CameraPanSettings PanSettings { get { return _panSettings; } }
|
|
public CameraLookAroundSettings LookAroundSettings { get { return _lookAroundSettings; } }
|
|
public CameraOrbitSettings OrbitSettings { get { return _orbitSettings; } }
|
|
public CameraZoomSettings ZoomSettings { get { return _zoomSettings; } }
|
|
public CameraFocusSettings FocusSettings { get { return _focusSettings; } }
|
|
public CameraRotationSwitchSettings RotationSwitchSettings { get { return _rotationSwitchSettings; } }
|
|
public CameraProjectionSwitchSettings ProjectionSwitchSettings { get { return _projectionSwitchSettings; } }
|
|
public CameraHotkeys Hotkeys { get { return _hotkeys; } }
|
|
|
|
public bool IsViewportHoveredByDevice()
|
|
{
|
|
Vector2 devicePos = RTInputDevice.Get.Device.GetPositionYAxisUp();
|
|
Vector3 viewportPoint = TargetCamera.ScreenToViewportPoint(devicePos);
|
|
return viewportPoint.x >= 0.0f && viewportPoint.x <= 1.0f &&
|
|
viewportPoint.y >= 0.0f && viewportPoint.y <= 1.0f;
|
|
}
|
|
|
|
public void SetTargetCamera(Camera camera)
|
|
{
|
|
if (camera == null) return;
|
|
|
|
if (Application.isPlaying)
|
|
{
|
|
if (IsDoingFocus || IsDoingProjectionSwitch || IsDoingRotationSwitch) return;
|
|
|
|
_targetCamera = camera;
|
|
_targetTransform = camera.transform;
|
|
_fieldOfView = camera.fieldOfView;
|
|
|
|
SetFocusPoint(GetFocusPoint());
|
|
AdjustOrthoSizeForFocusPt();
|
|
|
|
_isObjectVisibilityDirty = true;
|
|
}
|
|
#if UNITY_EDITOR
|
|
else
|
|
{
|
|
if (GameObjectEx.IsSceneObject(camera.gameObject))
|
|
{
|
|
_targetCamera = camera;
|
|
_fieldOfView = camera.fieldOfView;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
public void SetFieldOfView(float fov)
|
|
{
|
|
_targetCamera.fieldOfView = fov;
|
|
_fieldOfView = fov;
|
|
}
|
|
|
|
public void SetObjectVisibilityDirty()
|
|
{
|
|
_isObjectVisibilityDirty = true;
|
|
}
|
|
|
|
public void GetVisibleObjects(List<GameObject> visibleObjects)
|
|
{
|
|
visibleObjects.Clear();
|
|
|
|
if (_isObjectVisibilityDirty)
|
|
{
|
|
TargetCamera.GetVisibleObjects(new CameraViewVolume(TargetCamera), _visibleObjects);
|
|
_isObjectVisibilityDirty = false;
|
|
}
|
|
|
|
if (_visibleObjects.Count != 0) visibleObjects.AddRange(_visibleObjects);
|
|
}
|
|
|
|
public void PerformRotationSwitch(Quaternion targetRotation)
|
|
{
|
|
if (IsDoingProjectionSwitch) return;
|
|
|
|
StopCamTransform();
|
|
StopFocus();
|
|
|
|
if (RotationSwitchSettings.SwitchMode == CameraRotationSwitchMode.Constant) StartCoroutine(_genricCamTransformCrtn = DoConstantRotationSwitch(targetRotation));
|
|
else
|
|
if (RotationSwitchSettings.SwitchMode == CameraRotationSwitchMode.Smooth) StartCoroutine(_genricCamTransformCrtn = DoSmoothRotationSwitch(targetRotation));
|
|
else
|
|
{
|
|
if (RotationSwitchSettings.SwitchType == CameraRotationSwitchType.InPlace)
|
|
{
|
|
_targetTransform.rotation = targetRotation;
|
|
}
|
|
else
|
|
{
|
|
Vector3 focusPt = GetFocusPoint();
|
|
_targetTransform.rotation = targetRotation;
|
|
_targetTransform.position = focusPt - _targetTransform.forward * _focusPointOffset;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void PerformProjectionSwitch()
|
|
{
|
|
StopCamTransform();
|
|
StopFocus();
|
|
|
|
if (ProjectionSwitchSettings.SwitchMode == CameraProjectionSwitchMode.Transition)
|
|
{
|
|
_prjSwitchTranstion.TargetCamera = _targetCamera;
|
|
_prjSwitchTranstion.CamFieldOfView = _fieldOfView;
|
|
_prjSwitchTranstion.CamFocusPoint = GetFocusPoint();
|
|
_prjSwitchTranstion.DurationInSeconds = ProjectionSwitchSettings.TransitionDurationInSeconds;
|
|
_prjSwitchTranstion.Begin();
|
|
}
|
|
else PerformInstantProjectionSwitch();
|
|
}
|
|
|
|
public void Focus(List<GameObject> gameObjects)
|
|
{
|
|
var boundsQConfig = new ObjectBounds.QueryConfig();
|
|
boundsQConfig.NoVolumeSize = Vector3.one * 0.01f;
|
|
boundsQConfig.ObjectTypes = GameObjectType.Mesh | GameObjectType.Sprite | GameObjectType.Terrain;
|
|
|
|
AABB focusAABB = ObjectBounds.CalcObjectCollectionWorldAABB(gameObjects, boundsQConfig);
|
|
if (focusAABB.IsValid) Focus(focusAABB);
|
|
|
|
// var parents = GameObjectEx.FilterParentsOnly(gameObjects);
|
|
// if (parents.Count != 0)
|
|
// {
|
|
// AABB focusAABB = ObjectBounds.CalcHierarchyCollectionWorldAABB(parents, boundsQConfig);
|
|
// if (focusAABB.IsValid) Focus(focusAABB);
|
|
// }
|
|
}
|
|
|
|
public void Focus(AABB focusAABB)
|
|
{
|
|
if (_isDoingFocus || IsDoingProjectionSwitch || IsDoingRotationSwitch) return;
|
|
|
|
if (focusAABB.IsValid)
|
|
{
|
|
StopCamTransform();
|
|
|
|
CameraFocus.Data focusData = CameraFocus.CalculateFocusData(TargetCamera, focusAABB, FocusSettings);
|
|
if (FocusSettings.FocusMode == CameraFocusMode.Instant) PerformInstantFocus(focusData);
|
|
else if (FocusSettings.FocusMode == CameraFocusMode.Constant) StartCoroutine(_focusCrtn = DoConstantFocus(focusData));
|
|
else if (FocusSettings.FocusMode == CameraFocusMode.Smooth) StartCoroutine(_focusCrtn = DoSmoothFocus(focusData));
|
|
}
|
|
}
|
|
|
|
public void Update_SystemCall()
|
|
{
|
|
if (CanCameraProcessInput())
|
|
{
|
|
if (RTInputDevice.Get.DeviceType == InputDeviceType.Mouse) HandleMouseAndKeyboardInput();
|
|
}
|
|
|
|
if (!_worldTransformSnapshot.SameAs(_targetTransform))
|
|
{
|
|
SetObjectVisibilityDirty();
|
|
_worldTransformSnapshot.Snaphot(_targetTransform);
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if(TargetCamera == null)
|
|
{
|
|
Debug.Break();
|
|
Debug.LogError("RTCamera: No target camera was specified.");
|
|
}
|
|
|
|
SetTargetCamera(TargetCamera);
|
|
_worldTransformSnapshot.Snaphot(_targetTransform);
|
|
|
|
_prjSwitchTranstion.TargetMono = this;
|
|
_prjSwitchTranstion.TransitionBegin += OnPrjSwitchTransitionBegin;
|
|
_prjSwitchTranstion.TransitionUpdate += OnPrjSwitchTransitionUpate;
|
|
_prjSwitchTranstion.TransitionEnd += OnPrjSwitchTransitionEnd;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_lastFocusPoint = _targetTransform.position + _targetTransform.forward * _focusPointOffset;
|
|
SetFocusPoint(_lastFocusPoint);
|
|
AdjustOrthoSizeForFocusPt();
|
|
}
|
|
|
|
private void HandleMouseAndKeyboardInput()
|
|
{
|
|
float moveAmount = (_moveSettings.MoveSpeed + _currentAcceleration) * Time.deltaTime;
|
|
|
|
Vector3 moveVector = Vector3.zero;
|
|
_moveDirFlags[(int)MoveDirection.Forward] = Hotkeys.MoveForward.IsActive();
|
|
_moveDirFlags[(int)MoveDirection.Backwards] = !_moveDirFlags[(int)MoveDirection.Forward] && Hotkeys.MoveBack.IsActive();
|
|
_moveDirFlags[(int)MoveDirection.Left] = Hotkeys.StrafeLeft.IsActive();
|
|
_moveDirFlags[(int)MoveDirection.Right] = !_moveDirFlags[(int)MoveDirection.Left] && Hotkeys.StrafeRight.IsActive();
|
|
_moveDirFlags[(int)MoveDirection.Up] = Hotkeys.MoveUp.IsActive();
|
|
_moveDirFlags[(int)MoveDirection.Down] = !_moveDirFlags[(int)MoveDirection.Up] && Hotkeys.MoveDown.IsActive();
|
|
|
|
bool wasZoomed = false;
|
|
if (IsMovingForward) { Zoom(moveAmount); wasZoomed = true; }
|
|
else if (IsMovingBackwards) { Zoom(-moveAmount); wasZoomed = true; }
|
|
|
|
if (IsMovingLeft) moveVector -= _targetTransform.right * moveAmount;
|
|
else if (IsMovingRight) moveVector += _targetTransform.right * moveAmount;
|
|
if (IsMovingUp) moveVector += _targetTransform.up * moveAmount;
|
|
else if (IsMovingDown) moveVector -= _targetTransform.up * moveAmount;
|
|
|
|
bool needsToMove = moveVector.sqrMagnitude != 0.0f;
|
|
if (needsToMove) _targetTransform.position += moveVector;
|
|
|
|
if (needsToMove || wasZoomed)
|
|
{
|
|
float accelAdd = MoveSettings.AccelerationRate * Mathf.Abs(_targetCamera.EstimateZoomFactor(_lastFocusPoint)) * Time.deltaTime;
|
|
_currentAcceleration += accelAdd;
|
|
}
|
|
else _currentAcceleration = 0.0f;
|
|
|
|
// Get the mouse axes values. We need these for panning and rotation.
|
|
float mouseX = RTInput.MouseAxisX();
|
|
float mouseY = RTInput.MouseAxisY();
|
|
|
|
// Only proceed if at least one mouse axis value is != 0
|
|
if (mouseX != 0.0f || mouseY != 0.0f)
|
|
{
|
|
if (_panSettings.IsPanningEnabled && Hotkeys.Pan.IsActive())
|
|
{
|
|
if(_panSettings.PanMode == CameraPanMode.Standard) Pan(CalculatePanAmount(mouseX, mouseY));
|
|
else
|
|
{
|
|
StopCamTransform();
|
|
StartCoroutine(_genricCamTransformCrtn = DoSmoothPan(mouseX, mouseY));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((_orbitSettings.IsOrbitEnabled && Hotkeys.Orbit.IsActive()))
|
|
{
|
|
if (_orbitSettings.OrbitMode == CameraOrbitMode.Standard)
|
|
{
|
|
Vector2 rotation = CalculateOrbitRotation(mouseX, mouseY);
|
|
Orbit(rotation.x, rotation.y);
|
|
}
|
|
else
|
|
{
|
|
StopCamTransform();
|
|
StartCoroutine(_genricCamTransformCrtn = DoSmoothOrbit(mouseX, mouseY));
|
|
}
|
|
}
|
|
else
|
|
if (_lookAroundSettings.IsLookAroundEnabled && Hotkeys.LookAround.IsActive())
|
|
{
|
|
if (_lookAroundSettings.LookAroundMode == CameraLookAroundMode.Standard)
|
|
{
|
|
Vector2 rotation = CalculateLookAroundRotation(mouseX, mouseY);
|
|
LookAround(rotation.x, rotation.y);
|
|
}
|
|
else
|
|
{
|
|
StopCamTransform();
|
|
StartCoroutine(_genricCamTransformCrtn = DoSmoothLookAround(mouseX, mouseY));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (CanUseMouseScrollWheel())
|
|
{
|
|
float mouseScroll = RTInput.MouseScroll();
|
|
if (mouseScroll != 0.0f && _zoomSettings.IsZoomEnabled)
|
|
{
|
|
if (_zoomSettings.ZoomMode == CameraZoomMode.Standard) Zoom(CalculateScrollZoomAmount(mouseScroll));
|
|
else
|
|
{
|
|
StopCamTransform();
|
|
StartCoroutine(_genricCamTransformCrtn = DoSmoothZoom(mouseScroll));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool CanUseMouseScrollWheel()
|
|
{
|
|
if (CanUseScrollWheel == null) return true;
|
|
|
|
YesNoAnswer answer = new YesNoAnswer();
|
|
CanUseScrollWheel(answer);
|
|
return answer.HasOnlyYes;
|
|
}
|
|
|
|
private bool CanCameraProcessInput()
|
|
{
|
|
if (!_settings.CanProcessInput || _isDoingFocus ||
|
|
IsDoingProjectionSwitch || _isDoingRotationSwitch) return false;
|
|
|
|
if (CanProcessInput == null) return true;
|
|
|
|
YesNoAnswer answer = new YesNoAnswer();
|
|
CanProcessInput(answer);
|
|
return answer.HasOnlyYes;
|
|
}
|
|
|
|
private void Zoom(float zoomAmount)
|
|
{
|
|
Vector3 focusPoint = GetFocusPoint();
|
|
|
|
_targetTransform.position += _targetTransform.forward * zoomAmount;
|
|
if (TargetCamera.orthographic)
|
|
{
|
|
Vector3 toFocusPt = focusPoint - _targetTransform.position;
|
|
if (Vector3.Dot(toFocusPt, _targetTransform.forward) < 1e-2f)
|
|
{
|
|
_targetTransform.position = focusPoint - _targetTransform.forward * 1e-3f;
|
|
}
|
|
}
|
|
|
|
SetFocusPoint(focusPoint);
|
|
AdjustOrthoSizeForFocusPt();
|
|
}
|
|
|
|
private Vector3 GetFocusPoint()
|
|
{
|
|
return _targetTransform.position + _targetTransform.forward * _focusPointOffset;
|
|
}
|
|
|
|
private float CalculateScrollZoomAmount(float deviceScroll)
|
|
{
|
|
float zoomAmount = deviceScroll * _zoomSettings.GetZoomSensitivity(TargetCamera);
|
|
if (_zoomSettings.InvertZoomAxis) zoomAmount *= -1.0f;
|
|
|
|
zoomAmount *= _targetCamera.EstimateZoomFactorSpherical(_lastFocusPoint);
|
|
|
|
return zoomAmount;
|
|
}
|
|
|
|
private void Pan(Vector2 panAmount)
|
|
{
|
|
_targetTransform.position += _targetTransform.right * panAmount.x + _targetTransform.up * panAmount.y;
|
|
}
|
|
|
|
public void LookAround(float degreesLocalX, float degreesWorldY)
|
|
{
|
|
_targetTransform.Rotate(Vector3.up, degreesWorldY, Space.World);
|
|
_targetTransform.Rotate(_targetTransform.right, degreesLocalX, Space.World);
|
|
}
|
|
|
|
private void Orbit(float degreesLocalX, float degreesWorldY)
|
|
{
|
|
Vector3 orbitPoint = _targetTransform.position + _targetTransform.forward * _focusPointOffset;
|
|
|
|
_targetTransform.RotateAround(orbitPoint, Vector3.up, degreesWorldY);
|
|
_targetTransform.RotateAround(orbitPoint, _targetTransform.right, degreesLocalX);
|
|
_targetTransform.LookAt(orbitPoint, _targetTransform.up);
|
|
}
|
|
|
|
private void PerformInstantFocus(CameraFocus.Data focusData)
|
|
{
|
|
_targetTransform.position = focusData.CameraWorldPosition;
|
|
SetFocusPoint(focusData.FocusPoint);
|
|
_lastFocusPoint = focusData.FocusPoint;
|
|
|
|
AdjustOrthoSizeForFocusPt();
|
|
}
|
|
|
|
private void PerformInstantProjectionSwitch()
|
|
{
|
|
TargetCamera.orthographic = !TargetCamera.orthographic;
|
|
}
|
|
|
|
private Vector2 CalculateLookAroundRotation(float deviceAxisX, float deviceAxisY)
|
|
{
|
|
Vector2 rotation = Vector2.zero;
|
|
rotation.x = -deviceAxisY * _lookAroundSettings.Sensitivity;
|
|
if (_lookAroundSettings.InvertY) rotation.x *= -1.0f;
|
|
rotation.y = deviceAxisX * _lookAroundSettings.Sensitivity;
|
|
if (_lookAroundSettings.InvertX) rotation.y *= -1.0f;
|
|
|
|
return rotation;
|
|
}
|
|
|
|
private Vector2 CalculateOrbitRotation(float deviceAxisX, float deviceAxisY)
|
|
{
|
|
Vector2 rotation = Vector2.zero;
|
|
rotation.x = -deviceAxisY * _orbitSettings.OrbitSensitivity;
|
|
if (_orbitSettings.InvertY) rotation.x *= -1.0f;
|
|
rotation.y = deviceAxisX * _orbitSettings.OrbitSensitivity;
|
|
if (_orbitSettings.InvertX) rotation.y *= -1.0f;
|
|
|
|
return rotation;
|
|
}
|
|
|
|
private Vector2 CalculatePanAmount(float deviceAxisX, float deviceAxisY)
|
|
{
|
|
Vector2 panAmount = Vector2.zero;
|
|
panAmount.x = -deviceAxisX * _panSettings.Sensitivity;
|
|
if (_panSettings.InvertX) panAmount.x *= -1.0f;
|
|
panAmount.y = -deviceAxisY * _panSettings.Sensitivity;
|
|
if (_panSettings.InvertY) panAmount.y *= -1.0f;
|
|
|
|
panAmount *= Mathf.Abs(_targetCamera.EstimateZoomFactorSpherical(_lastFocusPoint));
|
|
|
|
return panAmount;
|
|
}
|
|
|
|
private void StopCamTransform()
|
|
{
|
|
if (_genricCamTransformCrtn != null)
|
|
{
|
|
StopCoroutine(_genricCamTransformCrtn);
|
|
_genricCamTransformCrtn = null;
|
|
}
|
|
}
|
|
|
|
private void StopFocus()
|
|
{
|
|
if(_focusCrtn != null)
|
|
{
|
|
StopCoroutine(_focusCrtn);
|
|
_focusCrtn = null;
|
|
}
|
|
}
|
|
|
|
private void SetFocusPoint(Vector3 focusPoint)
|
|
{
|
|
_focusPointOffset = (focusPoint - _targetTransform.position).magnitude;
|
|
}
|
|
|
|
private void AdjustOrthoSizeForFocusPt()
|
|
{
|
|
TargetCamera.orthographicSize = Mathf.Max(0.5f * TargetCamera.GetFrustumHeightFromDistance(_focusPointOffset), 1e-4f);
|
|
}
|
|
|
|
private IEnumerator DoSmoothPan(float deviceAxisX, float deviceAxisY)
|
|
{
|
|
Vector2 panAmount = CalculatePanAmount(deviceAxisX, deviceAxisY);
|
|
|
|
while(true)
|
|
{
|
|
Pan(panAmount);
|
|
panAmount = Vector2.Lerp(panAmount, Vector2.zero, _panSettings.SmoothValue * Time.deltaTime);
|
|
|
|
if (Mathf.Approximately(panAmount.sqrMagnitude, 0.0f)) break;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator DoSmoothLookAround(float deviceAxisX, float deviceAxisY)
|
|
{
|
|
Vector2 rotationAmount = CalculateLookAroundRotation(deviceAxisX, deviceAxisY);
|
|
|
|
while (true)
|
|
{
|
|
LookAround(rotationAmount.x, rotationAmount.y);
|
|
rotationAmount = Vector2.Lerp(rotationAmount, Vector2.zero, _lookAroundSettings.SmoothValue * Time.deltaTime);
|
|
|
|
if (Mathf.Approximately(rotationAmount.sqrMagnitude, 0.0f)) break;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator DoSmoothOrbit(float deviceAxisX, float deviceAxisY)
|
|
{
|
|
Vector2 rotationAmount = CalculateOrbitRotation(deviceAxisX, deviceAxisY);
|
|
|
|
while (true)
|
|
{
|
|
Orbit(rotationAmount.x, rotationAmount.y);
|
|
rotationAmount = Vector2.Lerp(rotationAmount, Vector2.zero, _orbitSettings.SmoothValue * Time.deltaTime);
|
|
|
|
if (Mathf.Approximately(rotationAmount.sqrMagnitude, 0.0f)) break;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator DoSmoothZoom(float deviceScroll)
|
|
{
|
|
float zoomAmount = CalculateScrollZoomAmount(deviceScroll);
|
|
|
|
while(true)
|
|
{
|
|
Zoom(zoomAmount);
|
|
zoomAmount = Mathf.Lerp(zoomAmount, 0.0f, _zoomSettings.GetZoomSmoothValue(TargetCamera) * Time.deltaTime);
|
|
|
|
if (Mathf.Approximately(zoomAmount, 0.0f)) break;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator DoConstantRotationSwitch(Quaternion targetRotation)
|
|
{
|
|
Quaternion sourceRotation = _targetTransform.rotation;
|
|
float elapsedTime = 0.0f;
|
|
|
|
_isDoingRotationSwitch = true;
|
|
if (RotationSwitchSettings.SwitchType == CameraRotationSwitchType.InPlace)
|
|
{
|
|
while (true)
|
|
{
|
|
_targetTransform.rotation = Quaternion.Slerp(sourceRotation, targetRotation, elapsedTime / RotationSwitchSettings.ConstantSwitchDurationInSeconds);
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
if (Mathf.Abs(Quaternion.Angle(_targetTransform.rotation, targetRotation)) < 1e-4f)
|
|
{
|
|
_targetTransform.rotation = targetRotation;
|
|
break;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Vector3 focusPt = GetFocusPoint();
|
|
while (true)
|
|
{
|
|
float t = elapsedTime / RotationSwitchSettings.ConstantSwitchDurationInSeconds;
|
|
_targetTransform.rotation = Quaternion.Slerp(sourceRotation, targetRotation, t);
|
|
_targetTransform.position = focusPt - _targetTransform.forward * _focusPointOffset;
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
if (Mathf.Abs(Quaternion.Angle(_targetTransform.rotation, targetRotation)) < 1e-4f)
|
|
{
|
|
_targetTransform.rotation = targetRotation;
|
|
break;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
_isDoingRotationSwitch = false;
|
|
}
|
|
|
|
private IEnumerator DoSmoothRotationSwitch(Quaternion targetRotation)
|
|
{
|
|
_isDoingRotationSwitch = true;
|
|
if (RotationSwitchSettings.SwitchType == CameraRotationSwitchType.InPlace)
|
|
{
|
|
while (true)
|
|
{
|
|
_targetTransform.rotation = Quaternion.Slerp(_targetTransform.rotation, targetRotation, Time.deltaTime * RotationSwitchSettings.SmoothValue);
|
|
if (Mathf.Abs(Quaternion.Angle(_targetTransform.rotation, targetRotation)) < 1e-4f)
|
|
{
|
|
_targetTransform.rotation = targetRotation;
|
|
break;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Vector3 focusPt = GetFocusPoint();
|
|
while (true)
|
|
{
|
|
float t = Time.deltaTime * RotationSwitchSettings.SmoothValue;
|
|
_targetTransform.rotation = Quaternion.Slerp(_targetTransform.rotation, targetRotation, t);
|
|
_targetTransform.position = focusPt - _targetTransform.forward * _focusPointOffset;
|
|
|
|
if (Mathf.Abs(Quaternion.Angle(_targetTransform.rotation, targetRotation)) < 1e-4f)
|
|
{
|
|
_targetTransform.rotation = targetRotation;
|
|
break;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
_isDoingRotationSwitch = false;
|
|
}
|
|
|
|
private IEnumerator DoConstantFocus(CameraFocus.Data focusData)
|
|
{
|
|
float targetOrthoSize = 0.5f * TargetCamera.GetFrustumHeightFromDistance(focusData.FocusPointOffset);
|
|
|
|
Vector3 camStartPos = _targetTransform.position;
|
|
Vector3 camMoveDir = Vector3.Normalize(focusData.CameraWorldPosition - camStartPos);
|
|
float distanceToTravel = (camStartPos - focusData.CameraWorldPosition).magnitude;
|
|
float initialCamOrthoSize = TargetCamera.orthographicSize;
|
|
|
|
_isDoingFocus = true;
|
|
while(true)
|
|
{
|
|
_targetTransform.position += camMoveDir * FocusSettings.ConstantSpeed * Time.deltaTime;
|
|
float t = 1.0f - (_targetTransform.position - focusData.CameraWorldPosition).magnitude / distanceToTravel;
|
|
TargetCamera.orthographicSize = Mathf.Lerp(initialCamOrthoSize, targetOrthoSize, t);
|
|
|
|
if (Vector3.Dot(camMoveDir, focusData.CameraWorldPosition - _targetTransform.position) <= 0.0f)
|
|
{
|
|
_targetTransform.position = focusData.CameraWorldPosition;
|
|
TargetCamera.orthographicSize = targetOrthoSize;
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
|
|
SetFocusPoint(focusData.FocusPoint);
|
|
_lastFocusPoint = focusData.FocusPoint;
|
|
_isDoingFocus = false;
|
|
}
|
|
|
|
private IEnumerator DoSmoothFocus(CameraFocus.Data focusData)
|
|
{
|
|
float targetOrthoSize = 0.5f * TargetCamera.GetFrustumHeightFromDistance(focusData.FocusPointOffset);
|
|
|
|
Vector3 camStartPos = _targetTransform.position;
|
|
Vector3 camMoveDir = Vector3.Normalize(focusData.CameraWorldPosition - camStartPos);
|
|
float elapsedTime = 0.0f;
|
|
|
|
_isDoingFocus = true;
|
|
while (true)
|
|
{
|
|
float t = elapsedTime / FocusSettings.SmoothTime;
|
|
_targetTransform.position = Vector3.Lerp(_targetTransform.position, focusData.CameraWorldPosition, t);
|
|
TargetCamera.orthographicSize = Mathf.Lerp(TargetCamera.orthographicSize, targetOrthoSize, t);
|
|
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
if (Vector3.Dot(camMoveDir, focusData.CameraWorldPosition - _targetTransform.position) <= 0.0f)
|
|
{
|
|
_targetTransform.position = focusData.CameraWorldPosition;
|
|
TargetCamera.orthographicSize = targetOrthoSize;
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
|
|
SetFocusPoint(focusData.FocusPoint);
|
|
_lastFocusPoint = focusData.FocusPoint;
|
|
_isDoingFocus = false;
|
|
}
|
|
|
|
private void OnPrjSwitchTransitionBegin(CameraPrjSwitchTransition.Type transitionType)
|
|
{
|
|
if (PrjSwitchTransitionBegin != null) PrjSwitchTransitionBegin(transitionType);
|
|
}
|
|
|
|
private void OnPrjSwitchTransitionUpate(CameraPrjSwitchTransition.Type transitionType)
|
|
{
|
|
if (PrjSwitchTransitionUpdate != null) PrjSwitchTransitionUpdate(transitionType);
|
|
}
|
|
|
|
private void OnPrjSwitchTransitionEnd(CameraPrjSwitchTransition.Type transitionType)
|
|
{
|
|
if (PrjSwitchTransitionEnd != null) PrjSwitchTransitionEnd(transitionType);
|
|
}
|
|
}
|
|
}
|