目次
UniRxとは
UniRxは、Reactive ExtensionsをUnity向けにカスタマイズしたライブラリです。
Reactive Extensions、略してRxは、MicrosoftResearchによって開発が行われた、C#向けのライブラリです。
GoFのデザインパターンの一つでもある、Observerパターンが軸となっています。
UniRxはUnity向けに作られたライブラリですが、Reactive Extensionsは他の言語にも移植されており、とても優れたライブラリになっています。
本物のReactive Extensionsに比べると、Unityに特化している、パフォーマンスが良くメモリが効率的に使われている、独自のReactivePropertyが追加されている、様々なオペレータが追加されている、などの特徴があります。
UniRxを使おうとした経緯
UniRxを使おうとした経緯ですが、ファイル操作、通信処理、UIの記述などを行う際、冗長的な書き方になってしまうことが多かった為、なんとかもう少し簡潔にできないだろうか、というところからUniRxにたどり着きました。
Subject
SubjectというものがUniRxを使う上で、重要なものになってきます。
その中でもさらに重要な概念として、Subscribeと、OnNextというものが存在します。
Subscribe
メッセージを受信した際に実行される処理を登録する。
OnNext
何かの値(メッセージ)をSubscribeが行われた際に渡す。
具体的な例は以下に記載します。
コード
Subject sub = new Subject();
sub.Subscribe(message => Debug.Log("A:" + message));
sub.Subscribe(message => Debug.Log("B:" + message));
sub.Subscribe(message => Debug.Log("C:" + message));
sub.OnNext("Message1");
sub.OnNext("Message2");
実行結果
A:Message1
B:Message1
C:Message1
A:Message2
B:Message2
C:Message2
IObservable、IObserver
先述したSubjectはIObservableインターフェースとIObserverインターフェースを実装しています。
IObservable
IObservableインターフェースは、イベントメッセージを購読できるインターフェースです。
内容としてはSubscribeメソッドが定義されています。
IObserver
IObserverインターフェースは、イベントメッセージを発行できるインターフェースです。
内容としてはOnCompleted、OnError、OnNextの3つのメソッドが定義されています。
上記のことからSubjectは、値を発行でき、かつ、値を購読できる、ということが言えます。
オペレーター
UniRxを使う上でかかせないのがオペレーターの存在です。
よく使用する頻度の高いものを少し紹介します。
Where
こちらはメッセージをフィルタリングするオペレーターになります。
使用例を以下に記載します。
“Message1″という文字がきたときのみ処理を行いたい場合
Subject sub = new Subject();
sub.Where(message => message == "Message1")
.Subscribe(message => Debug.Log("A:" + message));
sub.OnNext("Message1");
これをWhereを使わないで書くと、if文で分岐をしなくてもいけなくなります。
以下、例です。
Subject sub = new Subject();
sub.Subscribe(message => {
if(message == "Message1") {
Debug.Log("A:" + message);
}
}
);
sub.OnNext("Message1");
Whereを使ったほうがスッキリしているのが分かると思います。
uGUIをUniRxで管理する
UniRxを使うメリットの中でもとくにコードがスッキリするのがuGUIのボタンなどをRx化することではないかと思います。
Inspectorからボタンに関数を登録することもできますが、これだとScriptを見ただけではどの関数が呼ばれるのか分からない為、処理が追いにくいです。
そこでserializefieldにしたボタンをRx化して、処理を記述した方が、直感的に何をしたいのかがわかります。
以下に例を記載します。
[SerializeField]
private Button _button;
void Awake() {
_button.OnClickAsObservable()
.Subscribe(_ => {
// ここに処理を書いたり、関数を呼んだりします
});
}
ただ、注意しなければならないのが、このままだとストリームが破棄されません。
ストリームを破棄する為にはDisposeをする必要があるのですが、いちいちその処理を書くのが面倒という場合には便利な書き方があります。
それはAddToです。
AddToはUniRxに用意されているメソッドで、Subscribeの後に書くことで、対象のGameObject(Button)が破棄(Destroy)されたタイミングで、自動的にDisposeを実行してくれます。
便利なので忘れずに記述するようにした方がいいです。
ストリームが残ったままだとメモリリークの原因になります。
AddToは以下のように記載します。
[SerializeField]
private Button _button;
void Awake() {
_button.OnClickAsObservable()
.Subscribe(_ => {
// ここに処理を書いたり、関数を呼んだりします
}).AddTo(this.gameObject);
}
この記事へのコメントはありません。