笨木头  2018-03-09 17:44     Unity3D,Game Framework     阅读(17103)     评论(25)
转载请注明,原文地址: http://www.benmutou.com/archives/2571
文章来源:笨木头与游戏开发
本文 Game Framework 版本:3.0.9

本文 Unity3D 版本:2017.3

更多GF教程和实例:https://github.com/mutouzdl/gameframework_demo.git

 
转载请注明,原文地址:http://www.benmutou.com/archives/2571 文章来源:笨木头与游戏开发
 

这一篇我们来看看怎么订阅内置的一些事件,这些事件有很多很多,比如打开UI成功事件…以及……对,我们一起来看看吧。(旁白:你倒是多举几个例子啊!)

1.创建项目、初始场景、菜单场景

对于这些基础操作,大家参考之前的Demo就好了,这里不多说。

最终我们需要一个初始场景、一个菜单场景,菜单场景里随便加载一个菜单(使用框架的方式),如果大家不指定怎么做的话,请阅读《Demo3-加载UI》或者直接查看本Demo4源码。

2.订阅打开UI成功事件

还记得我们是在哪个地方打开UI的吗?(旁白:不记得)

OK,记得就好,我们的UI是在菜单流程里打开的,因为我们打开的是菜单UI。

 

为了在UI成功打开的时候做一些羞羞的事情,我们需要用到事件订阅,现在,打开Demo4_ProcedureMenu.cs脚本,修改OnEnter函数:
protected override void OnEnter(ProcedureOwner procedureOwner)
    {
        base.OnEnter(procedureOwner);
        // 加载框架Event组件
        EventComponent Event
            = UnityGameFramework.Runtime.GameEntry.GetComponent<EventComponent>();
        // 加载框架UI组件
        UIComponent UI
            = UnityGameFramework.Runtime.GameEntry.GetComponent<UIComponent>();
        // 订阅UI加载成功事件
        Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
        // 加载UI
        UI.OpenUIForm("Assets/Demo4/UI_Menu.prefab", "DefaultGroup", this);
    }
 

对于加载框架自带组件的方式,都是一样的,通过UnityGameFramework.Runtime.GameEntry.GetComponent的方式加载,以后就不多说了。

 

为了订阅事件,我们需要加载框架的EventComponent组件。

订阅事件的方式很简单:Event.Subscribe(事件唯一ID, 回调函数)。

 

OpenUIFormSuccessEventArgs是框架自带的事件类,这个事件类处理的是"打开界面成功事件",而它的EventId只是一个确保唯一的int类型,用于标识这是什么事件。

而回调函数,当然就是事件发生时我们希望调用的函数了。

 

订阅完事件之后,就是调用UI租一间的OpenUIForm函数加载UI了, 前两个参数我们在Demo3介绍过了。

最后一个参数是UserData,这是一个自定义的数据,你想传什么都行,在事件发生时,它会通过回调函数传回来。

3.事件回调函数

最后就来看看事件回调函数长什么样吧:
    private void OnOpenUIFormSuccess(object sender, GameEventArgs e)
    {
        OpenUIFormSuccessEventArgs ne = (OpenUIFormSuccessEventArgs)e;
        // 判断userData是否为自己
        if (ne.UserData != this)
        {
            return;
        }
        Log.Debug("UI_Menu:恭喜你,成功地召唤了我。");
    }
 

通过回调函数的e参数,我们可以获取UserData对象,也就是我们在订阅事件时传入的对象。

4.运行测试

现在,运行游戏,看看效果:



