Files
beyond/Assets/Scripts/InvectorDerivatives/bThirdPersonCamera.cs

192 lines
9.4 KiB
C#

using Invector;
using Invector.vCamera;
using UnityEngine;
namespace Beyond
{
public class bThirdPersonCamera : vThirdPersonCamera
{
private static bThirdPersonCamera _instance;
public static new bThirdPersonCamera instance
{
get { return _instance; }
}
private void Awake()
{
if (_instance == null)
{
_instance = this;
}
else
{
Debug.LogError("bThirdPersonCamera already exists!");
Destroy(gameObject);
}
}
public Vector3 GetCameraTargetPosition(bool useDefaultRotation)
{
if (currentTarget)
{
var camDir = (currentState.forward * targetLookAt.forward) + ((currentState.right * currentSwitchRight) * targetLookAt.right);
camDir = camDir.normalized;
var targetPos = new Vector3(currentTarget.position.x, currentTarget.position.y, currentTarget.position.z) + currentTarget.transform.up * offSetPlayerPivot;
current_cPos = targetPos + currentTarget.transform.up * currentHeight;
return current_cPos + (camDir * (distance));
}
else
{
return transform.position;
}
}
//********************************************************************************//
// >> CUSTOM CAMERA LOGIC OVERRIDE << //
//********************************************************************************//
// This method overrides the base class's CameraMovement function. //
// The new logic prioritizes pushing the camera towards the player in narrow //
// spaces, and only raises the camera's height as a last resort when it gets //
// too close. This prevents the camera from going over the player's head in //
// tight corridors. //
//********************************************************************************//
/*
protected override void CameraMovement(bool forceUpdate = false)
{
if (currentTarget == null || targetCamera == null || (!firstStateIsInit && !forceUpdate))
{
base.CameraMovement(forceUpdate);
return;
}
transformWeight = Mathf.Clamp(transformWeight += Time.fixedDeltaTime, 0f, 1f);
if (useSmooth)
{
currentState.Slerp(lerpState, smoothBetweenState * Time.fixedDeltaTime);
}
else
{
currentState.CopyState(lerpState);
}
if (currentState.useZoom)
{
currentZoom = Mathf.Clamp(currentZoom, currentState.minDistance, currentState.maxDistance);
distance = useSmooth ? Mathf.Lerp(distance, currentZoom, lerpState.smooth * Time.fixedDeltaTime) : currentZoom;
}
else
{
distance = useSmooth ? Mathf.Lerp(distance, currentState.defaultDistance, lerpState.smooth * Time.fixedDeltaTime) : currentState.defaultDistance;
currentZoom = currentState.defaultDistance;
}
targetCamera.fieldOfView = currentState.fov;
cullingDistance = Mathf.Lerp(cullingDistance, currentZoom, smoothBetweenState * Time.fixedDeltaTime);
currentSwitchRight = Mathf.Lerp(currentSwitchRight, switchRight, smoothSwitchSide * Time.fixedDeltaTime);
var camDir = (currentState.forward * targetLookAt.forward) + ((currentState.right * currentSwitchRight) * targetLookAt.right);
camDir = camDir.normalized;
var targetPos = new Vector3(currentTarget.position.x, currentTarget.position.y, currentTarget.position.z) + currentTarget.transform.up * offSetPlayerPivot;
currentTargetPos = targetPos;
desired_cPos = targetPos + currentTarget.transform.up * currentState.height;
current_cPos = firstUpdated ? targetPos + currentTarget.transform.up * currentHeight : Vector3.SmoothDamp(current_cPos, targetPos + currentTarget.transform.up * currentHeight, ref cameraVelocityDamp, lerpState.smoothDamp * Time.fixedDeltaTime);
firstUpdated = false;
RaycastHit hitInfo;
// --- Start of Modified Collision Logic ---
if (Physics.SphereCast(targetPos, checkHeightRadius, currentTarget.transform.up, out hitInfo, currentState.cullingHeight + 0.2f, cullingLayer))
{
var t = hitInfo.distance - 0.2f;
t -= currentState.height;
t /= (currentState.cullingHeight - currentState.height);
cullingHeight = Mathf.Lerp(currentState.height, currentState.cullingHeight, Mathf.Clamp(t, 0.0f, 1.0f));
}
else
{
cullingHeight = useSmooth ? Mathf.Lerp(cullingHeight, currentState.cullingHeight, smoothBetweenState * Time.fixedDeltaTime) : currentState.cullingHeight;
}
currentHeight = useSmooth ? Mathf.Lerp(currentHeight, currentState.height, smoothBetweenState * Time.fixedDeltaTime) : currentState.height;
var temporary_cPos = targetPos + currentTarget.transform.up * currentHeight;
ClipPlanePoints clipPoints = targetCamera.NearClipPlanePoints(temporary_cPos + (camDir * distance), clipPlaneMargin);
if (CullingRayCast(temporary_cPos, clipPoints, out hitInfo, distance, cullingLayer, Color.cyan))
{
distance = Mathf.Clamp(hitInfo.distance - clipPlaneMargin, 0.0f, currentState.defaultDistance);
}
if (distance < currentState.cullingMinDist)
{
var t = distance / currentState.cullingMinDist;
currentHeight = Mathf.Lerp(cullingHeight, currentState.height, Mathf.Clamp01(t));
}
current_cPos = targetPos + currentTarget.transform.up * currentHeight;
clipPoints = targetCamera.NearClipPlanePoints(current_cPos + (camDir * currentState.defaultDistance), clipPlaneMargin);
if (CullingRayCast(current_cPos, clipPoints, out hitInfo, currentState.defaultDistance, cullingLayer, Color.cyan))
{
distance = Mathf.Clamp(hitInfo.distance - clipPlaneMargin, 0.0f, currentState.defaultDistance);
}
// --- End of Modified Collision Logic ---
var lookPoint = current_cPos + targetLookAt.forward * targetCamera.farClipPlane;
lookPoint += (targetLookAt.right * Vector3.Dot(camDir * (distance), targetLookAt.right));
targetLookAt.position = current_cPos;
float _mouseY = Mathf.LerpAngle(mouseYStart, mouseY, transformWeight);
float _mouseX = Mathf.LerpAngle(mouseXStart, mouseX, transformWeight);
Quaternion newRot = Quaternion.Euler(_mouseY + offsetMouse.y, _mouseX + offsetMouse.x, 0);
targetLookAt.rotation = useSmooth ? Quaternion.Lerp(targetLookAt.rotation, newRot, smoothCameraRotation * Time.fixedDeltaTime) : newRot;
selfRigidbody.MovePosition(Vector3.Lerp(startPosition, current_cPos + (camDir * (distance)), transformWeight));
var rotation = Quaternion.LookRotation((lookPoint) - selfRigidbody.position);
if (lockTarget)
{
CalculeLockOnPoint();
if (!(currentState.cameraMode.Equals(TPCameraMode.FixedAngle)))
{
var collider = lockTarget.GetComponent<Collider>();
if (collider != null)
{
var point = (collider.bounds.center + Vector3.up * heightOffset) - selfRigidbody.position;
var euler = Quaternion.LookRotation(point).eulerAngles - rotation.eulerAngles;
if (isNewTarget)
{
lookTargetAdjust.x = Mathf.LerpAngle(lookTargetAdjust.x, euler.x, lockTargetWeight);
lookTargetAdjust.y = Mathf.LerpAngle(lookTargetAdjust.y, euler.y, lockTargetWeight);
lookTargetAdjust.z = Mathf.LerpAngle(lookTargetAdjust.z, euler.z, lockTargetWeight);
if (Vector3.Distance(lookTargetAdjust, euler) < .5f)
{
isNewTarget = false;
}
}
else
{
lookTargetAdjust = euler;
}
}
}
}
else
{
lookTargetAdjust.x = Mathf.LerpAngle(lookTargetAdjust.x, 0, currentState.smooth * Time.fixedDeltaTime);
lookTargetAdjust.y = Mathf.LerpAngle(lookTargetAdjust.y, 0, currentState.smooth * Time.fixedDeltaTime);
lookTargetAdjust.z = Mathf.LerpAngle(lookTargetAdjust.z, 0, currentState.smooth * Time.fixedDeltaTime);
}
var _euler = rotation.eulerAngles + lookTargetAdjust;
_euler.z = 0;
var _rot = Quaternion.Euler(_euler + currentState.rotationOffSet);
selfRigidbody.MoveRotation(Quaternion.Lerp(startRotation, _rot, transformWeight));
movementSpeed = Vector2.zero;
}
*/
}
}