80 lines
2.9 KiB
C#
Raw Normal View History

2020-11-01 11:52:31 +00:00
using UnityEngine;
2020-10-28 21:41:07 +00:00
namespace QSB.Instruments.QSBCamera
{
class CameraController : MonoBehaviour
{
private float _degreesX;
private float _degreesY;
private Quaternion _rotationX;
private Quaternion _rotationY;
2020-11-01 11:57:15 +00:00
// How far along the ray to move the camera. Avoids clipping into the walls.
2020-11-02 22:15:46 +00:00
private const float PercentToMove = 0.80f;
2020-11-01 11:57:15 +00:00
// Maximum distance for camera clipping
2020-11-02 22:15:46 +00:00
private const float RayLength = 5f;
2020-11-01 11:52:31 +00:00
public GameObject CameraObject;
2020-10-28 21:41:07 +00:00
void FixedUpdate()
{
if (CameraManager.Instance.Mode != CameraMode.ThirdPerson)
{
return;
}
2020-11-01 11:52:31 +00:00
UpdatePosition();
2020-10-28 21:41:07 +00:00
UpdateInput();
UpdateRotation();
}
2020-11-01 11:52:31 +00:00
private void UpdatePosition()
{
var origin = transform.position;
var localDirection = CameraObject.transform.localPosition.normalized;
Vector3 localTargetPoint;
2020-11-01 11:57:15 +00:00
if (Physics.Raycast(origin, transform.TransformDirection(localDirection), out RaycastHit outRay, RayLength, LayerMask.GetMask("Default")))
2020-11-01 11:52:31 +00:00
{
2020-11-01 12:26:09 +00:00
// Raycast hit collider, get target from hitpoint.
2020-11-01 11:52:31 +00:00
localTargetPoint = transform.InverseTransformPoint(outRay.point) * PercentToMove;
}
else
{
2020-11-01 12:26:09 +00:00
// Raycast didn't hit collider, get target from camera direction
2020-11-01 11:57:15 +00:00
localTargetPoint = localDirection * RayLength * PercentToMove;
2020-11-01 11:52:31 +00:00
}
var targetDistance = Vector3.Distance(origin, transform.TransformPoint(localTargetPoint));
var currentDistance = Vector3.Distance(origin, CameraObject.transform.position);
Vector3 movement;
if (targetDistance < currentDistance)
{
// Snap to target to avoid clipping
movement = localTargetPoint;
}
else
{
// Move camera out slowly
movement = Vector3.MoveTowards(CameraObject.transform.localPosition, localTargetPoint, Time.fixedDeltaTime * 2f);
}
CameraObject.transform.localPosition = movement;
}
2020-10-28 21:41:07 +00:00
private void UpdateInput()
{
var input = OWInput.GetValue(InputLibrary.look, false, InputMode.All);
_degreesX += input.x * 180f * Time.fixedDeltaTime;
_degreesY += input.y * 180f * Time.fixedDeltaTime;
}
private void UpdateRotation()
{
_degreesX %= 360f;
_degreesY %= 360f;
_degreesY = Mathf.Clamp(_degreesY, -80f, 80f);
_rotationX = Quaternion.AngleAxis(_degreesX, Vector3.up);
2020-11-01 11:57:15 +00:00
_rotationY = Quaternion.AngleAxis(_degreesY, Vector3.left);
2020-10-28 21:41:07 +00:00
var localRotation = _rotationX * _rotationY * Quaternion.identity;
2020-11-01 11:52:31 +00:00
transform.localRotation = localRotation;
2020-10-28 21:41:07 +00:00
}
}
}