Files

256 lines
5.8 KiB
C#
Raw Permalink Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class overrideCameraController : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public bool cameraControllerEnabled = true;
public Transform targetToFollow;
public Transform pivotTransform;
public Transform cameraTransform;
public bool cameraActive;
public Vector2 xLimits;
public float rotationSpeed = 10;
public float cameraRotationSpeedVertical = 5;
public float cameraRotationSpeedHorizontal = 5;
public LayerMask layer;
public float clipCastRadius;
public float backClipSpeed;
[Space]
[Header ("Other Settings")]
[Space]
public float controllerRadius = 2;
public bool reapearInCertainPosition;
public Transform positionToReapear;
[Space]
[Header ("Gizmo Settings")]
[Space]
public bool showGizmo;
public Color gizmoColor = Color.yellow;
[Space]
[Header ("Components")]
[Space]
public overrideInputManager overrideInput;
Vector2 axisValues;
Vector2 mouseAxis;
Vector2 lookAngle;
Quaternion currentPivotRotation;
float currentCameraUpRotation;
Ray ray;
RaycastHit[] hits;
float currentCameraDistance;
float originalCameraDistance;
float cameraSpeed;
Coroutine updateCoroutine;
void Start ()
{
originalCameraDistance = cameraTransform.localPosition.magnitude;
}
public void stopUpdateCoroutine ()
{
if (updateCoroutine != null) {
StopCoroutine (updateCoroutine);
}
}
IEnumerator updateSystemCoroutine ()
{
var waitTime = new WaitForSecondsRealtime (0.0001f);
while (true) {
updateSystem ();
yield return waitTime;
}
}
void updateSystem ()
{
if (cameraControllerEnabled && cameraActive && !overrideInput.isGamePaused ()) {
transform.position = targetToFollow.position;
//get the current input axis values from the input manager
axisValues = overrideInput.getCustomMouseAxis ();
mouseAxis.x = axisValues.x;
mouseAxis.y = axisValues.y;
//if the first camera view is enabled
lookAngle.x = mouseAxis.x * rotationSpeed;
lookAngle.y -= mouseAxis.y * rotationSpeed;
//clamp these values to limit the camera rotation
lookAngle.y = Mathf.Clamp (lookAngle.y, xLimits.x, xLimits.y);
currentPivotRotation = Quaternion.Euler (lookAngle.y, 0, 0);
pivotTransform.localRotation = Quaternion.Slerp (pivotTransform.localRotation, currentPivotRotation, cameraRotationSpeedVertical * Time.deltaTime);
currentCameraUpRotation = Mathf.Lerp (currentCameraUpRotation, lookAngle.x, cameraRotationSpeedHorizontal * Time.deltaTime);
transform.Rotate (0, currentCameraUpRotation, 0);
//get the current camera position for the camera collision detection
currentCameraDistance = checkCameraCollision ();
//set the local camera position
currentCameraDistance = Mathf.Clamp (currentCameraDistance, 0, originalCameraDistance);
cameraTransform.localPosition = -Vector3.forward * currentCameraDistance;
}
}
public Transform getCameraTransform ()
{
return cameraTransform;
}
public void setCameraActiveState (bool state)
{
if (!cameraControllerEnabled) {
return;
}
cameraActive = state;
stopUpdateCoroutine ();
if (!cameraActive) {
lookAngle = Vector2.zero;
mouseAxis = Vector2.zero;
axisValues = Vector2.zero;
currentPivotRotation = Quaternion.identity;
currentCameraUpRotation = 0;
pivotTransform.localRotation = Quaternion.identity;
transform.rotation = Quaternion.identity;
}
if (cameraActive) {
updateCoroutine = StartCoroutine (updateSystemCoroutine ());
}
}
public bool isCameraControllerEnabled ()
{
return cameraControllerEnabled;
}
public void setParentState (bool state)
{
if (targetToFollow != null) {
if (state) {
transform.SetParent (null);
transform.position = targetToFollow.position;
} else {
transform.SetParent (targetToFollow);
}
}
}
public void resetLocalRotationPosition ()
{
transform.localRotation = Quaternion.identity;
transform.localPosition = Vector3.zero;
}
public void resetRotation (Quaternion newRotation)
{
transform.eulerAngles = new Vector3 (0, newRotation.eulerAngles.y, 0);
}
//adjust the camera position to avoid cross any collider
public float checkCameraCollision ()
{
//launch a ray from the pivot position to the camera direction
ray = new Ray (pivotTransform.position, -pivotTransform.forward);
//store the hits received
hits = Physics.SphereCastAll (ray, clipCastRadius, originalCameraDistance + clipCastRadius, layer);
float closest = Mathf.Infinity;
float hitDist = originalCameraDistance;
//find the closest
for (int i = 0; i < hits.Length; i++) {
if (hits [i].distance < closest && !hits [i].collider.isTrigger) {
//the camera will be moved that hitDist in its forward direction
closest = hits [i].distance;
hitDist = -pivotTransform.InverseTransformPoint (hits [i].point).z;
}
}
//clamp the hidDist value
if (hitDist < 0) {
hitDist = 0;
}
if (hitDist > originalCameraDistance) {
hitDist = originalCameraDistance;
}
//return the value of the collision in the camera
return Mathf.SmoothDamp (currentCameraDistance, hitDist, ref cameraSpeed, currentCameraDistance > hitDist ? 0 : backClipSpeed);
}
public float getControllerRadius ()
{
return controllerRadius;
}
public bool reapearInCertainPositionActive ()
{
return reapearInCertainPosition;
}
public Vector3 getPositionToReapear ()
{
if (positionToReapear != null) {
return positionToReapear.position;
} else {
return Vector3.zero;
}
}
//Draw gizmos
void OnDrawGizmos ()
{
if (!showGizmo) {
return;
}
if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) {
DrawGizmos ();
}
}
void OnDrawGizmosSelected ()
{
DrawGizmos ();
}
void DrawGizmos ()
{
if (showGizmo) {
Gizmos.color = gizmoColor;
Gizmos.DrawWireSphere (transform.position, controllerRadius);
}
}
}