概述
? ? ? 使用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);
}
????
|