【Unity】UniRxを覚える(1)
C#のライブラリのReactive ExtensionsをUnity向けに作られたライブラリ
デザインパターンの一つのObserverパターンがベースになっています。
UniRxにおいて、重要なもの。
Subjectがこれまで使ってきた、eventの役割になる。
そしてSubjectの中でも重要な2つの処理が、
SubscribeとOnNext。
Subscribe
メッセージ受取時に実行する処理を登録
OnNext
Subscribeに登録された処理に渡して処理を実行
Subject、Subscribe、OnNextの処理を今までのイベント処理で書くとこんな感じになる。
UniRx実装前
/// <summary> /// イベント。 /// </summary> /// <param name="message">メッセージ。</param> public event Action<string> OnDisplayMessage = delegate(string message){}; void Awake() { // 登録。 OnDisplayMessage += (message) => { Debug.Log(message); }; } void Start() { // 呼び出し。 OnDisplayMessage("Hello!"); }
UniRxを使うとこのように書き直せる。
UniRx実装後
/// <summary> /// UniRx Subject。 /// </summary> public Subject<string> subject = new Subject<string>(); void Awake() { // UniRx Subjectへ登録。 subject.Subscribe(message => { Debug.Log(message); }); } void Start() { // UniRx Subject呼び出し。 subject.OnNext("UniRx Hello!"); }
SubjectはIObserverとIObservableの2つのインターフェースを実装しています。
IObserver
イベントメッセージの発行を担う
OnCompleted
OnError
OnNext
の3つのメソッドが定義されている。
IObservable
イベントメッセージを購読を担う
Subscribe
のメソッドが定義されている。
先程の処理に、OnNext、OnError、OnCompletedを追加するとこのように定義できる。
/// <summary> /// UniRx Subject。 /// </summary> public Subject<string> subject = new Subject<string>(); void Awake() { // UniRx Subject登録。 subject.Subscribe( message => { Debug.Log(message); }, error => { Debug.LogError("Error"); }, () => { Debug.Log("Completed"); } ); } void Start() { // UniRx Subject呼び出し。 subject.OnNext("UniRx Hello!"); }
SubjectとSubscribeの間に挟み込んでメッセージを処理する部品のこと。
LINQのWhereオペレータみたいなもの。
/// <summary> /// Linqサンプル。 /// </summary> public List<int> linqSampleList = new List<int>(); void Awake() { linqSampleList.Add(1); linqSampleList.Add(2); linqSampleList.Add(3); linqSampleList.Add(4); } void Start() { var resultList = linqSampleList.Where(e => e % 2 == 0).ToList(); for(var idx = 0; idx < resultList.Count; ++idx) { Debug.Log(resultList[idx]); } }
UniRxの代表的なオペレータ
Where:フィルタリング
Select:メッセージを変換
Distinct:重複を排除
Buffer:一定個数をまとめるまで待つ
ThrottleFirst:短時間にまとめてきた場合に先頭のみを使う
LINQライクな書き方
Whereを使用する
/// <summary> /// UniRx Subject。 /// </summary> public Subject<string> subject = new Subject<string>(); void Awake() { // UniRx Subject登録。 subject .Where( e => e == "UniRx Hello!" ) .Subscribe( message => { Debug.Log(message); }, error => { Debug.LogError("Error"); }, () => { Debug.Log("Completed"); } ); } void Start() { // UniRx Subject呼び出し。 subject.OnNext("UniRx Hello!"); subject.OnNext("UniRx Hello1!"); subject.OnNext("UniRx Hello2!"); }
"UniRx Hello!"のみ出力される
AwakeやStartへの負担が気になる…
続き
sunagimo-app.hatenablog.com