最近幾天在跟着一個視頻教程學習,其中用到了拖拽功能,我想到了官方的DEMO中有相應的例子,就去看了一下,很簡單,把官方的代碼拿過來,稍微做些修改就實現了拖動功能。
一、實現拖拽功能
先上代碼:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections;
public class DragableCard : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
// begin dragging
public void OnBeginDrag(PointerEventData eventData)
{
SetDraggedPosition(eventData);
}
// during dragging
public void OnDrag(PointerEventData eventData)
{
SetDraggedPosition(eventData);
}
// end dragging
public void OnEndDrag(PointerEventData eventData)
{
SetDraggedPosition(eventData);
}
/// <summary>
/// set position of the dragged game object
/// </summary>
/// <param name="eventData"></param>
private void SetDraggedPosition(PointerEventData eventData)
{
var rt = gameObject.GetComponent<RectTransform>();
// transform the screen point to world point int rectangle
Vector3 globalMousePos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out globalMousePos))
{
rt.position = globalMousePos;
}
}
}
只要繼承了IBeginDragHandler、IDragHandler、和IEndDragHandler這三個接口,並實現了OnBeginDrag、OnDrag和OnEndDrag這三個方法,我們就可以實現拖拽功能。其中,OnBeginDrag處理開始拖動時要做什么事,OnDrag處理拖動過程中要做什么事,OnEndDrag處理拖動結束時要做什么事,是不是很easy啊!
二、實現跟背包類似的功能
UGUI官方的例子實際是背包界面的雛形,剛好我要實現一個類似的功能,就是拖動卡片到指定區域。我同樣把官方的代碼稍做修改,運行,可是沒有起作用,經過研究和實踐,我發現必須保證指定區域對應的物體的渲染優先級比被拖動物體的高,即在Hierachy視圖中,指定區域對應的物體一定要在被拖動物體的下面,如圖

這樣才能保證腳本中的OnDrop方法才會被調用。接下來上代碼:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class DropMe : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
public GameObject m_myCardsObj;
private bool m_isIn = false;
public void OnEnable()
{
Debug.Log("............");
}
// when you release the left button of mouse
public void OnDrop(PointerEventData data)
{
Debug.Log(string.Format(">>>>> {0}", m_isIn));
if (!m_isIn)
{
m_myCardsObj.GetComponent<MyCards>().UpdateShow();
}
}
// when the mouse moving in the game object
public void OnPointerEnter(PointerEventData data)
{
m_isIn = true;
Debug.Log(m_isIn);
}
// when the mouse moving out the game object
public void OnPointerExit(PointerEventData data)
{
m_isIn = false;
Debug.Log(m_isIn);
}
private Sprite GetDropSprite(PointerEventData data)
{
var originalObj = data.pointerDrag;
if (originalObj == null)
return null;
var srcImage = originalObj.GetComponent<Image>();
if (srcImage == null)
return null;
return srcImage.sprite;
}
}
繼承了IDropHandler, IPointerEnterHandler, IPointerExitHandler這三個接口,同樣也實現對應的三個方法OnDrop、OnPointerEnter和OnPointerExit。其中,OnDrop處理松開鼠標左鍵時要做什么事,OnPointerEnter處理鼠標指針進入掛載該腳本的物體區域時要做什么事,OnPointerExit處理處理鼠標指針移出掛載該腳本的物體區域時要做什么事,也很easy!
在這里,我的描述太簡單了,要結合實際的例子,親自體會一下才會明白!官方的例子可以在Assets Stroe中找到,是免費的。
