前言:
最近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即可,而Title Bar其實只是一張Image。
快來看看效果吧:
結論:
依照以上的試用,可以知道此試作的語法是最精簡並且結合了Uuity Event System的控制方法。有需要的人可以直接把程式碼,貼上視窗標題(Title)物件。然後直接就能自動被滑鼠事件控制,達到 拖曳、置頂的細節控制。嚴然是最好的選擇,當然除了感謝本文的整理以外,還要感謝 Code Monkey的視頻分享。有機會可以去他的頻道按下讚。
參考:
Helpful & Awesome !