未来のプログラミング技術をUnityで -UniRx-

145
未来のプログラミング技術をUnityで ~UniRx~ @toRisouP 2015/03/20

Transcript of 未来のプログラミング技術をUnityで -UniRx-

Page 1: 未来のプログラミング技術をUnityで -UniRx-

未来のプログラミング技術をUnityで~UniRx~

@toRisouP

2015/03/20

Page 2: 未来のプログラミング技術をUnityで -UniRx-

スライド中に登場するサンプル

http://torisoup.net/unirx-examples/

Page 3: 未来のプログラミング技術をUnityで -UniRx-

【2015/10/5 】

一部加筆修正しました

Page 4: 未来のプログラミング技術をUnityで -UniRx-

合わせて読みたい

• もう少し踏み込んだ使い方の話はこちらのスライドで

• http://www.slideshare.net/torisoup/uni-rx

Page 5: 未来のプログラミング技術をUnityで -UniRx-

自己紹介

• とりすーぷ(@toRisouP)

• 26歳

• 本業はWebエンジニア

• 趣味でUnityでゲーム作ってます

Page 6: 未来のプログラミング技術をUnityで -UniRx-

過去に作ったもの

交通事故・渋滞シミュレータ

(sm16238908)

みくみくまうす

(ニコ生配信支援ツール)

NITORI BOX

(東方2次創作ゲーム)

Page 7: 未来のプログラミング技術をUnityで -UniRx-

みくみくまうす

• ニコ生の配信支援ツール

• MMDモデルがコメントを読み上げる

• Unity製

• フリーソフトとして公開中

http://mikumikumouth.net/

Page 8: 未来のプログラミング技術をUnityで -UniRx-

今作ってるゲーム

みこバト~レ

• 東方2次創作の同人ゲーム

• Unity + PhotonCloud

• 例大祭と夏コミあたりで体験版出したい…

Page 9: 未来のプログラミング技術をUnityで -UniRx-

ところで

Page 10: 未来のプログラミング技術をUnityで -UniRx-

「マウスのダブルクリック判定」

実装できますか?

Page 11: 未来のプログラミング技術をUnityで -UniRx-

マウスのダブルクリック判定

• どうやって実装する?

– 最後にクリックされてから一定時間以内ならダブルクリック?

– クリック回数の変数とタイマの変数をフィールドに定義?

– Update内に判定処理を書く?

Page 12: 未来のプログラミング技術をUnityで -UniRx-

めんどい

Page 13: 未来のプログラミング技術をUnityで -UniRx-

これをUniRxを使うと

たったの数行で済みます

Page 14: 未来のプログラミング技術をUnityで -UniRx-
Page 15: 未来のプログラミング技術をUnityで -UniRx-

たったのこれだけ!

Page 16: 未来のプログラミング技術をUnityで -UniRx-

すごくね?

Page 17: 未来のプログラミング技術をUnityで -UniRx-

今回の発表の目標

実際の使用例を通して

UniRxの凄さ便利さを伝えたい!

Page 18: 未来のプログラミング技術をUnityで -UniRx-

ターゲット

LINQは使えるレベルの人プログラミング始めたばかりの人には少々厳しいかも

Page 19: 未来のプログラミング技術をUnityで -UniRx-

端折った説明や

厳密ではない説明をします

ご了承ください(わかりやすさ第一で行きます)

Page 20: 未来のプログラミング技術をUnityで -UniRx-

もくじ

1. UniRxって何?

2. UniRxって何が便利なの?

3. ストリームを使うメリットと例

4. よく使うオペレータ解説

5. Unity上での実用例5つ

6. まとめ

Page 21: 未来のプログラミング技術をUnityで -UniRx-

UniRxって何?

Page 22: 未来のプログラミング技術をUnityで -UniRx-

UniRx

• Reactive Extensions for Unity

• 作者は@neueccさん

• MITライセンスで公開

• AssetStoreまたはgithubからダウンロード可(無料)

Page 23: 未来のプログラミング技術をUnityで -UniRx-

Reactive Extensionsとは

• FanctionalReactivePrograming をC#で実現するためのライブラリ

– LINQ to Events

– 元はMicrosoftReserchが開発

• 決してオレオレライブラリでは無い!

• 最近になって流行の兆しが来ている

– いろんな言語に移植されている

• RxJS、RxJava、ReactiveCocoa、RxPy、UniRx…

– どんな言語でもRxの考え方は共通している!

• 覚えておいて損は絶対にしない!

Page 24: 未来のプログラミング技術をUnityで -UniRx-

UniRxは何が便利なの?

Page 25: 未来のプログラミング技術をUnityで -UniRx-

UniRxを使うと

時間の取り扱いが

とても簡単になります

Page 26: 未来のプログラミング技術をUnityで -UniRx-

時間が絡んだ処理の例

• イベントの待ち受け

– マウスクリックやボタン入力のタイミングで処理をする

• 非同期処理

– 別スレッドで通信したり、別スレッドでデータロードしたり

• 時間計測が判定に必要な処理

– 長押し、ダブルクリックの判定

• 時間変化する値の監視

– False→Trueになった瞬間に1回だけ処理したい

Page 27: 未来のプログラミング技術をUnityで -UniRx-

こういった処理をRxを使うと

とても簡潔に記述できます

Page 28: 未来のプログラミング技術をUnityで -UniRx-

まずはRxの基本的な

考え方を実際のコードを見せつつ

説明します

Page 29: 未来のプログラミング技術をUnityで -UniRx-

ボタンがクリックされたら画面に表示する

Buttonをクリックした時にTextに”Clicked”と表示してみる

Page 30: 未来のプログラミング技術をUnityで -UniRx-

クリックされたら画面に表示するスクリプト

←メイン処理

Page 31: 未来のプログラミング技術をUnityで -UniRx-

クリックされたら画面に表示するスクリプト

←Unity側が用意しているクリックイベント

Page 32: 未来のプログラミング技術をUnityで -UniRx-

クリックされたら画面に表示するスクリプト

←イベントをストリームに変換

Page 33: 未来のプログラミング技術をUnityで -UniRx-

クリックされたら画面に表示するスクリプト

←ストリームの購読(最終的に何をするか書く)

Page 34: 未来のプログラミング技術をUnityで -UniRx-

ストリーム

• 「イベントが流れる配管」みたいなイメージ

– 難しく言えば「時間軸上に並んだイベントのシーケンス」

– 分岐させたり合流させたりできる

• コード中では IObservable<T> として扱われる

– LINQで言うIEnumerable<T>に相当

イベントメッセージ

イベントの流れそのものが「ストリーム」

Page 35: 未来のプログラミング技術をUnityで -UniRx-

ストリームに流すイベント「メッセージ」

メッセージは3種類ある

• OnNext

– 通常使用するメッセージ

– 普通はこれを使う

• OnError

– エラー発生時の例外を通知するメッセージ

• OnCompleted

– ストリームが終了した事を通知するメッセージ

Page 36: 未来のプログラミング技術をUnityで -UniRx-

ボタンは

「クリック時にイベントをストリームに流している」

と考えることができる

ストリームとボタンクリック

Button

ボタンがクリックされたタイミングでストリームにメッセージを送り込む(OnNext)

Page 37: 未来のプログラミング技術をUnityで -UniRx-

• ストリームの末端でメッセージが来た時に何をするかを定義する

• ストリームはSubscribeされた瞬間に生成される

– 基本的にSubscribeしない限りストリームは動かない

– Subscribeのタイミングによって結果が変わる可能性がある

• OnError, OnCompleteが来るとSubscribeは終了する

Subscribe(ストリームの購読)

Subscribeストリームを購読して

メッセージが来た時に処理をする

ストリーム

Page 38: 未来のプログラミング技術をUnityで -UniRx-

(補足)Subscribeとメッセージ

Subscribeはオーバーロードで複数定義されているので用途に合わせて使う

と良い

• OnNextのみ

• OnNext & OnCompleted

• OnNext & OnError & OnCompleted

Page 39: 未来のプログラミング技術をUnityで -UniRx-

全体の流れ

←ボタンクリックイベントをストリームに変換しメッセージが到着した時にテキストに”Clicked”を表示する

Page 40: 未来のプログラミング技術をUnityで -UniRx-

Subscribeのタイミング

Awake()/Start()でSubscribeするべきUpdate()に書くと無数のストリームが生成される

Page 41: 未来のプログラミング技術をUnityで -UniRx-

ちなみに

UniRxには、

uGUI用のObservableやSubscribeが準備されている

↑さっきの奴はこれくらい簡略化して書ける

Page 42: 未来のプログラミング技術をUnityで -UniRx-

「ストリーム」という考え方

のメリット

Page 43: 未来のプログラミング技術をUnityで -UniRx-

イベントの

射影、フィルタリング、合成

などができる

Page 44: 未来のプログラミング技術をUnityで -UniRx-

Page 45: 未来のプログラミング技術をUnityで -UniRx-

Buttonが3回押されたらTextに表示する

• ボタンがクリックされた回数をカウントする?

– カウンタ用の変数をフィールドに定義する?

Page 46: 未来のプログラミング技術をUnityで -UniRx-

Buttonが3回押されたらTextに表示する

• Buffer(3)を加えるだけ!

– 余計なフィールド変数不要!

– なお、Skip(2)でも同じ動作をする

• ここではわかりやすくBufferを使ったが、

n回後に動作するというシチュエーションではSkipの方が適切ではある

Page 47: 未来のプログラミング技術をUnityで -UniRx-

Buffer

• メッセージを蓄えて特定のタイミングで流す

– 放出する条件はいろいろ指定できる

• n個溜まったら流す

• 別のストリームにメッセージが流れてきたら流す

画像はhttp://reactivex.io/documentation/operators/map.htmlより引用

Page 48: 未来のプログラミング技術をUnityで -UniRx-

例2

Page 49: 未来のプログラミング技術をUnityで -UniRx-

Buttonが2つとも押されたらTextに表示する

• 両方が交互に1回ずつ押された時にTextに表示する

– 連打しても「1回押された」と判定させる

Page 50: 未来のプログラミング技術をUnityで -UniRx-

Zip

• 複数本のストリームのメッセージが全て揃うまで待つ

– メッセージが揃った時に1個ずつ取り出して後続に流す

– 揃ったメッセージは任意に加工して出力できる

画像はhttp://reactivex.io/documentation/operators/zip.htmlより引用

Page 51: 未来のプログラミング技術をUnityで -UniRx-

Buttonが2つとも押されたらTextに表示する

Page 52: 未来のプログラミング技術をUnityで -UniRx-

Buttonが2つとも押されたらTextに表示する

←1度動作した後にZip内のバッファをクリアする(後で説明します)

Page 53: 未来のプログラミング技術をUnityで -UniRx-

Rxを使わない従来のやり方では、

イベントを受け取った後に

どうするかを書いていた

Page 54: 未来のプログラミング技術をUnityで -UniRx-

Rxでは

イベントを受け取る前に

何をしたいかが書ける

Page 55: 未来のプログラミング技術をUnityで -UniRx-

「ストリームを加工して

自分が欲しいイベントだけ

通知させればいいじゃん!」

Page 56: 未来のプログラミング技術をUnityで -UniRx-

まとめると、

Rxは

1.ストリームを用意して

2.ストリームをオペレータで加工して

3.最後にSubscribeする

という考え方で使われる

Page 57: 未来のプログラミング技術をUnityで -UniRx-

オペレータストリームをこねこねするもの

Page 58: 未来のプログラミング技術をUnityで -UniRx-

オペレータ

• ストリームに操作を加える関数のこと

• メチャクチャたくさんある

Select, Where, Skip, SkipUntil, SkipWhile, Take, TakeUntil, TakeWhile, Throttle, Zip, Merge,

CombineLatest, Distinct, DistinctUntilChanged, Delay, DelayFrame, First, FirstOfDefault,

Last, LastOfDefault, StartWith, Concat, Buffer, Cast, Catch, CatchIgnore, ObserveOn, Do,

Sample, Scan, Single, SingleOrDefault, Retry, Repeat, Time, TimeStamp, TimeInterval…

Page 59: 未来のプログラミング技術をUnityで -UniRx-

よく使うオペレータ紹介

Page 60: 未来のプログラミング技術をUnityで -UniRx-

Where

