Unity3D – uGUI 拖曳視窗的語法

Unity3D_draggable_window_uGUI_feature_pic

前言:

最近unity3D專案剛好要做到的這樣的功能 – uGUI 視窗拖曳,老話一句條條大路通羅馬,這種很常見的功能一定是網路上範例比比皆是,順便探索一下,目前最方便最快的語法來達成拖曳視窗。

網路範例:

這邊我找到幾個都可以用的視窗拖曳語法

A. GitHub by nooralibutt

https://gist.github.com/nooralibutt/a7b84df4dee70c84bc26

這語法從程式來看思緒路如下

在Drag開始的時候把螢幕位置報上去,接著拖曳的時候做出螢幕點與拖曳點的計算,並將點資料轉換成攝影機螢幕的對應點資料,直到放開。

// Canvase should be Screen Space - Camera
// Attach a Event Trigger Script to image you want to Drag Drop
// Add Begin Drag and Drap Event Listener
// Attach this script to that image

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;

public class DragDropItem : MonoBehaviour
{
  // To keep track of drag position
	private Vector2 prevDragPos;

	public void OnDragBegin(BaseEventData data) {
    // 0- Save Begin drag position to use it OnDrag
		prevDragPos = getScreenPosition ();
	}
	
	public void OnDrag (BaseEventData data)
	{
		// 1- Get current position on screen
		Vector3 point = getScreenPosition ();
		
		// 2- Calc difference of movement with prev Drag pos
		float x = point.x - prevDragPos.x;
		float y = point.y - prevDragPos.y;
		
		// 3- Assign difference to current object's Transform
		Vector3 resPos = transform.position;
		resPos.x += x;
		resPos.y += y;
		transform.position = resPos;
		
		// 4- Now current Drag position become prev one
		prevDragPos = point;
	}
	
	private static Vector3 getScreenPosition ()
	{
		// Get current position on screen
		Vector3 curPos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
		curPos.z = 0;
		return curPos;
	}
}

B. Code Monkey => 推薦使用的方案

他的網站上號稱有專案可下載,但因為註冊信一直無法收到的原因,

因此這邊我照著Code monkey的影片Script重新繕打一次及局部改寫

(I wanna give a credit to Code Monkey , thanks him.)

程式碼如下: 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;


public class DragWindow : MonoBehaviour , IDragHandler , IPointerDownHandler
{
    [SerializeField] private RectTransform dragRectTransform;
    [SerializeField] private Canvas canvas;


    private void Awake()
    {
        //初始化
        //若RectTransform與Canvas未指定目標為空值,則自動抓取上層母物件
        if (dragRectTransform == null)
        {
            dragRectTransform = transform.parent.GetComponent<RectTransform>();
        }

        if (canvas == null)
        {
            Transform tempCanvasTransform = transform.parent;
            while (tempCanvasTransform != null)
            {
                canvas = tempCanvasTransform.GetComponent<Canvas>();
                if (canvas != null)
                {
                    break;
                }
                tempCanvasTransform = tempCanvasTransform.parent;
            }
        }

        
    }


    public void OnDrag(PointerEventData eventData)
    {
        dragRectTransform.anchoredPosition += eventData.delta / canvas.scaleFactor;
    }

 

    void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
    {
        dragRectTransform.SetAsLastSibling();
    }


}

把上面的Code另開一個C-Sharp Script檔名叫做DragWindow.cs,在複製貼上儲存即可開始使用。

實際使用:

直接把Script拖曳到視窗的Title Bar即可

使用方法很簡單,把本Script直接拖入視窗的Title Bar即可,而Title Bar其實只是一張Image。

快來看看效果吧:

實際展示

結論:

依照以上的試用,可以知道此試作的語法是最精簡並且結合了Uuity Event System的控制方法。有需要的人可以直接把程式碼,貼上視窗標題(Title)物件。然後直接就能自動被滑鼠事件控制,達到 拖曳、置頂的細節控制。嚴然是最好的選擇,當然除了感謝本文的整理以外,還要感謝 Code Monkey的視頻分享。有機會可以去他的頻道按下讚。

參考:

在〈Unity3D – uGUI 拖曳視窗的語法〉中有 1 則留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *