實現(xiàn)目標(biāo)
點住一個Image,這個Image能夠跟隨鼠標(biāo)/觸摸點的移動,松開停止移動。
EventSystem中有這樣的接口,IBeginDragHandler、IDragHandler和IEndDragHandler,在重寫的方法里添加上對應(yīng)的內(nèi)容即可。
public class DrogTest : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler {
RectTransform rect;
// Use this for initialization
void Start () {
rect = transform.GetComponent<RectTransform> ();
}
// Update is called once per frame
void Update () {
}
public void OnBeginDrag (PointerEventData eventData) {
}
public void OnDrag (PointerEventData eventData) {
Vector3 pos;
RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
transform.position = pos;
}
public void OnEndDrag (PointerEventData eventData) {
}
}
將腳本掛載在一個GameObject上,即可看到實現(xiàn)了要求。
要點
RectTransformUtility:一個關(guān)于RectTransform的幫助類。
ScreenPointToWorldPointInRectangle:直接翻譯是“將屏幕坐標(biāo)轉(zhuǎn)換為矩形框里的世界坐標(biāo)”。該方法的四個參數(shù)分別表示:
1.目標(biāo)Rect
2.點擊點的坐標(biāo)
3.顯示這個UI的相機
4.得到的世界坐標(biāo)
根據(jù)參數(shù),這個方法可以理解為“觸摸(從對應(yīng)camera出發(fā),是一條線)穿過目標(biāo)Rect(是一個面)后相交得到的世界坐標(biāo)點的坐標(biāo)”,最后將得到的坐標(biāo)賦予UI,即可讓UI跟隨鼠標(biāo)。
優(yōu)化
我們發(fā)現(xiàn),每次開始拖動時,UI會位移一下,是因為代碼會讓UI的中心點跟隨拖動點,如果拖動點一開始不在中心點,就會出現(xiàn)開始時的位移。那么優(yōu)化的方法就是在OnPointerDown鼠標(biāo)按下的方法中記錄UI中心點和拖動點的偏移,在給UI位置賦值時添加上這個偏移。(之所以在OnPointerDown鼠標(biāo)按下的方法中添加,而不是在OnBeginDrag開始拖動這個方法中添加,是因為在判定你開始拖動的時候,鼠標(biāo)已經(jīng)位移了一小段距離,導(dǎo)致最后的跟隨點與最開始按下的點有偏差。需要實現(xiàn)IPointerDownHandler接口)
public void OnPointerDown (PointerEventData eventData) {
Vector3 pos; //拖動點
RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
offset = rect.position - pos; //得到偏移值
}
全部代碼如下
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
public class DrogTest : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler, IPointerDownHandler {
RectTransform rect;
Vector3 offset;
// Use this for initialization
void Start () {
rect = transform.GetComponent<RectTransform> ();
}
// Update is called once per frame
void Update () {
}
//鼠標(biāo)按下時觸發(fā)
public void OnPointerDown (PointerEventData eventData) {
Vector3 pos; //拖動點
RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
offset = rect.position - pos; //得到偏移值
}
public void OnBeginDrag (PointerEventData eventData) {
}
public void OnDrag (PointerEventData eventData) {
Vector3 pos;
RectTransformUtility.ScreenPointToWorldPointInRectangle (rect, eventData.position, eventData.enterEventCamera, out pos);
transform.position = pos + offset;
}
public void OnEndDrag (PointerEventData eventData) {
}
}