• 条件を満たすメッセージのみ通過させるオペレータ

– 他の言語では「filter」とも呼ばれる

画像はhttp://reactivex.io/documentation/operators/filter.htmlより引用

Page 61: 未来のプログラミング技術をUnityで -UniRx-

Select

• 要素の値を射影(変換)する

– 他の言語では「map」とも呼ばれる

画像はhttp://reactivex.io/documentation/operators/map.htmlより引用

Page 62: 未来のプログラミング技術をUnityで -UniRx-

SelectMany

• 新たなストリームを生成して、そのストリームが流すメッセージを本流のス

トリームのメッセージとして扱う

– ストリームを別ストリームで差し替えるイメージ(厳密に言うと違う)

– 他の言語では「flatMap」とも呼ばれる

画像はhttp://reactivex.io/documentation/operators/flatmap.htmlより引用

Page 63: 未来のプログラミング技術をUnityで -UniRx-

Throttle/ThrottleFrame

• 落ち着いた時に最後のメッセージを流す

– メッセージが集中して流れてきたら最後以外を無視する

– 他の言語では「debounce」とも呼ばれる

– よく使う

画像はhttp://reactivex.io/documentation/operators/debounce.htmlより引用

Page 64: 未来のプログラミング技術をUnityで -UniRx-

ThrottleFirst/ThrottleFirstFrame

• 最初にメッセージが来てから一定時間遮断する

– 1つメッセージがそこからしばらくメッセージを遮断する

– 大量に流れてきたデータのうち最初だけ使いたいみたいなときに有

画像はhttp://reactivex.io/documentation/operators/sample.htmlより引用

Page 65: 未来のプログラミング技術をUnityで -UniRx-

Delay/DelayFrame

• メッセージの伝達を遅延させる

画像はhttp://reactivex.io/documentation/operators/delay.htmlより引用

Page 66: 未来のプログラミング技術をUnityで -UniRx-

DistinctUntilChanged

• メッセージが変化した時のみ通知する

– 同じ値が連続している場合は無視する

画像はhttp://rxmarbles.com/#distinctUntilChangedより引用

Page 67: 未来のプログラミング技術をUnityで -UniRx-

SkipUntil

• 指定したストリームにメッセージが来るまで

メッセージをSkipする

画像はhttp://rxmarbles.com/#skipUntilより引用

Page 68: 未来のプログラミング技術をUnityで -UniRx-

TakeUntil

• 指定したストリームにメッセージが来たら、

自身のストリームにOnCompletedを流して終了させる

画像はhttp://rxmarbles.com/#takeUntilより引用

Page 69: 未来のプログラミング技術をUnityで -UniRx-

TakeUntil

• 指定したストリームにメッセージが来たら、

自身のストリームにOnCompletedを流して終了させる

Page 70: 未来のプログラミング技術をUnityで -UniRx-

Repeat

• ストリームがOnCompletedで終了した時にもう一度Subscribe

を行う

Page 71: 未来のプログラミング技術をUnityで -UniRx-

SkipUntil+TakeUntil+Repeat

• よく使う組み合わせ

– イベントAが来てからイベントBが来るまでの間だけ処理したいような

時に使う

Page 72: 未来のプログラミング技術をUnityで -UniRx-

SkipUntil+TakeUntil+Repeatの例

例)ドラッグでオブジェクトを回転させる

– MouseDownが来てからMouseUpが来るまで処理したい

Page 73: 未来のプログラミング技術をUnityで -UniRx-

First

• ストリームに最初に来たメッセージのみを流す

– OnNextの直後にOnCompleteも流れる

画像はhttp://reactivex.io/documentation/operators/first.htmlより引用

Page 74: 未来のプログラミング技術をUnityで -UniRx-

さっきのZipの例でFirst+Repeatを使った意図

First+Repeatで1回動作する度にストリームを作り直している(Zip内のメッセージキューをリセットするため)

Page 75: 未来のプログラミング技術をUnityで -UniRx-

ここまでが基礎基礎の説明だけでスライド70枚突破してる

Page 76: 未来のプログラミング技術をUnityで -UniRx-

ここから実例を紹介

Page 77: 未来のプログラミング技術をUnityで -UniRx-

実際の使用例5つ

1. ダブルクリック判定

2. 値の変動を監視する

3. 値の変動を丸める

4. WWWを使いやすくする

5. PhotonCloudと組み合わせる

Page 78: 未来のプログラミング技術をUnityで -UniRx-

1.ダブルクリック判定

Page 79: 未来のプログラミング技術をUnityで -UniRx-

ダブルクリック検知のコード

Page 80: 未来のプログラミング技術をUnityで -UniRx-

クリックストリームの定義

クリックのストリームを定義(≠生成)

Page 81: 未来のプログラミング技術をUnityで -UniRx-

クリックストリームの定義

【10/5 加筆】現在はUniRx.Triggersをusingに加えた上で、this.UpdateAsObservable()で呼び出せます

Page 82: 未来のプログラミング技術をUnityで -UniRx-

クリックストリーム

UpdateAsObservable()Updateのタイミングを通知

Where()クリックがあったフレームのみ通過

clickStreamクリックイベントのストリーム

Page 83: 未来のプログラミング技術をUnityで -UniRx-

よくみると2つのストリームがある

Page 84: 未来のプログラミング技術をUnityで -UniRx-

よくみると2つのストリームがある

Page 85: 未来のプログラミング技術をUnityで -UniRx-

意味

クリックストリームを塞き止めてまとめる。開放条件は「最後にクリックされてから200ミリ秒経過した時」である。

Page 86: 未来のプログラミング技術をUnityで -UniRx-

クリックストリーム

clickStreamマウスクリックのストリーム

Throttle(200ms)200ms間イベントが起きなかったら通知

200ms

Bufferイベントをまとめる終了条件はThrottleイベントが来るまで

3 1 2

Page 87: 未来のプログラミング技術をUnityで -UniRx-

2.値の変動を監視する

Page 88: 未来のプログラミング技術をUnityで -UniRx-

プレイヤが着地した瞬間にエフェクトを再生する

Page 89: 未来のプログラミング技術をUnityで -UniRx-

着地した瞬間の検知方法

1. CharacterController.isGroundedを毎フレーム監視

2. 現フレームにおける値をフィールド変数に保存

3. 次フレームでFalse → Trueに変わった時にエフェクトを再生する

Page 90: 未来のプログラミング技術をUnityで -UniRx-

UniRxを使わずに着地した瞬間の検知をしてみる

Page 91: 未来のプログラミング技術をUnityで -UniRx-

UniRxを使わずに着地した瞬間の検知をしてみる

パッと見で何やってるか判断できない!

←一時保存用のためだけのフィールド変数!!

Page 92: 未来のプログラミング技術をUnityで -UniRx-

UniRxで着地した瞬間の検知をしてみる

Page 93: 未来のプログラミング技術をUnityで -UniRx-

UniRxで着地した瞬間の検知をしてみる

ここだけ!フィールド変数なんぞいらん!

Page 94: 未来のプログラミング技術をUnityで -UniRx-

着地判定のイメージ図

F F F T T T T F F

F T F

T

UpdateAsObservable()Updateのタイミングを通知

Select()IsGroundedの値に差し替え

DistinctUntilChanged()値に変化があった時のみ通過

Where()値がTrueの時のみ通過

Subscribe()isGroundedがFalse→Trueになった瞬間が通知される

Page 95: 未来のプログラミング技術をUnityで -UniRx-

【追記】ObserveEveryValueChanged

毎フレーム値の変動を監視するなら「ObserveEveryValueChanged」の方がシ

ンプルにかける

Page 96: 未来のプログラミング技術をUnityで -UniRx-

3.値の変動を丸める

Page 97: 未来のプログラミング技術をUnityで -UniRx-

isGroundedの変動を丸める

• isGroundedの精度の改善

– 斜面を移動するとTrue/Falseが激しく変動する

– この値の変動をUniRxで抑えこんでみる

Page 98: 未来のプログラミング技術をUnityで -UniRx-

方針

• isGroundedの変動をThrottleで無視させる

– DistinctUntilChangedと併用すればOK

Page 99: 未来のプログラミング技術をUnityで -UniRx-

UniRxでisGroundedの変動を丸める

Page 100: 未来のプログラミング技術をUnityで -UniRx-

