void CameraMovement() { if (currentTarget == null || _camera == null) { return; } if (useSmooth) { currentState.Slerp(lerpState, smoothBetweenState * Time.deltaTime); } else { currentState.CopyState(lerpState); } if (currentState.useZoom) { currentZoom = Mathf.Clamp(currentZoom, currentState.minDistance, currentState.maxDistance); distance = useSmooth ? Mathf.Lerp(distance, currentZoom, lerpState.smoothFollow * Time.deltaTime) : currentZoom; } else { distance = useSmooth ? Mathf.Lerp(distance, currentState.defaultDistance, lerpState.smoothFollow * Time.deltaTime) : currentState.defaultDistance; currentZoom = currentState.defaultDistance; } _camera.fieldOfView = currentState.fov; cullingDistance = Mathf.Lerp(cullingDistance, currentZoom, smoothBetweenState * Time.deltaTime); currentSwitchRight = Mathf.Lerp(currentSwitchRight, switchRight, smoothBetweenState * Time.deltaTime); 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 = targetPos + currentTarget.transform.up * currentHeight; RaycastHit hitInfo; ClipPlanePoints planePoints = _camera.NearClipPlanePoints(current_cPos + (camDir * (distance)), clipPlaneMargin); ClipPlanePoints oldPoints = _camera.NearClipPlanePoints(desired_cPos + (camDir * currentZoom), clipPlaneMargin); //Check if Height is not blocked 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.deltaTime) : currentState.cullingHeight; } //Check if desired target position is not blocked if (CullingRayCast(desired_cPos, oldPoints, out hitInfo, currentZoom + 0.2f, cullingLayer, Color.blue)) { distance = hitInfo.distance - 0.2f; if (distance < currentState.defaultDistance) { var t = hitInfo.distance; t -= currentState.cullingMinDist; t /= (currentZoom - currentState.cullingMinDist); currentHeight = Mathf.Lerp(cullingHeight, currentState.height, Mathf.Clamp(t, 0.0f, 1.0f)); current_cPos = targetPos + currentTarget.transform.up * currentHeight; } } else { currentHeight = useSmooth ? Mathf.Lerp(currentHeight, currentState.height, smoothBetweenState * Time.deltaTime) : currentState.height; } //Check if target position with culling height applied is not blocked if (CullingRayCast(current_cPos, planePoints, out hitInfo, distance, cullingLayer, Color.cyan)) { distance = Mathf.Clamp(cullingDistance, 0.0f, currentState.defaultDistance); } var lookPoint = current_cPos + targetLookAt.forward * 2f; lookPoint += (targetLookAt.right * Vector3.Dot(camDir * (distance), targetLookAt.right)); targetLookAt.position = current_cPos; Quaternion newRot = Quaternion.Euler(mouseY + offsetMouse.y, mouseX + offsetMouse.x, 0); targetLookAt.rotation = useSmooth ? Quaternion.Lerp(targetLookAt.rotation, newRot, smoothCameraRotation * Time.deltaTime) : newRot; transform.position = current_cPos + (camDir * (distance)); var rotation = Quaternion.LookRotation((lookPoint) - transform.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) - transform.position; var euler = Quaternion.LookRotation(point).eulerAngles - rotation.eulerAngles; if (isNewTarget) { lookTargetAdjust.x = Mathf.LerpAngle(lookTargetAdjust.x, euler.x, currentState.smoothFollow * Time.deltaTime); lookTargetAdjust.y = Mathf.LerpAngle(lookTargetAdjust.y, euler.y, currentState.smoothFollow * Time.deltaTime); lookTargetAdjust.z = Mathf.LerpAngle(lookTargetAdjust.z, euler.z, currentState.smoothFollow * Time.deltaTime); // Quaternion.LerpUnclamped(lookTargetAdjust, Quaternion.Euler(euler), currentState.smoothFollow * Time.deltaTime); if (Vector3.Distance(lookTargetAdjust, euler) < .5f) { isNewTarget = false; } } else { lookTargetAdjust = euler; } } } } else { lookTargetAdjust.x = Mathf.LerpAngle(lookTargetAdjust.x, 0, currentState.smoothFollow * Time.deltaTime); lookTargetAdjust.y = Mathf.LerpAngle(lookTargetAdjust.y, 0, currentState.smoothFollow * Time.deltaTime); lookTargetAdjust.z = Mathf.LerpAngle(lookTargetAdjust.z, 0, currentState.smoothFollow * Time.deltaTime); //lookTargetAdjust = Quaternion.LerpUnclamped(lookTargetAdjust, Quaternion.Euler(Vector3.zero), 1 * Time.deltaTime); } var _euler = rotation.eulerAngles + lookTargetAdjust; _euler.z = 0; var _rot = Quaternion.Euler(_euler + currentState.rotationOffSet); transform.rotation = _rot; movementSpeed = Vector2.zero; if (currentState.cameraMode.Equals(TPCameraMode.FixedAngle)) { RotateCamera(currentState.fixedAngle.x, currentState.fixedAngle.y);//if fixed angle state (update the rotation) } }