首页 > 解决方案 > 统一3D。C#。我可以添加最大值和最小值来放大这段代码吗?

问题描述

在 3D 项目中,我有脚本,我可以毫无疑问地在场景中旋转/移动,但是缩放有问题,我可以做的太近和太远。我将它放大到地板或远处的天空,然后堆叠。我使用透视相机。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

class ScrollAndPinch : MonoBehaviour
{
    public Camera Camera;
    public bool Rotate;
    protected Plane Plane;

    private void Awake()
    {
        if (Camera == null)
            Camera = Camera.main;
    }

    private void Update()
    {

        //Update Plane
        if (Input.touchCount >= 1)
            Plane.SetNormalAndPosition(transform.up, transform.position);

        var Delta1 = Vector3.zero;
        var Delta2 = Vector3.zero;

        //Scroll
        if (Input.touchCount >= 1)
        {
            Delta1 = PlanePositionDelta(Input.GetTouch(0));
            if (Input.GetTouch(0).phase == TouchPhase.Moved)
                Camera.transform.Translate(Delta1, Space.World);
        }

        //Pinch
        if (Input.touchCount >= 2)
        {
            var pos1 = PlanePosition(Input.GetTouch(0).position);
            var pos2 = PlanePosition(Input.GetTouch(1).position);
            var pos1b = PlanePosition(Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition);
            var pos2b = PlanePosition(Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition);

            //calc zoom
            var zoom = Vector3.Distance(pos1, pos2) /
                       Vector3.Distance(pos1b, pos2b);

            //edge case
            if (zoom == 9 || zoom > 10)
                return;


            //Move cam amount the mid ray
            Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, 1 / zoom);

            if (Rotate && pos2b != pos2)
                Camera.transform.RotateAround(pos1, Plane.normal, Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal));
        }

    }


    protected Vector3 PlanePositionDelta(Touch touch)
    {
        //not moved
        if (touch.phase != TouchPhase.Moved)
            return Vector3.zero;

        //delta
        var rayBefore = Camera.ScreenPointToRay(touch.position - touch.deltaPosition);
        var rayNow = Camera.ScreenPointToRay(touch.position);
        if (Plane.Raycast(rayBefore, out var enterBefore) && Plane.Raycast(rayNow, out var enterNow))
            return rayBefore.GetPoint(enterBefore) - rayNow.GetPoint(enterNow);

        //not on plane
        return Vector3.zero;
    }

    protected Vector3 PlanePosition(Vector2 screenPos)
    {
        //position
        var rayNow = Camera.ScreenPointToRay(screenPos);
        if (Plane.Raycast(rayNow, out var enterNow))
            return rayNow.GetPoint(enterNow);

        return Vector3.zero;
    }

    private void OnDrawGizmos()
    {
        Gizmos.DrawLine(transform.position, transform.position + transform.up);
    }
}

对不起菜鸟问题,我最近开始了我的unity3D之旅。我如何在这里设置限制?

标签: unity3d

解决方案


如果您的意思是您想在一次捏合操作中限制缩放,您可能会这样做,例如

// Configure these in the Inspector
[SerializeField] private float minZoom = 0.1f;
[SerializeField] private float maxZoom = 10f;

...
    var zoom = Vector3.Distance(pos1, pos2) / Vector3.Distance(pos1b, pos2b);
    zoom = Mathf.Clamp(minZoom, maxZoom);
...

如果您想限制整体组合缩放,则必须存储和组合缩放量,例如

private float finalZoom = 1;

...
    var zoom = Vector3.Distance(pos1, pos2) / Vector3.Distance(pos1b, pos2b);
    finalZoom *= zoom;
    finalZoom = Mathf.Clamp(minZoom, maxZoom);

    // And from here use finalZoom instead of zoom    
    Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, 1 / finalZoom);
...

推荐阅读