isGroundedの丸め込みイメージ図

T F T T T T T T T

T

T

UpdateAsObservable()Updateのタイミングを通知

Select()IsGroundedの値に差し替え

DistinctUntilChanged()値に変化があった時のみ通過

ThrottleFrame(5)値が5フレームの間来なかったら最後の値を放流

Subscribe()isGroundedが6フレーム以上安定していた時に最後の値が通知される

F T

1 2 3 4 5

Page 101: 未来のプログラミング技術をUnityで -UniRx-

4.WWWを使いやすくする

Page 102: 未来のプログラミング技術をUnityで -UniRx-

UnityのWWW

• Unityの標準のHTTP通信用モジュール

– コルーチンとして使う必要があり

– そこまで使い勝手は良くない(HttpWebRequestよりはだいぶマシだけどさ…)

Page 103: 未来のプログラミング技術をUnityで -UniRx-

ObservableWWW

• WWWをObservableとして扱えるようにしたもの

– Subscribeされた瞬間に通信が行われる

– 後は勝手に裏で通信して結果がストリームに流れてくる

– コルーチンを使わずにかける

Page 104: 未来のプログラミング技術をUnityで -UniRx-

例)ボタンが押されたらテクスチャを読み込む

• ボタンが押されたら指定URLのテクスチャ画像をダウンロード

してImageに表示する

Page 105: 未来のプログラミング技術をUnityで -UniRx-

WWWでテクスチャ読み込み

Page 106: 未来のプログラミング技術をUnityで -UniRx-

WWWでテクスチャ読み込み

クリックストリームをObservableWWWのストリームで上書きする

←ボタンを連打されても通信は1回しかさせないためにFirstを入れる

Page 107: 未来のプログラミング技術をUnityで -UniRx-

WWWでテクスチャ読み込み

複雑なことも上から読めば何やってるかすぐわかる1. ボタンがクリックされたら2. HTTPでテクスチャ画像をダウンロードして3. その結果をSpriteに変換し4. Imageとして表示する

Page 108: 未来のプログラミング技術をUnityで -UniRx-

タイムアウトを付け加える

タイムアウトが欲しいならここにオペレータを挟むだけ

Page 109: 未来のプログラミング技術をUnityで -UniRx-

ObservableWWWでいろいろ

• 同時に通信して全てデータが揃ったら処理を進める

Page 110: 未来のプログラミング技術をUnityで -UniRx-

ObservableWWWでいろいろ

• 前の通信の結果を使って次の通信を行う

– サーバに「リソースへのURL」を問い合わせて、サーバに教えてもらっ

たURLからデータをダウンロードする

resourcepath.txtの中に書かれたURLへアクセスするコード

Page 111: 未来のプログラミング技術をUnityで -UniRx-

5.Photon Cloudと組み合わせる

Page 112: 未来のプログラミング技術をUnityで -UniRx-

PhotonCloud

• Unityで簡単にネットワーク対戦が実装できるライブラリ

• 通知が全てコールバックで微妙に使い勝手が悪い

– UniRxでなんとかしたい

Page 113: 未来のプログラミング技術をUnityで -UniRx-

• PhotonCloudのコールバックがストリームに変換される

– ごちゃごちゃしたコールバックは隠蔽される

UniRxと組み合わせると?

PhotonCloudコールバックで

ごちゃごちゃした世界

最新の部屋情報の通知ストリーム ロビー参加に成功した通知ストリーム

部屋に参加成功した通知ストリーム

UniRxでコールバックを隠蔽

Page 114: 未来のプログラミング技術をUnityで -UniRx-

コールバックからストリームに変換するメリット

• IDEの補完が効くようになる

– PhotonのコールバックはSendMessageで呼び出される

– Observableとしてちゃんと定義してあげれば補完が効く

• 多様なオペレータによる柔軟な制御ができるようになる

– ログインに失敗したら3秒後にリトライ試すとか

– 全員からレスポンスがあった時に処理をするとか

– 部屋情報リストが更新されたことを通知するとか

Page 115: 未来のプログラミング技術をUnityで -UniRx-

コールバックからストリームに変換するメリット

• IDEの補完が効くようになる

– PhotonのコールバックはSendMessageで呼び出される

– Observableとしてちゃんと定義してあげれば補完が効く

• 多様なオペレータによる柔軟な制御ができるようになる

– ログインに失敗したら3秒後にリトライ試すとか

– 全員からレスポンスがあった時に処理をするとか

– 部屋情報リストが更新されたことを通知するとか

Page 116: 未来のプログラミング技術をUnityで -UniRx-

例)最新の部屋情報を通知するストリームを作る

• OnRevicedRoomListUpdate

– PhotonNetwork.GetRoomList()が更新された時に実行される

– これをストリームにしてしまう

Page 117: 未来のプログラミング技術をUnityで -UniRx-

つまりこういう形にしたい

最新のRoomInfo[]が流れるストリームこれをSubscribeしておけば、部屋リストに更新があったことがすぐわかる

Page 118: 未来のプログラミング技術をUnityで -UniRx-

ストリームの根源の作り方

• Observableのファクトリメソッドを使う

• 既存のイベント等から変換する

• Subject<T>系を使う

• ReactiveProperty<T>を使う

Page 119: 未来のプログラミング技術をUnityで -UniRx-

ReactiveProperty

• Subscribeすることができる変数

• ObservableとしてSubscribeができる

• 値を書き込んだ時にOnNextメッセージが飛ぶ

Page 120: 未来のプログラミング技術をUnityで -UniRx-

ReactivePropertyで部屋情報を通知する

Page 121: 未来のプログラミング技術をUnityで -UniRx-

ReactivePropertyで部屋情報を通知する

OnRecivedRoomListUpdateのタイミングで_reactiveRoomsの値を書き換え、同時にストリームに通知が飛ぶ

Page 122: 未来のプログラミング技術をUnityで -UniRx-

ReactivePropertyで部屋情報を通知する

Observableとしてクラスの外に公開

Page 123: 未来のプログラミング技術をUnityで -UniRx-

受信側(さっきと同じスライド)

コールバック地獄からの開放!

Page 124: 未来のプログラミング技術をUnityで -UniRx-

【追記】PhotonRx

• PhotonRx

– PUNの使い勝手を上げるライブラリ

– 各コールバックをObservableとして取得できる

– 詳しくは以下のスライドをどうぞ

– http://www.slideshare.net/torisoup/unirxpun

Page 125: 未来のプログラミング技術をUnityで -UniRx-

紹介したい機能は

まだまだたくさんある

Page 126: 未来のプログラミング技術をUnityで -UniRx-

これ以上話すと

さすがに詰め込み過ぎなので

ココらへんで終わります(というか既に詰め込み過ぎ)

Page 127: 未来のプログラミング技術をUnityで -UniRx-

補足スライドも用意してあるので

そちらも見てね

Page 128: 未来のプログラミング技術をUnityで -UniRx-

まとめ

• UniRxは便利なので使ってみよう!!!!!!!!

– 「時間」をすごい簡単に扱えるようになる

– GUI周りの実装もスッキリ書ける

– ゲームロジックに適用することもできる

• UniRxは便利だが難しい面もある

– 学習コストが高くて概念的にも難しい

– 導入する場合はプログラムの設計から考え直す必要が出てくる

• 真価を発揮させるには設計の根幹にUniRxがガッツリ食い込む

• 「便利ライブラリ」ではなく「言語拡張」だと思う必要がある

Page 129: 未来のプログラミング技術をUnityで -UniRx-

ありがとうございました@toRisouP

Page 130: 未来のプログラミング技術をUnityで -UniRx-
Page 131: 未来のプログラミング技術をUnityで -UniRx-

以下補足とか

Page 132: 未来のプログラミング技術をUnityで -UniRx-

参考にするとよいサイト

• ReactiveX

– http://reactivex.io/

– Rxについて細かく解説されているサイト(ただし英語)

• Reactive extensions入門v0.1

– http://www.slideshare.net/okazuki0130/reactive-extensionsv01

– @okazukiさんがまとめてくれたRxについての日本語資料

– すごいよくまとまっているので1度目を通すべし

• Rx入門

– http://blog.xin9le.net/entry/rx-intro

– じんぐる(@xin9le)さんがRxについてまとめてくれた日本語サイト

