最近开始学习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)函数无法执行。