Beispiel #1
0
        public static ClipPlanePoints NearClipPlanePoints(this Camera camera, Vector3 pos, float clipPlaneMargin)
        {
            var clipPlanePoints = new ClipPlanePoints();

            var transform = camera.transform;
            var halfFOV   = (camera.fieldOfView / 2) * Mathf.Deg2Rad;
            var aspect    = camera.aspect;
            var distance  = camera.nearClipPlane;
            var height    = distance * Mathf.Tan(halfFOV);
            var width     = height * aspect;

            height *= 1 + clipPlaneMargin;
            width  *= 1 + clipPlaneMargin;
            clipPlanePoints.LowerRight  = pos + transform.right * width;
            clipPlanePoints.LowerRight -= transform.up * height;
            clipPlanePoints.LowerRight += transform.forward * distance;

            clipPlanePoints.LowerLeft  = pos - transform.right * width;
            clipPlanePoints.LowerLeft -= transform.up * height;
            clipPlanePoints.LowerLeft += transform.forward * distance;

            clipPlanePoints.UpperRight  = pos + transform.right * width;
            clipPlanePoints.UpperRight += transform.up * height;
            clipPlanePoints.UpperRight += transform.forward * distance;

            clipPlanePoints.UpperLeft  = pos - transform.right * width;
            clipPlanePoints.UpperLeft += transform.up * height;
            clipPlanePoints.UpperLeft += transform.forward * distance;

            return(clipPlanePoints);
        }
        bool CullingRayCast(Vector3 from, 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);
        }
        void CameraMovement(bool forceUpdate = false)
        {
            if (currentTarget == null || _camera == null || (!firstStateIsInit && !forceUpdate))
            {
                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.smooth * Time.deltaTime) : currentZoom;
            }
            else
            {
                distance    = useSmooth ? Mathf.Lerp(distance, currentState.defaultDistance, lerpState.smooth * 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     = firstUpdated ? targetPos + currentTarget.transform.up * currentHeight:  Vector3.SmoothDamp(current_cPos, targetPos + currentTarget.transform.up * currentHeight, ref cameraVelocityDamp, lerpState.smoothDamp * Time.deltaTime);
            firstUpdated     = false;
            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.smooth * Time.deltaTime);
                            lookTargetAdjust.y = Mathf.LerpAngle(lookTargetAdjust.y, euler.y, currentState.smooth * Time.deltaTime);
                            lookTargetAdjust.z = Mathf.LerpAngle(lookTargetAdjust.z, euler.z, currentState.smooth * 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.smooth * Time.deltaTime);
                lookTargetAdjust.y = Mathf.LerpAngle(lookTargetAdjust.y, 0, currentState.smooth * Time.deltaTime);
                lookTargetAdjust.z = Mathf.LerpAngle(lookTargetAdjust.z, 0, currentState.smooth * 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;
        }