Пример #1
0
    void LateUpdate()
    {
        float wheel = Input.GetAxis("Mouse ScrollWheel");

        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        bool rayIntersectsAnyCollider = Physics.Raycast(ray, out hit, maxCameraDistance, lm.value);

        //print(state);

        if (isLocked)
        {
            if (lockedTransform != null)
            {
                offSet = lockedTransform.position - off;
                off    = lockedTransform.position;                                                         //in case the lockedTransform is moving

                if (Input.GetMouseButton(1) == false)
                {
                    state = CameraState.isIdling;

                    float magnitude = (targetTransform.position - transform.position).magnitude;           //in case the lockedTransform is moving
                    transform.position       = targetTransform.position - (transform.rotation * Vector3.forward * magnitude) + offSet;
                    targetTransform.position = lockedTransform.position;
                }
            }
            else
            {
                isLocked = false;
            }
        }

        if (state != CameraState.isTargeting)
        {
            if (panMode == true && Input.GetMouseButton(2) == true)
            {
                if (state != CameraState.isPanning)
                {
                    lastMousePos = Input.mousePosition;
                }

                state = CameraState.isPanning;
            }
            if (Input.GetMouseButton(1) == true)
            {
                state = CameraState.isRotating;
            }
            else if (Input.GetMouseButtonUp(1))
            {
                yDeg = transform.rotation.eulerAngles.x;
                if (yDeg > 180)
                {
                    yDeg -= 360;
                }

                xDeg = transform.rotation.eulerAngles.y;

                state = CameraState.isIdling;
            }
            else if (wheel != 0)
            {
                state = CameraState.isZooming;
            }
        }

        switch (state)
        {
            #region Idling
        case CameraState.isIdling:
            break;
            #endregion

            #region Rotating
        case CameraState.isRotating:

            float getAxisX = Input.GetAxis("Mouse X");
            float getAxisY = Input.GetAxis("Mouse Y");

            if (Mathf.Abs(getAxisX) > 0.05f || Mathf.Abs(getAxisY) > 0.05f)
            {
                isMovingWithRotation = true;
            }

            xDeg += getAxisX * xSpeed;
            yDeg -= getAxisY * ySpeed;
            yDeg  = ClampAngle(yDeg, yMinLimit, yMaxLimit, 5);

            transform.rotation    = Quaternion.Lerp(transform.rotation, Quaternion.Euler(yDeg, xDeg, 0), Time.deltaTime * rotationDampening / Time.timeScale);
            transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0);

            float magnitude = (targetTransform.position - transform.position).magnitude;
            transform.position = targetTransform.position - (transform.rotation * Vector3.forward * magnitude) + offSet;

            targetTransform.position = targetTransform.position + offSet;

            break;
            #endregion

            #region Zooming
        case CameraState.isZooming:

            Vector3 hitPoint = Vector3.zero;
            if (rayIntersectsAnyCollider)
            {
                hitPoint = hit.point;
            }
            else
            {
                planeZero.Raycast(ray, out float enter1);
                hitPoint = ray.GetPoint(enter1);
            }
            perpendToViewplane.SetNormalAndPosition(-transform.forward, hitPoint);

            perpendToViewplane.Raycast(ray, out enter);
            rayPlanePoint = ray.GetPoint(Mathf.Min(enter, 100f));
            ray.direction = transform.forward;

            float par = 0.33f;
            enter = Mathf.Abs(enter);
            targetTransform.position = transform.forward * enter + transform.position;
            if (wheel > 0)
            {
                desiredPosition = MathLibrary.ClampMagnitude((rayPlanePoint - transform.position), cameraMaxDistance, 10) * par + transform.position;
            }
            else if (wheel < 0)
            {
                desiredPosition = -MathLibrary.ClampMagnitude((targetTransform.position - transform.position), cameraMaxDistance, 10) * par + transform.position;
            }

            transform.position = Vector3.Lerp(transform.position, desiredPosition, zoomRate * Time.deltaTime / Time.timeScale);

            if (Vector3.SqrMagnitude(transform.position - desiredPosition) < zoomThres)
            {
                state = CameraState.isIdling;
            }
            break;
            #endregion

            #region Panning
        case CameraState.isPanning:

            Vector3 v             = new Vector3(Input.mousePosition.x - lastMousePos.x, 0, Input.mousePosition.y - lastMousePos.y);
            Vector3 centerToMouse = transform.rotation * v;
            centerToMouse.y = 0;

            centerToMouse.Normalize();
            centerToMouse *= 30;
            centerToMouse *= transform.position.y;

            float distFromCenter = centerToMouse.magnitude;

            if (lockedTransform != null)
            {
                UnlockObject();
            }

            rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z);

            //targetTransform.Translate(centerToMouse * Time.deltaTime * panSpeed);   //here, right is wrt the loc ref because Space.Self by default
            //transform.Translate(centerToMouse * Time.deltaTime * panSpeed);

            float t = panSpeed * Time.deltaTime / Time.timeScale;

            targetTransform.position = Vector3.Lerp(targetTransform.position, transform.position + centerToMouse, t);
            transform.position       = Vector3.Lerp(transform.position, transform.position + centerToMouse, t);

            if (Input.GetMouseButtonUp(2) == true)
            {
                state = CameraState.isIdling;
            }
            break;
            #endregion

            //#region Panning
            //case CameraState.isPanning:
            //    Vector3 screenCenter = new Vector3(Screen.width, Screen.height, 0) * 0.5f;
            //    Vector3 centerToMouse = Input.mousePosition - lastMousePos;
            //    float distFromCenter = centerToMouse.magnitude;
            //    if (lockedTransform != null) {
            //        UnlockObject();
            //    }
            //    rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z);
            //    //targetTransform.Translate(centerToMouse * Time.deltaTime * panSpeed);   //here, right is wrt the loc ref because Space.Self by default
            //    //transform.Translate(centerToMouse * Time.deltaTime * panSpeed);
            //    targetTransform.position = Vector3.Lerp(transform.position, transform.position + centerToMouse, panSpeed * Time.deltaTime / Time.timeScale);
            //    transform.position = Vector3.Lerp(transform.position, transform.position + centerToMouse, panSpeed * Time.deltaTime / Time.timeScale);
            //    if (Input.GetMouseButtonUp(2) == true) {
            //        state = CameraState.isIdling;
            //    }
            //    //float panNorm = transform.position.y;
            //    //if ((Input.mousePosition.x - Screen.width + panThres) > 0) {
            //    //    targetTransform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm);   //here, right is wrt the loc ref because Space.Self by default
            //    //    transform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm);
            //    //} else if ((Input.mousePosition.x - panThres) < 0) {
            //    //    targetTransform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm);
            //    //    transform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm);
            //    //}
            //    //if ((Input.mousePosition.y - Screen.height + panThres) > 0) {
            //    //    rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z);
            //    //    targetTransform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //    transform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //}
            //    //if ((Input.mousePosition.y - panThres) < 0) {
            //    //    rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z);
            //    //    targetTransform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //    transform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //}
            //    //if (lockedTransform != null)
            //    //    UnlockObject();
            //    //float panNorm = transform.position.y;
            //    //if ((Input.mousePosition.x - Screen.width + panThres) > 0) {
            //    //    targetTransform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm);   //here, right is wrt the loc ref because Space.Self by default
            //    //    transform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm);
            //    //} else if ((Input.mousePosition.x - panThres) < 0) {
            //    //    targetTransform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm);
            //    //    transform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm);
            //    //}
            //    //if ((Input.mousePosition.y - Screen.height + panThres) > 0) {
            //    //    rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z);
            //    //    targetTransform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //    transform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //}
            //    //if ((Input.mousePosition.y - panThres) < 0) {
            //    //    rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z);
            //    //    targetTransform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //    transform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World);
            //    //}
            //    break;
            //#endregion

            #region Targeting
        case CameraState.isTargeting:

            off    = lockedTransform.position;
            offSet = lockedTransform.position - off;
            targetTransform.position = Vector3.Lerp(targetTransform.position, lockedTransform.position,
                                                    3 * zoomRate * Time.deltaTime / Time.timeScale);

            desiredPosition = targetTransform.position - limit * transform.forward;

            transform.position = Vector3.Lerp(transform.position, desiredPosition, zoomRate * Time.deltaTime / Time.timeScale);

            if (Vector3.SqrMagnitude(transform.position - desiredPosition) < 50 * 50)
            {
                state = CameraState.isIdling;
            }

            break;
            #endregion

        default:
            break;
        }

        targetTransform.position = Vector3.ClampMagnitude(targetTransform.position, cameraMaxDistance);
        distanceTozero           = transform.position.magnitude;
        if (distanceTozero > cameraMaxDistance)
        {
            transform.position = Vector3.ClampMagnitude(transform.position, cameraMaxDistance);
        }
    }