172 lines
3.9 KiB
C#
172 lines
3.9 KiB
C#
using UnityEngine;
|
|
|
|
namespace Gaia
|
|
{
|
|
public class CameraController : MonoBehaviour
|
|
{
|
|
public GameObject target;
|
|
|
|
public float targetHeight = 5f;
|
|
|
|
public float distance = 12f;
|
|
|
|
public float offsetFromWall = 0.1f;
|
|
|
|
public float maxDistance = 20f;
|
|
|
|
public float minDistance = 0.6f;
|
|
|
|
public float xSpeed = 200f;
|
|
|
|
public float ySpeed = 200f;
|
|
|
|
public float yMinLimit = -80f;
|
|
|
|
public float yMaxLimit = 80f;
|
|
|
|
public float zoomRate = 40f;
|
|
|
|
public float rotationDampening = 0.5f;
|
|
|
|
public float zoomDampening = 5f;
|
|
|
|
public LayerMask collisionLayers = -1;
|
|
|
|
public bool lockToRearOfTarget;
|
|
|
|
public bool allowMouseInputX = true;
|
|
|
|
public bool allowMouseInputY = true;
|
|
|
|
private float xDeg;
|
|
|
|
private float yDeg;
|
|
|
|
private float currentDistance;
|
|
|
|
private float desiredDistance;
|
|
|
|
private float correctedDistance;
|
|
|
|
private bool rotateBehind;
|
|
|
|
private bool mouseSideButton;
|
|
|
|
private float pbuffer;
|
|
|
|
private void Start()
|
|
{
|
|
Vector3 eulerAngles = base.transform.eulerAngles;
|
|
xDeg = eulerAngles.x;
|
|
yDeg = eulerAngles.y;
|
|
currentDistance = distance;
|
|
desiredDistance = distance;
|
|
correctedDistance = distance;
|
|
if (lockToRearOfTarget)
|
|
{
|
|
rotateBehind = true;
|
|
}
|
|
if (target == null)
|
|
{
|
|
target = GameObject.FindGameObjectWithTag("Player");
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (target == null)
|
|
{
|
|
return;
|
|
}
|
|
if (pbuffer > 0f)
|
|
{
|
|
pbuffer -= Time.deltaTime;
|
|
}
|
|
if (pbuffer < 0f)
|
|
{
|
|
pbuffer = 0f;
|
|
}
|
|
if (mouseSideButton && Input.GetAxis("Vertical") != 0f)
|
|
{
|
|
mouseSideButton = false;
|
|
}
|
|
if (GUIUtility.hotControl == 0)
|
|
{
|
|
if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
|
|
{
|
|
if (allowMouseInputX)
|
|
{
|
|
xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
|
|
}
|
|
else
|
|
{
|
|
RotateBehindTarget();
|
|
}
|
|
if (allowMouseInputY)
|
|
{
|
|
yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
|
|
}
|
|
if (!lockToRearOfTarget)
|
|
{
|
|
rotateBehind = false;
|
|
}
|
|
}
|
|
else if (Input.GetAxis("Vertical") != 0f || Input.GetAxis("Horizontal") != 0f || rotateBehind || mouseSideButton)
|
|
{
|
|
RotateBehindTarget();
|
|
}
|
|
}
|
|
yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
|
|
Quaternion quaternion = Quaternion.Euler(yDeg, xDeg, 0f);
|
|
desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
|
|
desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
|
|
correctedDistance = desiredDistance;
|
|
Vector3 vector = new Vector3(0f, 0f - targetHeight, 0f);
|
|
Vector3 end = target.transform.position - (quaternion * Vector3.forward * desiredDistance + vector);
|
|
Vector3 vector2 = new Vector3(target.transform.position.x, target.transform.position.y + targetHeight, target.transform.position.z);
|
|
bool flag = false;
|
|
if (Physics.Linecast(vector2, end, out var hitInfo, collisionLayers))
|
|
{
|
|
correctedDistance = Vector3.Distance(vector2, hitInfo.point) - offsetFromWall;
|
|
flag = true;
|
|
}
|
|
currentDistance = ((!flag || correctedDistance > currentDistance) ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance);
|
|
currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance);
|
|
end = target.transform.position - (quaternion * Vector3.forward * currentDistance + vector);
|
|
base.transform.rotation = quaternion;
|
|
base.transform.position = end;
|
|
}
|
|
|
|
private void RotateBehindTarget()
|
|
{
|
|
float y = target.transform.eulerAngles.y;
|
|
float y2 = base.transform.eulerAngles.y;
|
|
xDeg = Mathf.LerpAngle(y2, y, rotationDampening * Time.deltaTime);
|
|
if (y == y2)
|
|
{
|
|
if (!lockToRearOfTarget)
|
|
{
|
|
rotateBehind = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rotateBehind = true;
|
|
}
|
|
}
|
|
|
|
private float ClampAngle(float angle, float min, float max)
|
|
{
|
|
if (angle < -360f)
|
|
{
|
|
angle += 360f;
|
|
}
|
|
if (angle > 360f)
|
|
{
|
|
angle -= 360f;
|
|
}
|
|
return Mathf.Clamp(angle, min, max);
|
|
}
|
|
}
|
|
}
|