【问题标题】:Unity: How to limit the zooming out of the cameraUnity:如何限制相机的缩小
【发布时间】:2019-01-16 02:44:07
【问题描述】:

使用 Unity 2018.3

此相机脚本允许用户放大和缩小并通过触摸移动相机。

Start() 上,脚本获取摄像机的当前位置并将其保存为越界限制。所以如果玩家放大并将相机移到一边,相机会在到达边界限制时停止。

我的问题是,目前用户可以缩小他们想要的一切,导致相机在脚本试图重新定位相机时摇晃,但这并不能阻止用户增加orthographicSize

如何限制用户缩小超出Start() 的超出范围限制?

public class ControlCamera : MonoBehaviour
{

    private Vector2?[] oldTouchPositions = {
        null,
        null
    };

    private Vector2 oldTouchVector;

    private float oldTouchDistance;

    private Vector3 bottomLeft;
    private Vector3 topRight;

    private float cameraMaxY;
    private float cameraMinY;
    private float cameraMaxX;
    private float cameraMinX;

    public float maxZoom;
    public float minZoom;

    private void Start()
    {
        //  Set max camera bounds
        topRight = GetComponent<Camera>().ScreenToWorldPoint(new Vector3(GetComponent<Camera>().pixelWidth, GetComponent<Camera>().pixelHeight, -transform.position.z));
        bottomLeft = GetComponent<Camera>().ScreenToWorldPoint(new Vector3(0, 0, -transform.position.z));
        cameraMaxX = topRight.x;
        cameraMaxY = topRight.y;
        cameraMinX = bottomLeft.x;
        cameraMinY = bottomLeft.y;
    }

    private void Update()
    {
        //  No touches
        if (Input.touchCount == 0)
        {
            oldTouchPositions[0] = null;
            oldTouchPositions[1] = null;
        }
        //  1 Touch
        else if (Input.touchCount == 1)
        {
            if (oldTouchPositions[0] == null || oldTouchPositions[1] != null)
            {
                oldTouchPositions[0] = Input.GetTouch(0).position;
                oldTouchPositions[1] = null;
            }
            else
            {
                Vector2 newTouchPosition = Input.GetTouch(0).position;

                transform.position += transform.TransformDirection((Vector3)((oldTouchPositions[0] - newTouchPosition) * GetComponent<Camera>().orthographicSize / GetComponent<Camera>().pixelHeight * 2f));

                oldTouchPositions[0] = newTouchPosition;
            }
            //  2 touches or more
        } else {

            if (oldTouchPositions[1] == null)
            {
                oldTouchPositions[0] = Input.GetTouch(0).position;
                oldTouchPositions[1] = Input.GetTouch(1).position;
                oldTouchVector = (Vector2)(oldTouchPositions[0] - oldTouchPositions[1]);
                oldTouchDistance = oldTouchVector.magnitude;

            } else {

                Vector2 screen = new Vector2(GetComponent<Camera>().pixelWidth, GetComponent<Camera>().pixelHeight);

                Vector2[] newTouchPositions = {
                    Input.GetTouch(0).position,
                    Input.GetTouch(1).position
                };
                Vector2 newTouchVector = newTouchPositions[0] - newTouchPositions[1];
                float newTouchDistance = newTouchVector.magnitude;

                transform.position += transform.TransformDirection((Vector3)((oldTouchPositions[0] + oldTouchPositions[1] - screen) * GetComponent<Camera>().orthographicSize / screen.y));
                GetComponent<Camera>().orthographicSize *= oldTouchDistance / newTouchDistance;
                transform.position -= transform.TransformDirection((newTouchPositions[0] + newTouchPositions[1] - screen) * GetComponent<Camera>().orthographicSize / screen.y);

                oldTouchPositions[0] = newTouchPositions[0];
                oldTouchPositions[1] = newTouchPositions[1];
                oldTouchVector = newTouchVector;
                oldTouchDistance = newTouchDistance;

                // --------------------------------------------------------------->>

                //  Control Zoom In
                if (GetComponent<Camera>().orthographicSize > minZoom)
                {
                    //
                }

                //  Control Zoom Out
                if (GetComponent<Camera>().orthographicSize < maxZoom)
                {
                    //
                }

                // --------------------------------------------------------------->>
            }
        }

        //  Check if camera is out-of-bounds, if so, move back in-bounds
        topRight = GetComponent<Camera>().ScreenToWorldPoint(new Vector3(GetComponent<Camera>().pixelWidth, GetComponent<Camera>().pixelHeight, -transform.position.z));
        bottomLeft = GetComponent<Camera>().ScreenToWorldPoint(new Vector3(0, 0, -transform.position.z));

        if (topRight.x > cameraMaxX)
        {
            transform.position = new Vector3(transform.position.x - (topRight.x - cameraMaxX), transform.position.y, transform.position.z);
        }

        if (topRight.y > cameraMaxY)
        {
            transform.position = new Vector3(transform.position.x, transform.position.y - (topRight.y - cameraMaxY), transform.position.z);
        }

        if (bottomLeft.x < cameraMinX)
        {
            transform.position = new Vector3(transform.position.x + (cameraMinX - bottomLeft.x), transform.position.y, transform.position.z);
        }

        if (bottomLeft.y < cameraMinY)
        {
            transform.position = new Vector3(transform.position.x, transform.position.y + (cameraMinY - bottomLeft.y), transform.position.z);
        }
    }
}

【问题讨论】:

  • 那么你在控制缩小和控制放大if语句中写了什么?

标签: unity3d


【解决方案1】:
  1. 您不应该重复使用GetComponent,尤其是在Update 或任何重复调用的方法中,因为这会产生很多不必要的开销。而是得到它一次

    private Camera camera;
    
    private void Awake()
    {
        camera = GetComponent<Camera>();
    }
    

    并重用该引用 -> 到处替换 GetComponent&lt;Camera&gt;() 宽度 camera

  2. 如果我的理解是正确的,orthographicSize 是世界单位中相机高度的一半。

    由于您已经在世界坐标中获得了topRightbottomLeft,您应该能够计算出orthographicSize

    maxZoom = (CameraMaxY - CameraMinY) / 2.0f;
    

    但是,如果您希望原始缩放成为最大缩放,您也可以简单地存储原始缩放,例如

    maxZoom = camera.orthographicSize;
    
  3. 以后你可以简单地clamp这个值

    camera.orthographicSize = Mathf.Clamp(
        camera.orthographicSize * oldTouchDistance / newTouchDistance, 
        minZoom, 
        maxZoom);
    

    -> 不需要额外的if 检查

【讨论】:

  • @WokerHead 很高兴为您提供帮助 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
相关资源
最近更新 更多