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(); 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; } */ } }