如果能成功地看到日志输出,那就代表我们成功了。
25 条评论
  • ACE 2021-04-26 19:18:39

    现在感觉GameFramework颇有ECS的味道
    0回复
    • 博主 笨木头 2021-04-26 19:46:04

      是有点,官方的DOTS好像还没出正式版?这大招憋了挺久的😂
      0回复
      • ACE 2021-04-26 19:48:52

        官方的DOTS正式版确实还没有,现在用还需要用job system,burst一些插件,没有很好的集成,倒是GameFrameWork有那么点以上😂,如果官方后面整合好点,Unity以后的开发模式会发生大变化,现在Unity开发大部分都是事件框架😂
        0回复
  • YKK 2020-12-14 16:15:08

    我的UI界面成功打开了,为什么我的那个事件的回调函数没有被调用
    0回复
    • 123 2022-04-24 15:39:59

      我也是
      0回复
  • 江志远 2020-06-19 14:35:51

    场景离开是不是要取消订阅
    0回复
    • 博主 笨木头 2020-06-22 17:41:36

      对,需要的需要的,文章没有提醒大家,疏忽了
      0回复
  • 菜鸟一号 2020-03-13 11:56:57

    我的UserData也为空,找了半天才发现自己少填了最后一个参数 UI.OpenUIForm("Assets/Demo4/UI_Menu.prefab", "DefaultGroup", this);
    0回复
    • et群里的leo 2022-03-04 16:23:07

      我的也是
      0回复
  • 哇卡哇卡 2019-08-01 17:33:48

    大佬,为什么我的UserData为空
    0回复
    • 博主 笨木头 2019-08-05 08:58:08

      单是这么说的话,我也不好判断,理论上来说,就是没有传值,所以获取的时候是空的。
      实际上,你可以试试我的项目是否也有相同的情况?
      如果代码完全一样,也有可能是框架版本引起的(可能性比较小)
      0回复
  • hai 2019-04-20 21:12:12

    你的工程下下来到处报错(=。=)
    0回复
    • 博主 笨木头 2019-04-22 07:37:35

      额...注意Unity和GF的版本,新版本不一定能跑起来(悲伤...)
      0回复
  • XTStarry 2018-09-07 20:29:29

    问一下能用一个回调函数处理生成两个UI的Prefab么?
    0回复
    • 博主 笨木头 2018-09-08 20:55:41

      你说的是事件吧,是可以的,目前就是这么做的,需要在事件里自己判断是打开了哪个UI。
      0回复
  • 2018-07-18 10:01:16

    少引用了Gameframework.Event这个命名空间
    1回复
  • 2018-07-16 13:59:25

    事件回调的参数类型GameEventArg应该是GameFrameworkEventArgs吧,
    0回复
    • 博主 笨木头 2018-07-17 08:45:37

      不是的...你看看Event.Subscribe的参数,里面已经写了是GameEventArg
      0回复
      • 2018-12-22 14:28:54

        为什么直接写GameEventArg会报错,啊?按照小马哥的两个方法是不报错,但是UI没有加载出来,
        0回复
        • 博主 笨木头 2018-12-24 08:13:05

          GameEventArg需要引用命名空间,你用VS的话,它会有提醒
          0回复
  • XTStarry 2018-05-27 23:26:51

    好奇事件订阅在实际使用中有哪些用途?
    0回复
    • 博主 笨木头 2018-05-28 08:39:04

      基本上是用于解耦的,举一个比较实在的例子:
      在游戏中,我们要知道是否有怪物死亡,一旦有怪物死亡,我们就需要更新UI上的怪物剩余数量、更新英雄的经验值、做其他我们希望做的事情。

      实现这种需求,我们可以简单地循环怪物列表,如果发现了状态为Dead的怪物,就进行以上的操作。
      但是这样会有很多问题,一个是效率低,另一个是让不同类型的操作耦合在一起了(因为以上的各种操作都需要在找出死亡怪物时执行)。

      而用事件订阅可以将以上主动的操作转换为被动,我们不需要遍历怪物列表,我们只需要在各个不同的地方订阅怪物死亡消息。
      当怪物死亡时,它自己发出一个怪物死亡消息即可,至于谁要做什么操作,怪物不用管,各自的订阅者会执行自己的逻辑。

      目前来说,如果没有事件订阅机制,我基本上写不出游戏了...(其实不仅仅是游戏,其他开发也是充满了各种事件订阅机制的)
      4回复
      • XTStarry 2018-05-29 18:01:34

        感谢~
        0回复
      • 烟雨迷离半世殇 2018-12-12 19:45:53

        大佬6666
        1回复
      • 大宝 2023-07-25 14:19:14

        大佬太牛了
        0回复
发表评论
粤ICP备16043700号

本博客基于 BlazorAnt Design Blazor 开发