IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 使用UniRx、注解来构建Unity事件发布/订阅简易框架(RxBus、UniRxBus) -> 正文阅读

[游戏开发]使用UniRx、注解来构建Unity事件发布/订阅简易框架(RxBus、UniRxBus)

概述

? ? ? 使用UniRx构建事件发布/订阅框架,通过解耦发布者和订阅者简化Unity中事件传递同时方便开发过程的使用。

1、首先导入com.neuecc.unirx 的插件包 可通过opemupm或unity的AssetStore进行导入

?2、构建RxAttribute、RxBus

using System;
using System.Collections.Generic;
using System.Reflection;
using UniRx;
using UnityEngine;
using Object = System.Object;

//RxBus核心代码
//事件发布/订阅简易框架
//需要在Start中调用RxBus.Bind(this)、RxBus.UnBind(this) 进行绑定及解出
//通过Send发布事件
public class RxBus
{
    private static Dictionary<int, Subject<Object>> subjectMap = new Dictionary<int, Subject<Object>>();
    public static Dictionary<long,List<IDisposable>> disposableMap = new Dictionary<long, List<IDisposable>>();
    public static Subject<Object> GetSubject(int code)
    {
        Subject<Object> subject = null;
        if (!subjectMap.TryGetValue(code, out subject))
        {
            subject = new Subject<Object>();
            subject.OnErrorRetry((Exception ex) => Debug.Log("RxBus:" + ex.Message));
            subjectMap.Add(code, subject);
        }

        return subject;
    }
    
    public static List<IDisposable> GetDisposables(long instanceID)
    {
        List<IDisposable> disposables = null;
        if (!disposableMap.TryGetValue(instanceID, out disposables))
        {
            disposables = new List<IDisposable>();
            disposableMap.Add(instanceID, disposables);
        }

        return disposables;
    }

    public static void Send(int code)
    {
        Send(code, null);
    }

    public static void Send(int code, Object data)
    {
        GetSubject(code)
            .OnNext(data);
    }

    public static void Bind(UnityEngine.Object obj)
    {
        MemberInfo[] attribute = obj.GetType().GetMembers(); //获取所有方法
        for (int i = 0; i < attribute.Length; i++)
        {
            MemberInfo mInfo = attribute[i];
            IEnumerable<Attribute> ies = mInfo.GetCustomAttributes(typeof(RxBusAttribute));
            foreach (Attribute attr in ies)
            {
                RxBusAttribute ca = attr as RxBusAttribute;
                if (ca.Code != -1)
                {
                    IDisposable disposable=  GetSubject(ca.Code)
                        .Subscribe(data =>
                        {
                            try
                            {
                                MethodInfo info = obj.GetType().GetMethod(mInfo.Name);
                                if (info.GetParameters().Length == 1)
                                {
                                    info.Invoke(obj, new object[] {data});
                                }
                                else if (info.GetParameters().Length == 0)
                                {
                                    info.Invoke(obj, null);
                                }
                            }
                            catch (Exception e)
                            {
                            }
                        });
                    
                    GetDisposables(obj.GetInstanceID()).Add(disposable);
                }
            }
        }
    }

    public static void UnBind(UnityEngine.Object obj)
    {
        foreach (var disposable in GetDisposables(obj.GetInstanceID()))
        {
            disposable.Dispose();
        }
    }
}

? ? ? ?

using System;

//实现RxBus的注解
//RxBus通过方法上注解的事件code进行订阅/发布
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class SubscribeAttribute : Attribute
{
    private int code;
    public SubscribeAttribute(int code)
    {
        this.code = code;
    }

    public int Code
    {
        get => code;
        set => code = value;
    }
}

3、在实际中使用

? ? 1.通过注解需要订阅消息的方法进行订阅相应消息、Rxbus会根据消息的code和消息方法的参数不同进行不同的消息发布。

????2.通过RxBus.Send(int,Object)发布相应类型的事件回调

? ?3. 现在支持无参和单个参数的订阅回调。同时支持一个方法可以订阅不同事件的code。

????????

void Start()
   {
     RxBus.Bind(this);   
   }

   private void OnDestroy()
   {
      RxBus.UnBind(this);
   }


[Subscribe(100)]
[Subscribe(200)]
public void Sub1(int data)
{
      this.gameObject.SetActive(!this.gameObject.activeSelf);
      Debug.Log(data+"");
 }
public void Send1()
{
   RxBus.Send(100);
}

????

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:41:08  更:2021-08-29 09:41:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 9:45:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码