博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UGUI事件的系统
阅读量:2503 次
发布时间:2019-05-11

本文共 4000 字,大约阅读时间需要 13 分钟。

EventSystem对象说明

  当我们在场景中创建任意UI对象后,Hierarchy面板中都可以看到系统自动创建了EventSystem,可以看到该对象有三个组件:EventSystem、StandaloneInputModule、TouchInputModule,后面两个组件都继承自BaseInputModule。

  EventSystem组件主要负责处理输入、射线投射以及发送事件。一个场景只能有一个EventSystem,并且需要BaseInputModule类型组件的协助才能工作。EventSystem在一开始的时候会把自己所属对象下的BaseInputModule类型组件加到一个内部列表,并且在每个Update周期通过接口UpdateModules接口调用这些基本输入模块的UpdateModule接口,然后BaseInputModule会在UpdateModule接口中将自己的状态修改成’Updated’,之后BaseInputModule的Process接口才会被调用。
  BaseInputModule是一个基类模块,负责发送输入事件(点击、拖拽、选中等)到具体对象。EventSystem下的所有输入模块都必须继承自BaseInputModule组件。StandaloneInputModule和TouchInputModule组件是系统提供的标准输入模块和触摸输入模块,我们可以通过继承BaseInputModule实现自己的输入模块。
  除了以上两个组件,还有一个很重要的组件通过EventSystem对象我们看不到,它是BaseRaycaster组件。BaseRaycaster也是一个基类,前面说的输入模块要检测到鼠标事件必须有射线投射组件才能确定目标对象。系统实现的射线投射类组件有PhysicsRaycaster, Physics2DRaycaster, GraphicRaycaster。这个模块也是可以自己继承BaseRaycaster实现个性化定制。

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

UGUI中的事件系统

  根据第一节中的说明,EventSystem和BaseInputModule是粘在一个对象上的,这两个模块在EventSystem对象上可以直接看到。那么,BaseRaycaster模块呢。

  其实射线检测,肯定是从摄像机发起的,那么BaseRaycaster模块也一定和摄像机关系一定不简单。
  对于UI模块,在Canvas对象下我们可以看到GraphicRaycaster组件。如果Canvas的渲染模式是SceenSpace-Overlay,那么我们是看不到Camera组件的。所以应该是GraphicRaycaster会对UI不同的渲染模式做特殊处理。因为有GraphicRaycaster组件的原因,Canvas上的所有UI对象,都可以接受输入模块发出的事件,具体事件的处理请看下面UGUI添加事件的方式。

场景对象中使用事件系统

  场景中的非UI对象,如果想要接收输入模块的事件,一样的道理,也需要给摄像机挂上一个射线检测组件。PhysicsRaycaster, Physics2Draycaster这两个组件分别是用于3D和2D的场景。当然,还需要场景的对象挂了collider射线才检测的到。

  其实官方对射线检测也是做了说明的,如果不详读手册是不会发现的,这里是传送门:
  如果场景中只有一个射线检测源:When a Raycaster is present and enabled in the scene it will be used by the EventSystem whenever a query is issued from an InputModule.
  如果场景中有多个射线检测源:If multiple Raycasters are used then they will all have casting happen against them and the results will be sorted based on distance to the elements.

UGUI添加事件的方式

  • ugui将UI触发的事件分为12个类型,即EventTriggerType枚举的12个值。

实现事件主要有3种方式:

我们以PointerClick为例, 用于某点点击事件, 其他事件类型可以根据相同的办法调用。之所以使用PointerClick为例,是因为相比其他事件类型,它还有一个特殊的实现方式。

  • 方式1:继承基础接口

1.创建ObjectClick脚本,继承MonoBehaviour和IpointerClickHandler接口:

using System;using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;public class ObjectClick : MonoBehaviour, IPointerClickHandler {   public  void OnPointerClick(PointerEventData eventData)    {        Debug.Log("$click test");        //throw new NotImplementedException();    }}

2.创建一个名为testObject的空对象,并将ObjectClick附加到testObject上。

3.启动并点击testObject。

  • 方式2:编辑器设置实现

1.创建一个UI控件如Panel、Image等,命名为UIPanel。

2.创建c#脚本TestClick,并附加到UIPanel上。

using System.Collections;using System.Collections.Generic;using UnityEngine;public class TestClick : MonoBehaviour{    public void onTestClick()    {        Debug.Log("$$onTestClick");    }}

3.控件添加EventTrigger组件,” Add New” -> 选择” PointerClick”。将UIPanel对象拖拽到触发者位置。然后点击”No Function”选择我们写在Test脚本中的OnTestClick事件。

这里写图片描述
4.启动并点击UIPanel。

  • 方式3:程序动态设置实现

在日常的开发中,可能需要动态的变更绑定的事件。那么我们如何使用代码控制绑定触发事件呢?

1.代码控制。ScriptControl.cs脚本如下:

public class ScriptControl : MonoBehaviour {    // Use this for initialization    void Start () {        EventTrigger trigger = this.gameObject.GetComponent
(); if(trigger == null) { trigger = this.gameObject.AddComponent
(); } //实例化triggers trigger.triggers = new List
(); //定义需要绑定的事件类型。并设置回调函数 EventTrigger.Entry entry = new EventTrigger.Entry(); //设置事件类型 entry.eventID = EventTriggerType.PointerClick; //设置回调函数 entry.callback = new EventTrigger.TriggerEvent(); UnityAction
callback = new UnityAction
(onScriptControl); entry.callback.AddListener(callback); trigger.triggers.Add(entry); } public void onScriptControl(BaseEventData eventData) { Debug.Log("$onScriptControl test"); }}

2.创建一个GameObject对象,将脚本绑定到该对象。

3.运行并点击该对象。

  • 点击事件的特殊实现方式:使用Button控件实现

针对Click事件还存在一种特殊方式:ugui系统中官方提供了一种Button控件。Button封装了官方提供的一套OnClick事件。操作完全类似于方式二。便不详述了。

你可能感兴趣的文章
编程十年 (8):歪打正着C#
查看>>
.Net程序员 初学Ubuntu ,配置Nignix
查看>>
一个段错误调试
查看>>
Codeforces-936B Sleepy Game
查看>>
kubernetes系列
查看>>
exports和module.exports的区别
查看>>
Memcached add 命令
查看>>
ansible简要说明
查看>>
Unity of Prism
查看>>
原型模式和享元模式
查看>>
Day 16:输入输出字符流、缓冲输入字符流
查看>>
hiho一下 第200周 题目1 : Shortening Sequence
查看>>
分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系
查看>>
高老师的架构设计_隽语集(DD_1951)
查看>>
等价类的划分之三个输入框
查看>>
MySQL、Oracle数据库之操作系统版本选择
查看>>
模板 可持久化字典树
查看>>
HDU 5643 King's Game 打表
查看>>
Gym 100646 Problem C: LCR 模拟题
查看>>
web页面内容优化管理与性能技巧
查看>>