起因:想使用UGUI給項目設(shè)計一個萬能拖拽系統(tǒng)(2d-3d劝评,3d-3d, 3d-2d)姐直,做了快兩天了,完成度99%蒋畜,但就是有點小BUG無法解決声畏,天氣又冷,煩惱姻成。
靜下心來插龄,覺得還是對unity 的事件系統(tǒng)不熟悉,今晚坐下來讀了讀官網(wǎng)文檔(終于)科展,收獲不小均牢,寫在這里,也算是一個記錄:
Unity EventSystem
- Message System
- Input Modules
- Supported Events
- Raycasters
1. Message System(改進(jìn)的消息系統(tǒng))
基本上可以看成是以前SendMessage的升級版才睹。
使用方法(照抄官網(wǎng)):
step1. 聲明一個接口徘跪,繼承自IEventSystemHandler
public interface ICustomMessageTarget : IEventSystemHandler
{
// functions that can be called via the messaging system
void Message1();
void Message2();
}
step2. 實現(xiàn)這個接口 , 把這個腳本掛在某個物體上,這里假設(shè)為物體AAA
public class CustomMessageTarget : MonoBehaviour, ICustomMessageTarget
{
public void Message1()
{
Debug.Log ("Message 1 received");
}
public void Message2()
{
Debug.Log ("Message 2 received");
}
}
step3. 在任何腳本中使用ExecuteEvents
靜態(tài)類發(fā)送Message砂竖,來執(zhí)行接口中定義的方法
//target should be AAA
ExecuteEvents.Execute<ICustomMessageTarget>(target, null, (x,y)=>x.Message1());
注意 : step3里的Excute泛型方法真椿,有3個參數(shù),第一個參數(shù)是發(fā)送message的gameobject對象乎澄,只有當(dāng)對象上有IEventSystemHandler
實現(xiàn)類的時候才可以突硝,這個例子中自然就是AAA物體。
還要注意 : ExecuteEvents靜態(tài)類還有其他方法:
## Static Functions
EventSystems.ExecuteEvents.CanHandleEvent Can the given GameObject handle the IEventSystemHandler of type T.
EventSystems.ExecuteEvents.Execute Execute the event of type T : IEventSystemHandler on GameObject.
EventSystems.ExecuteEvents.ExecuteHierarchy Recurse up the hierarchy calling Execute<T> until there is a GameObject that can handle the event.
EventSystems.ExecuteEvents.GetEventHandler Traverse the object hierarchy starting at root, and return the GameObject which implements the event handler of type <T>
EventSystems.ExecuteEvents.ValidateEventData Attempt to convert the data to type T. If conversion fails an ArgumentException is thrown.
名字解釋都比較直白置济,就不翻譯了解恰。比如那個EventSystems.ExecuteEvents.ExecuteHierarchy
, 是遞歸尋找適合的gameobject浙于,并執(zhí)行方法护盈。
說實話,比以前的SendMessage科學(xué)了不少羞酗,以前只能在Hierarchy里上下求索腐宋,現(xiàn)在是有目的的尋找了。
但....我看來也就僅此而已了檀轨,SendMessage我在實際工程中從來都沒用過胸竞,這個估計也不會用。為什么参萄?有了System.Action誰還用這個...
2. Input Modules
此部分略卫枝,大致就是unity支持所有的輸入方式,包括鍵盤啦讹挎,手柄啦校赤,觸摸啦等等吆玖,balabala...
3. Supported Events(支持的輸入事件)
這部分就比較重要了,unity事件系統(tǒng)支持以下17種輸入事件
事件接口 | 含義 |
---|---|
IPointerEnterHandler | pointer進(jìn)入 |
IPointerExitHandler | pointer離開 |
IPointerDownHandler | pointer按下 |
IPointerUpHandler | pointer抬起 |
IPointerClickHandler | pointer按下和抬起 |
IInitializePotentialDragHandler | 可拖拽物體被發(fā)現(xiàn)马篮,可用來初始化一些變量 |
IBeginDragHandler | 開始拖拽 |
IDragHandler | 拖拽中 |
IEndDragHandler | 拖拽結(jié)束時 (when) |
IDropHandler | 拖拽結(jié)束位置(where) |
IScrollHandler | 鼠標(biāo)滾輪 |
IUpdateSelectedHandler | 選中物體時沾乘,持續(xù)發(fā)送 |
ISelectHandler | 物體變?yōu)楸贿x擇 |
IDeselectHandler | 物體變?yōu)槿∠x擇 |
IMoveHandler | 物體移動(左右上下等) |
ISubmitHandler | submit(提交)按鈕按下 |
ICancelHandler | cancel(取消)按鈕按下 |
注意: 這里的“pointer”可以是鼠標(biāo)、touch等一切unity支持的類型
那也就意味著积蔚,我們終于可以在PC和移動端共用一套代碼了
4. Raycasters(射線們)
這也是另外一個重要的點:決定了unity對何種輸入方式進(jìn)行響應(yīng):
射線類型 | 含義 |
---|---|
Graphic Raycaster | UI使用 |
Physics 2D Raycaster | 2D 物體組件使用意鲸,如 BoxCollider2D等 |
Physics Raycaster | 3D物體使用(UI其實也能使用) |
5. Practice - 練習(xí)和測試
我們來建個簡單的場景:
- 場景中增加一個空物體,命名為
EventSystem
尽爆,添加EventSystem
組件怎顾,點擊組件上的Add Default Input Modules
按鈕 - 場景中的攝像機上,添加
Physics Raycaster
組件 - 場景中建立一個3d的 Cude漱贱, 和一個2d的image
- 將以下腳本拖給Cude和Image:
using UnityEngine;
using UnityEngine.EventSystems;
public class SupportedEventsTest : MonoBehaviour,
IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler,
IPointerClickHandler, IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler,
IEndDragHandler, IDropHandler, IScrollHandler, IUpdateSelectedHandler,
ISelectHandler, IDeselectHandler, IMoveHandler, ISubmitHandler, ICancelHandler
{
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("OnBeginDrag");
}
public void OnCancel(BaseEventData eventData)
{
Debug.Log("OnCancel");
}
public void OnDeselect(BaseEventData eventData)
{
Debug.Log("OnDeselect");
}
public void OnDrag(PointerEventData eventData)
{
Debug.Log("OnDrag");
}
public void OnDrop(PointerEventData eventData)
{
Debug.Log("OnDrop");
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("OnEndDrag");
}
public void OnInitializePotentialDrag(PointerEventData eventData)
{
Debug.Log("OnInitializePotentialDrag");
}
public void OnMove(AxisEventData eventData)
{
Debug.Log("OnMove");
}
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("OnPointerClick");
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("OnPointerDown");
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("OnPointerEnter");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("OnPointerExit");
}
public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("OnPointerUp");
}
public void OnScroll(PointerEventData eventData)
{
Debug.Log("OnScroll");
}
public void OnSelect(BaseEventData eventData)
{
Debug.Log("OnSelect");
}
public void OnSubmit(BaseEventData eventData)
{
Debug.Log("OnSubmit");
}
public void OnUpdateSelected(BaseEventData eventData)
{
Debug.Log("OnUpdateSelected");
}
}
運行游戲槐雾,我們可以看到,3d和2d物體都可以相應(yīng)事件系統(tǒng)幅狮,這是由于我們給攝像機添加了Physics Raycaster
組件募强。如果你換成Graphic Raycaster
,那Cube是不會響應(yīng)的崇摄。
好擎值,今天就寫到這,寫的還算整齊逐抑,睡覺了鸠儿。
╮(╯3╰)╭睡眠不足,不熬夜不追劇( ̄▽ ̄)*