Page 133: 未来のプログラミング技術をUnityで -UniRx-

参考にするとよいサイト2

• Qiita - UniRxについて書いた記事をまとめてみた

– http://qiita.com/toRisouP/items/48b9fa25df64d3c6a392

– 自分がUniRxを使う上でのメモ書きとして残したもの

– 参考になれば

Page 134: 未来のプログラミング技術をUnityで -UniRx-

補足)Subject<T>

• ストリームの根源を作るもの

– Subject,ReplySubject,BehaviorSubject,AsyncSubjectと複数種類あり

– 外に公開するときは必ずAsObservableを挟んで公開する

• 外から直接OnNextが叩ける状態にしない

Page 135: 未来のプログラミング技術をUnityで -UniRx-

• Disposeを呼び出すとSubscribeが中止される

– ストリームの根源が削除されると自動的にDisposeされる

– ストリームが終了状態になってもDisposeされる

– staticなストリームを作った場合は手動Disposeが必要

補足)Subscribeの止め方

button.onClickで作ったストリームはButtonがシーンから削除されたタイミングでDisposeされる

Page 136: 未来のプログラミング技術をUnityで -UniRx-

補足)UpdateAsObservableとObservable.EveryUpdate

どちらもUpdate()のタイミングを通知してくれるObservable

• UpdateAsObservable

– ObservableMonoBehaviour を継承すると使える

– (追記)ObservableMonoBehabiourを継承する方式は非推奨になりました

代わりにUniRx.Triggers名前空間に用意されている拡張メソッドの方

を使いましょう

– IObservable<Unit>

– コンポーネントのDestory時に自動Disposeされる

• Observable.EveryUpdate

– どのスクリプトからでも使える

– IObservable<long> (Subscribeした時からのフレーム数)

– 使い終わったら明示的にDisposeする必要がある

• またはOnCompleteがちゃんと発火するストリームにする

Page 137: 未来のプログラミング技術をUnityで -UniRx-

おまけ

Page 138: 未来のプログラミング技術をUnityで -UniRx-

おまけ)コルーチンをObservableに変換する

• Observable.FromCoroutineを使うと変換できる

– コルーチンの実行順序や実行条件をストリームで定義できる

コルーチンAが終わったらコルーチンBを実行する例

Page 139: 未来のプログラミング技術をUnityで -UniRx-

おまけ)UniRx+コルーチン

• FromCoroutine<T>を使うと自由なストリームが作れる

カウントダウンタイマの例

Page 140: 未来のプログラミング技術をUnityで -UniRx-

続き)カウントダウンタイマを作るのなら…

• ただしFromCoroutine<T>でカウントダウンタイマを作るよりも

Observable.Timerで作った方がスマート

Page 141: 未来のプログラミング技術をUnityで -UniRx-

おまけ)HttpWebRequest を使ってPUT/DELETE

• WWW/ObservableWWWはGETとPOSTのみサポート

– PUT/DELETEを使いたい場合HttpWebRequestを使う必要がある

• HttpWebRequestをそのまま使うとそこそこツライ

– 同期処理で書くとスレッドを分離する必要がある

– 非同期処理で書くのも結構めんどくさい

Page 142: 未来のプログラミング技術をUnityで -UniRx-

おまけ)UniRxでHttpWebRequest

• HttpWebReqeustでDELETEを叩く

– Observable.Startを使えば別スレッドで実行できる

– それをObserveOnでメインスレッドに戻す

Page 143: 未来のプログラミング技術をUnityで -UniRx-

おまけ)ObserveOn

• 処理を行うスレッドを切り替えるオペレータ

– ObserveOnを使えばスレッド間でのデータのやり取りを考慮する必要

は無い

Page 144: 未来のプログラミング技術をUnityで -UniRx-

応用例)テキスト入力された時に検索サジェストを出す

1. InputFiledにテキストが入力された時に

2. 最後に入力されてから200m秒以上間隔が開いたら

3. GoogleSuggestAPIを叩いて

4. その時のサジェスト結果をTextに表示する

Page 145: 未来のプログラミング技術をUnityで -UniRx-

応用例)テキスト入力された時に検索サジェストを出す