EventSystem

有三个组件:EventSystem、StandaloneInputModule、TouchInputModule,后面两个组件都继承自BaseInputModule。

EventSystem组件主要负责处理输入、射线投射以及发送事件。一个场景中只能有一个EventSystem组件,并且需要BaseInputModule类型组件的协助才能工作。EventSystem在一开始的时候会把自己所属对象下的BaseInputModule类型组件加到一个内部列表,并且在每个Update周期通过接口TickModules接口调用这些基本输入模块的UpdateModule接口,然后BaseInputModule会在UpdateModule接口中将自己的状态修改成'Updated',之后BaseInputModule的Process接口才会被调用。

BaseInputModule是一个基类模块,负责发送输入事件(点击、拖拽、选中等)到具体对象。EventSystem下的所有输入模块都必须继承自BaseInputModule组件。StandaloneInputModule和TouchInputModule组件是系统提供的标准输入模块和触摸输入模块,我们可以通过继承BaseInputModule实现自己的输入模块。

   除了以上两个组件,还有一个很重要的组件通过EventSystem对象我们看不到,它是BaseRaycaster组件。BaseRaycaster也是一个基类,前面说的输入模块要检测到鼠标事件必须有射线投射组件才能确定目标对象。系统实现的射线投射类组件有PhysicsRaycaster, Physics2DRaycaster, GraphicRaycaster。这个模块也是可以自己继承BaseRaycaster实现个性化定制。

总的来说,EventSystem负责管理,BaseInputModule负责输入,BaseRaycaster负责确定目标对象,目标对象负责接收事件并处理,然后一个完整的事件系统就有.


 

下边是场景中的3D物体怎么用EventSystem响应事件

1.首先确保场景中有一个EventSystem,添加方式最开始有提到。

 

2.因为3d物体上没有canvas上边的GraphicRaycaster所以要Main Camera上添加Physics Raycaster,就相当于UI上的GraphicRaycaster

unity eventtrigger 触发条件 unity中eventsystem_unity

3.创建一个Cube(或者其他什么随便你,但是确保物体上有collion组件,因为没有碰撞器无法检测射线),作为事件触发的3d物体

 

4.在3D物体上(你创建的那个cube或者什么)挂上EventTrigger,然后指定怎么触发,指定要触发的方法,如下。

unity eventtrigger 触发条件 unity中eventsystem_unity_02

5.在要触发事件的物体上(你创建的Cube或者其他什么),挂上如下脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class testMouse : MonoBehaviour//,IPointerDownHandler
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
         
        if(Input.GetMouseButtonDown(0))
        {
            Debug.Log("Input.GetMouseButtonDown response");
        }
    }
    void OnMouseDown()
    {
        Debug.Log("OnMouseDown response");
    }
    void OnGUI()
    {
        if(Event.current!=null && Event.current.type == EventType.MouseDown)
        {
            Debug.Log("EventType.mouseDown response");
        }
    }
    public void OnPointerClickHandler() //在cube上挂上EventTrigger并指定该方法
    {
        Debug.Log("????");
    }
    /* 
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log(eventData.button);
        Debug.Log(eventData);
        Debug.Log(Input.mousePosition);

        Debug.Log(eventData.pointerPressRaycast.gameObject.name);
        Debug.Log("press");
    }
    */
}

运行结果:

在Cube上点击,

unity eventtrigger 触发条件 unity中eventsystem_3D_03

不在Cube上点击,

unity eventtrigger 触发条件 unity中eventsystem_unity_04

解释:

OnGUI()一帧调用好多次,所以首当其冲,在最前面输出

然后是OnMouseDown(),因为这个事件是在Update()之前调用的

然后是Update()轮询Input.GetMouseButtonDown()

然后是我们的EventSystem的支持事件,EventTrigger相当于是如下被EventSystem支持的事件的封装好的可视化接口,我们自定义了该事件的响应方法OnPointerClickHandler(),这样当发生Pointer Click事件的时候,就会调用OnPointerClickHandler()方法

unity eventtrigger 触发条件 unity中eventsystem_unity_05

当然也可以不挂EventTrigger,直接实现接口,返回第3步。

 4.引用接口(你想用什么方式触发就实现对应的接口,这里以鼠标按下为例),要引用UnityEngine.EventSystems然后实现接口方法。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class testMouse : MonoBehaviour,IPointerDownHandler
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
         
        if(Input.GetMouseButtonDown(0))
        {
            Debug.Log("Input.GetMouseButtonDown response");
        }
    }
    void OnMouseDown()
    {
        Debug.Log("OnMouseDown response");
    }
    void OnGUI()
    {
        if(Event.current!=null && Event.current.type == EventType.MouseDown)
        {
            Debug.Log("EventType.mouseDown response");
        }
    }
    /* 
    public void OnPointerClickHandler() //在cube上挂上EventTrigger并指定该方法
    {
        Debug.Log("????");
    }
    */
    
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log(eventData.button);
        Debug.Log(eventData);
        Debug.Log(Input.mousePosition);

        Debug.Log(eventData.pointerPressRaycast.gameObject.name);
        Debug.Log("press");
    }
    
}

    5.同样挂上上边脚本,将脚本中红色部分的注释取消,cube移除EventTrigger组件,然后就可以了。

运行结果:

unity eventtrigger 触发条件 unity中eventsystem_unity_06

解释:

最先还是OnGUI(),这是由Unity内部函数的执行顺序决定的

然后是OnMouseDown()

然后是OnPointerDown(),也就就是我们自定义的事件响应方法,传递的参数是PointerEventData,其中可以看到是鼠标左键,给了按下的位置和增量,然后是鼠标按下的物体是Cube  (注意这里不一定非得是鼠标,如果是触摸,OnPointerDown()应该也是可以的,因为Input的类型模块被EventSystem管了)

然后是Update()的轮询

unity eventtrigger 触发条件 unity中eventsystem_unity_07