Unity實現放大縮小以及相機位置平移實現拖拽效果


放大縮小功能是游戲開發中用到的功能,今天就來講一下Unity中放大縮小怎么實現。

1.IDragHandler, IBeginDragHandler, IEndDragHandler這三個接口是Unity常用的接口,分別對應於拖拽,開始拖拽,可結束拖拽(需要注意的是,這三個接口只能運用在UGUI(無需添加Collider),Sprite不能使用(Sprite可以使用OnMouseDown,OnMouseDrag,OnMouseUp)),並且拖拽物體需要是Cavas下面的子元素。

先看一下簡單的拖拽開始和拖拽結束,拖拽開始只有簡單的判斷是不是單點點擊,記錄點擊的位置,標記拖拽狀態為true。結束拖拽里面標記拖拽狀態為flase。

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (Input.touchCount <= 1)
        {
            isDrag = true;
            lastPoint = Input.mousePosition;
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        isDrag = false;
    }

 

重點看一下拖拽中這個方法:這個方法是在你按下的過程中一直在執行,基本上每一行都有注釋,應該都很好懂的

    public void OnDrag(PointerEventData eventData)
    {

        if (isDrag && Input.touchCount <= 1)
        {
            //記錄當前鼠標位置
            currentPoint = Input.mousePosition;
            //記錄移動的距離 -號是因為我們要移動的是因為相機來顯示物體的移動
            //如果自己移動物體可以不加上-,原理是一樣的,直接移動物體會造成重構,特別的有大量物體(比如地圖的時候就會出現這種情況),性能上會消耗巨大
            moveDir = -(currentPoint - lastPoint);
            //規整z軸方向
            moveDir = new Vector3(moveDir.x, moveDir.y, 0);
            
            //如果移動的距離為0那么說明沒有進行拖拽,直接返回
            if (moveDir == Vector3.zero)
            {
                return;
            }

            //這一段可以參考 https://www.jianshu.com/p/148725feecfa
            //主要用於做到屏幕移動距離和相機移動距離保持一致,不隨着縮放而改變
            float aspect = eyeCamera.aspect;
            float halfFOVTan = Mathf.Tan((eyeCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad);
            float hight = Mathf.Abs(eyeCamera.transform.position.z) * halfFOVTan * 2;// 參照圖片(計算透視相機視口寬高示意圖)
            float width = hight * aspect;
            //計算實際上相機需要移動的距離
            moveDir.x = moveDir.x / Screen.width * width;
            moveDir.y = moveDir.y / Screen.height * hight;
            
            //相機移動距離:moveDir后面乘上的是一個下面我們要說的一個縮放系數,如果不加上的話會導致縮小之后移動比較慢一點,放大之后移動比較快速
            eyeCamera.transform.Translate(moveDir * scale/6.6f);

            if (lastPoint != currentPoint)
            {
                lastPoint = currentPoint;
            }
        }
    }

2.放大縮小

 
    //這里是因為我用的正交相機,而正交相機的默認size等於6.6    
   private float scale = 6.6f;
public void ScaleView()
{
//多點觸摸, 放大縮小(記錄兩個新的觸摸點)
Touch newTouch1 = Input.GetTouch(0);
Touch newTouch2 = Input.GetTouch(1);
     //判斷是不是取消了,或者是新的點點擊了或者抬起了直接退出ScaleView方法
for (int i = 0; i < Input.touchCount; ++i)
{
if (Input.GetTouch(i).phase == TouchPhase.Began || Input.GetTouch(i).phase == TouchPhase.Canceled ||
Input.GetTouch(i).phase == TouchPhase.Ended)
{
//取消之后當前點變成了上一個記錄點
lastTouch2 = newTouch2;
lastTouch1 = newTouch1;
return;
}
}

//計算老的兩點距離和新的兩點間距離,變大要放大模型,變小要縮放模型
float lastDistance = Vector2.Distance(lastTouch1.position, lastTouch2.position);
float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);

//兩個距離之差,為正表示放大手勢, 為負表示縮小手勢
float offset = lastDistance - newDistance;
//放大因子, 一個像素按 0.01倍來算(100可調整)
float scaleFactor = offset / zoomFactor;
//當前的相機size
float localScale = eyeCamera.orthographicSize;
//計算整體的放大倍數
scale = localScale + scaleFactor;
if (scale < minScale)
{
scale = minScale;
}
else if (scale > maxScale)
{
scale = maxScale;
}
//調整相機的尺寸
Scale2D.SetCameraOrthographicSize(scale, eyeCamera);
//記住最新的觸摸點,下次使用
lastTouch1 = newTouch1;
lastTouch2 = newTouch2;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM