UniRx に付属しているプロセス内の簡易型の広域メッセージ送受信ライブラリのMessageBroker の使い方の紹介です。
最近は MessageBroker の代わりによりモダンな MessagePipe というライブラリもリリースされていますが、Unity で単一シーン、簡単な UI しか持たないアプリに DI だのなんだのを導入するまでもないため、イベント関係で必須の UniRx にも似たような機能がり、簡単に使うにはそれでいいじゃんということで使い方の紹介です。
DI と関係なく使用するためスコープなんか無いですし、インジェクションだのは使用しません。
確認環境
- Unity 2021.3.16f1
- Windows11 + VisualStudio2022
- UniRx 7.1.0
使用方法
交換する型の作成
同じ型どうしでメッセージがやり取りできるのでデータをやり取りする型を作成します。
// classではなくreadonly structのほうがGCAllocが少ない public readonly struct SamplEventArgs { public readonly int Value; public SamplEventArgs(int value) => Value = value; }
int とかでもやり取りできますが同じ型で登録したハンドラーが全部反応する & 意味不明になるため専用の型を作成します。
イベントを発行する
// (1) フィールドに送信する変数を取ってから送信する IMessagePublisher b = MessageBroker.Default; private void Send() { b.Publish(new SamplEventArgs(10)); } // (2) 直接送信する private void Send() { MessageBroker.Default.Publish(new SamplEventArgs(20)); }
イベントを購読する
// (1) フィールドに受信する変数を取ってから送信する IMessageReceiver r = MessageBroker.Default; private void Receive() { r.Receive<SamplEventArgs>() .Subscribe(e => Debug.Log(e.Value)).AddTo(this); } // (2) 直接受信を登録する private void Receive() { MessageBroker.Default.Receive<SamplEventArgs>() .Subscribe(e => Debug.Log(e.Value)).AddTo(this); }
DomainReload対応
static 変数を使ってるので DomainReload を有効にしてる場合、2度目から正常に動かなくなるので以下を修正しておきます。
修正しないと Publish したときにオブジェクトが Destory 済みですみたいなメッセージが表示されます。
MessageBroker.cs // ★修正前 public class MessageBroker : IMessageBroker, IDisposable { /// <summary> /// MessageBroker in Global scope. /// </summary> public static readonly IMessageBroker Default = new MessageBroker(); // ★修正後 public class MessageBroker : IMessageBroker, IDisposable { /// <summary> /// MessageBroker in Global scope. /// </summary> public static IMessageBroker Default => _default; private static IMessageBroker _default = new MessageBroker(); [UnityEngine.RuntimeInitializeOnLoadMethod( UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)] static void OnDidReloadScripts() { _default = new MessageBroker(); }
関連記事
MessageBrokerを少し便利にする実装です。