博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Unity做个游戏(二) - 事件系统
阅读量:6870 次
发布时间:2019-06-26

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

本文首发自

前言

之前一直在用cocos2d-x用c++写代码嘛,所以为了开发方便自己设计了一套事件系统,现在转到unity用c#了,就很自然地把之前那套东西搬过来用了XD

C#自带的event其实就完全可以用,不过功能略显简陋,Unity自带的EventSystem感觉太复杂了,而且我又不太喜欢去操作editor,所以我还是决定自己造轮子,弄一个最适合自己的事件机制

设计

事件机制基于观察者模式,事件订阅者向某个事件发布者订阅事件,绑定回调函数,事件发布者发布事件时会通知所有订阅者,按订阅顺序依次调用他们预留的回调函数

三个类,SFEvent(SF是前缀,啥意思大家也不用在意233),SFEventDataSFEventDispatcher

作用
SFEvent 事件类
SFEventData 事件所包含的数据
SFEventDispatcher 事件发布者

SFEvent

其中,事件类SFEvent包含类型,事件数据SFEventData,以及发布者

不同事件的数据可能需要不同的数据结构,所以我们抽象出一层接口ISFEventData,实际使用的数据结构均继承这个接口即可
下面贴出部分代码(不完整,完整代码见本文末尾)

public class SFEvent{    public string eventType; // 事件类型    public ISFEventData data; // 事件包含的自定义数据    public object target; // 事件发送者    // 以下是事件枚举    public const string EVENT_TEST = "EVENT_TEST";};public interface ISFEventData{};复制代码

SFEventData

所有事件数据的数据结构均继承了ISFEventData这个空接口,这样一来不同的事件就可以定制自己需要的事件数据结构了,如果时间数据非常简单比如只有一个数字,我这里也准备了一个通用的数据结构:

public class SFSimpleEventData : ISFEventData{    public object objVal = null;    public int intVal = 0;    public float floatVal = 0;    public string strVal = "";}复制代码

SFEventDispatcher

这个事件系统的核心部分,负责分发事件,管理订阅

之前用cocos的时候习惯使用多继承的方式来把dispatcher的功能加到一个类上,不过现在C#不支持多继承了,于是就只能使用组合的方式,在类中储存一个dispatcher类的实例来实现类似的效果。写法会从this->dispatchEvent(e);变成this.dispatcher.dispatchEvent(e);
使用C#的委托来实现订阅,订阅者传递这个委托类型的回调函数给发布者即可:

public delegate void SFListenerSelector(SFEvent e);复制代码

使用一个字典来管理不同的事件所各自对应的订阅者

Dictionary
> m_dictListener;复制代码

订阅者通过addEventListener方法来订阅一个事件:

public bool addEventListener(string eventType, SFListenerSelector sel){    if (eventType != "" && sel != null) // 判断有效性    {        if (hasEventListener(eventType, sel))        {            // SFUtils这个类是我自己弄的,下一篇文章再讲            SFUtils.log(string.Format("重复监听!type={0}", eventType));        }        if (!m_dictListeners.ContainsKey(eventType))        {            // 不存在的话就新建一个            List
newSelectors = new List
(); m_dictListeners[eventType] = newSelectors; } var selectors = m_dictListeners[eventType]; selectors.Add(sel); return true; } return false;}复制代码

任何人都可以通过发布者(通常来说是发布者自己)来发布事件:

public int dispatchEvent(SFEvent e){    int count = 0;    if (m_dictListeners.ContainsKey(e.eventType))    {        var selectors = m_dictListeners[e.eventType];        foreach (var item in selectors)        {            item(e);            count += 1;        }    }    return count;}复制代码

用途相关

其实更常见的使用场景是在UI,我这次用的是Unity5自带的UGUI,写了一个控件来结合Unity的事件系统和我这个事件系统,实际开发的时候使用UI事件的方式和使用普通事件的方式是完全一致的,这个我们后面再详细介绍

完整代码

上面贴出的代码片段由于篇幅限制只保留了关键部分,完整的代码可在上找到

转载于:https://juejin.im/post/58d13af761ff4b00603e5ee8

你可能感兴趣的文章
.NET的URL怎么静态化
查看>>
day06:shell脚本介绍 | shell脚本结构 | 执行data命令用法 | shell脚本中变量
查看>>
Centos7:timedatectl命令
查看>>
LeetCode:Fizz Buzz - Fizz Buzz 游戏
查看>>
如何在Shell中判断一个变量是否为整数
查看>>
juqery验证中文
查看>>
Linux OS Service 'ntpd' (文档 ID 551704.1)
查看>>
Jquery Validate 使用手册
查看>>
课堂录制的FTP配置
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
常见算法的记录
查看>>
ssh 问题
查看>>
Android源代码下载编译
查看>>
nhmicro添加信审功能
查看>>
eclipse安装maven插件-解决requires ‘bundle org.slf4j.api
查看>>
在Centos 5.x或6.x上安装RHEL EPEL Repo
查看>>
TextField 使用与方法总结
查看>>
湿润的武汉,湿润的心;干燥的北京,干涸的心。
查看>>
Help Desk Meet Power Shell
查看>>