private bool CullingRayCast(Vector3 from, Utility.ClipPlanePoints _to, out RaycastHit hitInfo, float distance, LayerMask cullingLayer, Color color) { bool value = false; if (showGizmos) { Debug.DrawRay(from, _to.LowerLeft - from, color); Debug.DrawLine(_to.LowerLeft, _to.LowerRight, color); Debug.DrawLine(_to.UpperLeft, _to.UpperRight, color); Debug.DrawLine(_to.UpperLeft, _to.LowerLeft, color); Debug.DrawLine(_to.UpperRight, _to.LowerRight, color); Debug.DrawRay(from, _to.LowerRight - from, color); Debug.DrawRay(from, _to.UpperLeft - from, color); Debug.DrawRay(from, _to.UpperRight - from, color); } if (Physics.Raycast(from, _to.LowerLeft - from, out hitInfo, distance, cullingLayer)) { value = true; CullingDistance = hitInfo.distance; } if (Physics.Raycast(from, _to.LowerRight - from, out hitInfo, distance, cullingLayer)) { value = true; if (CullingDistance > hitInfo.distance) { CullingDistance = hitInfo.distance; } } if (Physics.Raycast(from, _to.UpperLeft - from, out hitInfo, distance, cullingLayer)) { value = true; if (CullingDistance > hitInfo.distance) { CullingDistance = hitInfo.distance; } } if (Physics.Raycast(from, _to.UpperRight - from, out hitInfo, distance, cullingLayer)) { value = true; if (CullingDistance > hitInfo.distance) { CullingDistance = hitInfo.distance; } } return(value); }
private void CameraMovement() { if (currentTarget == null || _camera == null) { return; } if (useSmooth) { currentState.Slerp(transitionState, smoothBetweenState * Time.deltaTime); } else { currentState.CopyState(transitionState); } if (currentState.useZoom) { currentZoom = Mathf.Clamp(currentZoom, currentState.minDistance, currentState.maxDistance); distance = useSmooth ? Mathf.Lerp(distance, currentZoom, transitionState.smoothFollow * Time.deltaTime) : currentZoom; } else { distance = useSmooth ? Mathf.Lerp(distance, currentState.defaultDistance, transitionState.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; #region Clipping RaycastHit hitInfo; Utility.ClipPlanePoints planePoints = _camera.NearClipPlanePoints(current_cPos + (camDir * (distance)), clipPlaneMargin); Utility.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)) { hitSomething = true; 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; hitSomething = true; } } 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); } #endregion 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; if (hitSomething) { transform.position = Vector3.Lerp(transform.position, current_cPos + (camDir * (distance)), Time.deltaTime * collisionRecoverSpeed); hitSomething = false; } else { transform.position = current_cPos + (camDir * (distance)); } var rotation = Quaternion.LookRotation((lookPoint) - transform.position); if (blackboard.lockOnPressed) { SetLockTarget(blackboard.lockTarget); } else { ClearLockOnTarget(); } if (lockTarget) { CalculateLockOnPoint(); 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; }