最近開始學習UGUI,但發現相比NGUI,UGUI的資料比較少,很多東西只能慢慢摸索,我參考了一下Unity官方出的Unity Samples UI例子,嘗試完成UI拖拽功能。
1.首先模擬一個簡單的物品拖拽的菜單:


2.然后在准備拖拽的Image1和Image2上添加同一個腳本:
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 using UnityEngine.EventSystems; 5 6 public class TestForDrag : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler, IDropHandler 7 { 8 //創建一個Gameobject作為拖拽時被拖拽對象的代替品 9 private GameObject drag_icon; 10 11 public void OnDrag(PointerEventData eventData) 12 { 13 //並將拖拽時的坐標給予被拖拽對象的代替品 14 Vector3 pos; 15 if (RectTransformUtility.ScreenPointToWorldPointInRectangle(drag_icon.GetComponent<RectTransform>(), 16 eventData.position, Camera.main, out pos)) 17 { 18 drag_icon.transform.position = pos; 19 } 20 21 } 22 23 public void OnBeginDrag(PointerEventData eventData) 24 { 25 //代替品實例化 26 drag_icon = new GameObject("icon"); 27 drag_icon.transform.SetParent(GameObject.Find("Canvas").transform, false); 28 drag_icon.AddComponent<RectTransform>(); 29 var img = drag_icon.AddComponent<Image>(); 30 img.sprite = this.GetComponent<Image>().sprite; 31 32 //防止拖拽結束時,代替品擋住了准備覆蓋的對象而使得 OnDrop() 無效 33 CanvasGroup group = drag_icon.AddComponent<CanvasGroup>(); 34 group.blocksRaycasts = false; 35 } 36 public void OnEndDrag(PointerEventData eventData) 37 { 38 //拖拽結束,銷毀代替品 39 if (drag_icon) 40 { 41 Destroy(drag_icon); 42 } 43 } 44 45 public void OnDrop(PointerEventData eventData) 46 { 47 //根據代替品的信息,改變當前對象的Sprite。 48 var obj = eventData.pointerDrag; 49 this.GetComponent<Image>().sprite = obj.GetComponent<Image>().sprite; 50 } 51 }
3.將Canvas上的Canvas組件的RenderMode改為Screen Space-Camera或者World Space,就OK了。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
注意事項:
1.
腳本需要先引入
using UnityEngine.UI;
using UnityEngine.EventSystems;
2.
引入EventSystems后,繼承IDragHandler, IBeginDragHandler, IEndDragHandler, IDropHandler
其分別代表 拖動,開始拖動,結束拖動,拖動目標 ,然后分別實現其相關的處理函數:
public void OnBeginDrag(PointerEventData eventData);
public void OnDrag(PointerEventData eventData);
public void OnEndDrag(PointerEventData eventData) ;
public void OnEndDrag(PointerEventData eventData) ;
3.
在創建代替品后,代碼添加CanvasGroup組價,並將blocksRaycasts設為false;
這樣可以防止其他物體被代替品遮擋,導致拖動目標位置的GameObject無法事件監測,OnDrop(PointerEventData eventData)函數無法執行。
