Unity EventSystem
- Message System
- Input Modules
- Supported Events
- Raycasters
1. Message System(改进的消息系统)
基本上可以看成是以前SendMessage的升级版。
使用方法(照抄官网):
step1. 声明一个接口,继承自IEventSystemHandler
public interface ICustomMessageTarget : IEventSystemHandler { // functions that can be called via the messaging system void Message1(); void Message2(); }
step2. 实现这个接口 , 把这个脚本挂在某个物体上,这里假设为物体AAA
public class CustomMessageTarget : MonoBehaviour, ICustomMessageTarget { public void Message1() { Debug.Log ("Message 1 received"); } public void Message2() { Debug.Log ("Message 2 received"); } }
step3. 在任何脚本中使用ExecuteEvents
静态类发送Message,来执行接口中定义的方法
//target should be AAA ExecuteEvents.Execute<ICustomMessageTarget>(target, null, (x,y)=>x.Message1());
注意 : step3里的Excute泛型方法,有3个参数,第一个参数是发送message的gameobject对象,只有当对象上有IEventSystemHandler
实现类的时候才可以,这个例子中自然就是AAA物体。
还要注意 : ExecuteEvents静态类还有其他方法:
## 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,并执行方法。
说实话,比以前的SendMessage科学了不少,以前只能在Hierarchy里上下求索,现在是有目的的寻找了。
但....我看来也就仅此而已了,SendMessage我在实际工程中从来都没用过,这个估计也不会用。为什么?有了System.Action谁还用这个...
2. Input Modules
此部分略,大致就是unity支持所有的输入方式,包括键盘啦,手柄啦,触摸啦等等,balabala...
3. Supported Events(支持的输入事件)
这部分就比较重要了,unity事件系统支持以下17种输入事件
事件接口 | 含义 |
---|---|
IPointerEnterHandler | pointer进入 |
IPointerExitHandler | pointer离开 |
IPointerDownHandler | pointer按下 |
IPointerUpHandler | pointer抬起 |
IPointerClickHandler | pointer按下和抬起 |
IInitializePotentialDragHandler | 可拖拽物体被发现,可用来初始化一些变量 |
IBeginDragHandler | 开始拖拽 |
IDragHandler | 拖拽中 |
IEndDragHandler | 拖拽结束时 (when) |
IDropHandler | 拖拽结束位置(where) |
IScrollHandler | 鼠标滚轮 |
IUpdateSelectedHandler | 选中物体时,持续发送 |
ISelectHandler | 物体变为被选择 |
IDeselectHandler | 物体变为取消选择 |
IMoveHandler | 物体移动(左右上下等) |
ISubmitHandler | submit(提交)按钮按下 |
ICancelHandler | cancel(取消)按钮按下 |
注意: 这里的“pointer”可以是鼠标、touch等一切unity支持的类型
那也就意味着,我们终于可以在PC和移动端共用一套代码了
4. Raycasters(射线们)
这也是另外一个重要的点:决定了unity对何种输入方式进行响应:
射线类型 | 含义 |
---|---|
Graphic Raycaster | UI使用 |
Physics 2D Raycaster | 2D 物体组件使用,如 BoxCollider2D等 |
Physics Raycaster | 3D物体使用(UI其实也能使用) |
5. Practice - 练习和测试
我们来建个简单的场景:
- 场景中增加一个空物体,命名为
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物体都可以相应事件系统,这是由于我们给摄像机添加了Physics Raycaster
组件。如果你换成Graphic Raycaster
,那Cube是不会响应的。