$30 off During Our Annual Pro Sale. View Details »

UniRx とか Reactive Property とか

UniRx とか Reactive Property とか

「Unity のための C# 勉強会」での発表資料です (セッション タイトル決めるのをすっかり忘れていて、発表 5 分前に適当に埋めた!)。
・UniRx の紹介と、社内で実施したハンズオンをベースに簡単な解説
・Reactive Property を使った弊社の取り組み (MV(R)P) について

http://grabacr.net/archives/4711

Grabacr07

March 21, 2015
Tweet

More Decks by Grabacr07

Other Decks in Technology

Transcript

  1. UniRx とか
    ReactiveProperty とか
    2015/03/21 Unity のための C# 勉強会
    Manato KAMEYA (@Grabacr07)

    View Slide

  2. Self Introduction
    Work
    亀谷学人 – 株式会社グラニ
    C# + Unity でソーシャルゲーム開発
    Private
    Microsoft MVP for .NET (Visual C#)
    Room metro Tokyo staff
    (Windows クライアント開発 勉強会)
    Twitter: @Grabacr07
    Facebook: manato.kameya
    Blog: http://grabacr.net/
    最先端の C# をフルに活用
    CTO: @neuecc (UniRx 開発者)

    View Slide

  3. C# Everywhere
    Windows Desktop
    WinForms, WPF
    Windows 8
    Windows Universal apps
    Mac application
    Xamarin.Mac
    Web application
    ASP
    .NET MVC, ASP
    .NET Web API
    Game
    Unity, Paradox, Unreal Engine
    Mobile (iOS, Android, WP)
    MonoTouch, Mono for Android
    Embedded, IoT
    .NET Framework Embedded
    Cloud
    Windows Azure, AWS

    View Slide

  4. Topics
    Unity 製ゲーム開発
    Unity 5.0 + uGUI + UniRx
    社内 UniRx ハンズオン (勉強会? ハッカソン?) 的なことをやったり
    その内容を共有します!
    Goal
    Rx と UniRx を知ってもらいたい!

    View Slide

  5. Reactive Extensions (Rx)
    LINQ to Events
    LINQ が扱うデータ ソースの概念を「イベント」に広げる
    LINQ to Objects
    • Array
    • List
    • Stream
    • etc…
    LINQ to XML
    • XML
    • JSON
    LINQ to Events
    • User (input)
    • Sensor device (input)
    • Web service (notification)
    • etc...
    あらゆるものがイベント

    View Slide

  6. イベントを、時間軸に乗ったシーケンスと見なす
    イベント ストリームにメッセージが流れてくる
    LINQ で使える時属性魔法 (Where でフィルター、Select で射影 (変換)、etc…)
    時間をベースにした処理 (計測、非同期、イベントの合成、etc…)
    Event stream
    Reactive Extensions (Rx)
    IObservable
    onClick
    time
    onClick (3 秒後)
    onClick (5 秒後)
    onClick (1 秒後)

    View Slide

  7. Reactive Extensions (Rx)
    for .NET
    Microsoft の DevLabs で 2009 年に公開されたプロジェクト
    Across Languages
    その後、多くの言語向けに移植されていく
    RxJS, bacon.js, RxJava, RxScala, ReactiveCocoa, Rx.rb, etc…
    つまり今アツい分野!

    View Slide

  8. UniRx
    Reactive Extensions for Unity
    https://github.com/neuecc/UniRx
    弊社 CTO、@neuecc が Unity 向けに移植した Rx
    オレオレライブラリではない (重要!)
    言語は違っても、概念は同じ
    つまり、覚えておけば他の言語でも使える!

    View Slide

  9. Study
    勉強用の資料 & 解説ページ等
    Reactive Programming by UniRx for Asynchronous & Event Processing
    開発者、弊社 CTO @neuecc による Rx + UniRx 解説資料
    Rx とは? なぜ Unity で Rx が良いのか? というのが解ります
    http://www.slideshare.net/neuecc/reactive-programming-by-unirxfor-asynchronous-event-processing
    未来のプログラミング技術をUnityで ~UniRx~
    @toRisouP 氏による Rx + UniRx 解説資料
    サンプル・図解が多く、めっちゃわかりやすい (おすすめ!)
    http://www.slideshare.net/torisoup/unity-unirx

    View Slide

  10. Study
    ReactiveX
    Rx の概念や、Observable、各 Operator の動作等を図解付きで詳しく解説したサイト (英語)
    http://reactivex.io/
    Reactive extensions入門
    @okazuki 氏による Rx 解説資料
    http://www.slideshare.net/okazuki0130/reactive-extensionsv01
    Rx入門
    @xin9le 氏による Rx 解説ページ
    http://blog.xin9le.net/entry/rx-intro

    View Slide

  11. Reactive Extensions + Unity + uGUI (Unity UI)
    UniRx

    View Slide

  12. Enable / Disable
    ストリームの射影
    (変換と言った方がわかりやすいかも)
    入力ボックスが空だったら検索ボタンを押せなくする UI

    View Slide

  13. Enable / Disable
    ストリームの射影
    public class EnableDisablePresenter : MonoBehaviour
    {
    public Button SearchButton;
    public InputField WordInput;
    private void Start()
    {
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .SubscribeToInteractable(this.SearchButton);
    }
    }

    View Slide

  14. Enable / Disable
    ストリームの射影
    public class EnableDisablePresenter : MonoBehaviour
    {
    public Button SearchButton;
    public InputField WordInput;
    private void Start()
    {
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .SubscribeToInteractable(this.SearchButton);
    }
    }
    OnValueChangeAsObservable() で
    UniRx のイベント ストリーム (IObseravable) にする

    View Slide

  15. Enable / Disable
    ストリームの射影
    public class EnableDisablePresenter : MonoBehaviour
    {
    public Button SearchButton;
    public InputField WordInput;
    private void Start()
    {
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .SubscribeToInteractable(this.SearchButton);
    }
    }
    OnValueChangeAsObservable() で
    UniRx のイベント ストリーム (IObseravable) にする
    Select() で射影 (というか変換)
    string から bool へ (空文字なら false、それ以外は true)
    IObservable な On/Off ストリームにする

    View Slide

  16. Enable / Disable
    ストリームの射影
    public class EnableDisablePresenter : MonoBehaviour
    {
    public Button SearchButton;
    public InputField WordInput;
    private void Start()
    {
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .SubscribeToInteractable(this.SearchButton);
    }
    }
    OnValueChangeAsObservable() で
    UniRx のイベント ストリーム (IObseravable) にする
    Select() で射影 (というか変換)
    string から bool へ (空文字なら false、それ以外は true)
    IObservable な On/Off ストリームにする
    Subscribe() でストリームの購読
    On/Off ストリームからの interactable 設定は
    SubscribeToInteractable() が便利

    View Slide

  17. ストリームの射影
    Enable / Disable
    OnValueChangeAsObservable()
    InputField (WordInput) の値が変更されると配信
    Select(x => !string.IsNullOrEmpty(x))
    string を bool に射影
    false
    Subscribe()
    イベント購読
    true false
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .SubscribeToInteractable(this.SearchButton);
    (空文字)
    IObservable から IObservable へ
    True/False ストリーム (= On/Off ストリーム) に変換
    "h"
    true
    "ho" "hog"
    true
    (空文字)
    true
    "foo"

    View Slide

  18. Enable / Disable
    ストリームのフィルター
    public class EnableDisablePresenter : MonoBehaviour
    {
    public Button SearchButton;
    public InputField WordInput;
    private void Start()
    {
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .DistinctUntilChanged()
    .SubscribeToInteractable(this.SearchButton);
    }
    }

    View Slide

  19. Enable / Disable
    ストリームのフィルター
    public class EnableDisablePresenter : MonoBehaviour
    {
    public Button SearchButton;
    public InputField WordInput;
    private void Start()
    {
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .DistinctUntilChanged()
    .SubscribeToInteractable(this.SearchButton);
    }
    }
    DistinctUntilChanged() でフィルター
    同じ値が連続している場合は無視する

    View Slide

  20. ストリームのフィルター
    Enable / Disable
    OnValueChangeAsObservable()
    InputField (WordInput) の値が変更されると配信
    Select(x => !string.IsNullOrEmpty(x))
    string を bool に射影
    false
    Subscribe()
    イベント購読
    true false
    this.WordInput
    .OnValueChangeAsObservable()
    .Select(x => !string.IsNullOrEmpty(x))
    .DistinctUntilChanged()
    .SubscribeToInteractable(this.SearchButton);
    (空文字) "h"
    true
    "ho" "hog"
    true
    (空文字)
    true
    "foo"
    DistinctUntilChanged()
    同じ値が連続している場合は無視する
    false true false true
    連続した値は配信されない

    View Slide

  21. Simple Calculation
    ストリームの結合
    シンプルな足し算をする UI

    View Slide

  22. Simple Calculation
    ストリームの結合
    public class CalculatorPresenter : MonoBehaviour
    {
    public InputField Left;
    public InputField Right;
    public Text Result;
    void Start()
    {
    var left = this.Left
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    var right = this.Right
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    left.CombineLatest(right, (l, r) => l + r)
    .SubscribeToText(this.Result);
    }
    }

    View Slide

  23. Simple Calculation
    ストリームの結合
    public class CalculatorPresenter : MonoBehaviour
    {
    public InputField Left;
    public InputField Right;
    public Text Result;
    void Start()
    {
    var left = this.Left
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    var right = this.Right
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    left.CombineLatest(right, (l, r) => l + r)
    .SubscribeToText(this.Result);
    }
    }
    OnValueChangeAsObservable() で
    UniRx のイベント ストリーム (IObseravable) にする

    View Slide

  24. Simple Calculation
    ストリームの結合
    public class CalculatorPresenter : MonoBehaviour
    {
    public InputField Left;
    public InputField Right;
    public Text Result;
    void Start()
    {
    var left = this.Left
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    var right = this.Right
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    left.CombineLatest(right, (l, r) => l + r)
    .SubscribeToText(this.Result);
    }
    }
    OnValueChangeAsObservable() で
    UniRx のイベント ストリーム (IObseravable) にする
    InputField の値は文字列 (string) で配信されるので
    整数値 (int) に変換する

    View Slide

  25. Simple Calculation
    ストリームの結合
    public class CalculatorPresenter : MonoBehaviour
    {
    public InputField Left;
    public InputField Right;
    public Text Result;
    void Start()
    {
    var left = this.Left
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    var right = this.Right
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    left.CombineLatest(right, (l, r) => l + r)
    .SubscribeToText(this.Result);
    }
    }
    OnValueChangeAsObservable() で
    UniRx のイベント ストリーム (IObseravable) にする
    CombineLatest() で 2 つの IObservable を結合
    left と right いずれかのイベントが配信されたとき、
    互いの最後の値を使って 1 つのイベントを配信する
    (ただし、両方揃ってからしか配信されない)
    InputField の値は文字列 (string) で配信されるので
    整数値 (int) に変換する

    View Slide

  26. ストリームの結合
    Left
    Simple Calculation
    OnValueChangeAsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "0"
    0
    var left = this.Left
    .OnValueChangeAsObservable() // Left (InputField) の値が変更されるとイベント配信
    .Select(x => int.Parse(x)); // 信された入力値 (x) は文字列なので、整数値に変換
    "12"
    12
    "7"
    7
    ユーザーのテキスト入力

    View Slide

  27. ストリームの結合
    Left
    Simple Calculation
    OnValueChangeAsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "0"
    0
    Right
    OnValueChangeAsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "25"
    25
    "12"
    12
    "7"
    7
    "0"
    0
    "6"
    6
    "3"
    3
    CombineLatest(left, right)
    互いの最後の値を結合して配信
    7+3
    0+0 12+0 12+6 12+3 7+25

    View Slide

  28. ストリームの結合
    Left
    Simple Calculation
    OnValueChangeAsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "0"
    0
    Right
    OnValueChangeAsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "25"
    25
    "12"
    12
    "7"
    7
    "0"
    0
    "6"
    6
    "3"
    3
    CombineLatest(left, right)
    互いの最後の値を結合して配信
    7+3
    0+0 12+0 12+6 12+3 7+25
    CombineLatest
    たとえば left ストリームから 12 が配信されたとき、
    left の最新値 12 と right の最新値 0 を Combine する

    View Slide

  29. uGUI Integration
    UnityEvent をお手軽ハンドリング
    Button.OnClickAsObservable
    Slider.OnValueChangeAsObservable
    Toggle.OnValueChangeAsObservable
    InputField.OnEndEditAsObservable
    IObservable.SubscribeToText
    IObservable.SubscribeToInteractable
    this.MyButton
    .OnClickAsObservable()
    .Subscribe(_ => Debug.Log("clicked!"));
    this.MyInput
    .OnEndEditAsObservable()
    .SubscribeToText(this.MyText);
    文字列ストリームや On/Off ストリームを
    Subscribe して UI に反映 (頻出パターン)
    UnityEvent を IObservable の
    イベント ストリームにする

    View Slide

  30. UnityEvent to IObservable
    OnValueChangeAsObservable() と
    onValueChange.AsObservable() は何が違うのか?
    uGUI Integration
    var left = this.Left
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    // どっちがいいの?
    var left = this.Left.onValueChange
    .AsObservable()
    .Select(x => int.Parse(x));

    View Slide

  31. ストリームの結合 (onValueChange の場合)
    Left
    Simple Calculation
    onValueChange.AsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    Right
    onValueChange.AsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "25"
    25
    "12"
    12
    "7"
    7
    "6"
    6
    "3"
    3
    CombineLatest(left, right)
    互いの最後の値を結合して配信
    7+3
    12+6 12+3 7+25
    "0"
    0
    "0"
    0
    0+0 12+0

    View Slide

  32. ストリームの結合 (onValueChange の場合)
    Left
    Simple Calculation
    onValueChange.AsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    Right
    onValueChange.AsObservable()
    InputField の値が変更されると配信
    Select(x => int.Parse(x))
    string を int に変換
    "25"
    25
    "12"
    12
    "7"
    7
    "6"
    6
    "3"
    3
    CombineLatest(left, right)
    互いの最後の値を結合して配信
    7+3
    12+6 12+3 7+25
    "0"
    0
    "0"
    0
    0+0 12+0
    初期値が配信されない
    両方揃うまで配信されない
    (最初の配信がこのタイミングになる)

    View Slide

  33. UnityEvent to IObservable
    OnValueChangeAsObservable() と
    onValueChange.AsObservable() は何が違うのか?
    uGUI Integration
    var left = this.Left
    .OnValueChangeAsObservable()
    .Select(x => int.Parse(x));
    // どっちがいいの?
    var left = this.Left.onValueChange
    .AsObservable()
    .Select(x => int.Parse(x));
    Control.XxxAsObservable() ったら最強ね!
    • イベント ストリームをお手軽生成
    • UnityEvent.AsObservable() と違い、初期値を供給
    → 宣言的な UI を作る上で重要な機能
    初期値が供給されるかどうかの違いがある

    View Slide

  34. というものを試験運用中
    MV(R)P Pattern

    View Slide

  35. Model-View-(Reactive)Presenter
    Unity における M-V-○○ パターン
    View = Scene, Hierarchy
    どうやって View を更新するか?
    Passive View
    ???
    Model
    updates view
    state-change
    events
    user events
    update model

    View Slide

  36. Model-View-(Reactive)Presenter
    Unity における M-V-○○ パターン
    View = Scene, Hierarchy
    どうやって View を更新するか?
    View (XAML)
    ViewModel
    Model
    例えば XAML Platform なら

    View Slide

  37. Model-View-(Reactive)Presenter
    Unity における M-V-○○ パターン
    View = Scene, Hierarchy
    どうやって View を更新するか?
    View (XAML)
    ViewModel
    Model
    INotifyPropertyCanged
    INotifyPropertyCanged
    例えば XAML Platform なら DataBinding system
    + INotifyProperyChanged をベースとした通知基盤がある

    ICommand
    method call

    View Slide

  38. Model-View-(Reactive)Presenter
    Unity における M-V-○○ パターン
    View = Scene, Hierarchy
    どうやって View を更新するか?
    Unity にデータ バインディングは無い
    複雑だし、パフォーマンス的にも作りたくない
    View (XAML)
    ViewModel
    Model
    INotifyPropertyCanged
    INotifyPropertyCanged
    例えば XAML Platform なら DataBinding system
    + INotifyProperyChanged をベースとした通知基盤がある

    ICommand
    method call

    View Slide

  39. Reactive Property
    通知可能なプロパティ
    値の変更を IObservable で配信できる
    public class Enemy
    {
    public ReactiveProperty CurrentHp { get; private set; }
    public ReactiveProperty IsDead { get; private set; }
    public Enemy(int initialHp)
    {
    // Declarative Property
    this.CurrentHp = new ReactiveProperty(initialHp);
    this.IsDead = this.CurrentHp.Select(x => x <= 0).ToReactiveProperty();
    }
    }
    コンストラクターで宣言的に書く
    IsDead がどういう動作をするか
    ( = CurrentHP がどう作用するか)
    見て一発でわかりますよね?

    View Slide

  40. Model-View-(Reactive)Presenter
    Unity における M-V-○○ パターン
    View = Scene, Hierarchy
    どうやって View を更新するか?
    UniRx が可能にする MV(R)P
    View を操作する (Reactive)Presenter
    バインディングがない以上、誰かが View を知らなければならない
    ReactiveProperty による通知
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model

    View Slide

  41. Model-View-(Reactive)Presenter
    IObservable で繋がる M-V-(R)P
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model
    UIControl.XxxAsObservable
    UnityEvent.AsObservable
    ObservableEventTrigger
    Subscribe
    ToReactiveProperty
    ReactiveProperty
    Subscribe
    SubscribeToText
    SubscribeToInteractable

    View Slide

  42. Count up / down
    UniRx (+ Reactive Property) を使って MV(R)P
    …の、極小サンプルとしてひとつ
    ・Up ボタンで数値 + 1
    ・Down ボタンで数値 -1

    View Slide

  43. Count up / down
    UniRx (+ Reactive Property) を使って MV(R)P
    // Presenter
    public class UpDownPresenter : MonoBehaviour
    {
    // View
    public Button UpButton;
    public Button DownButton;
    public Text ScoreText;
    // Model
    [InspectorDisplay]
    public IntReactiveProperty Score;
    private void Start()
    {
    this.UpButton.OnClickAsObservable().Subscribe(_ => this.Score.Value++);
    this.DownButton.OnClickAsObservable().Subscribe(_ => this.Score.Value--);
    this.Score.SubscribeToText(this.ScoreText);
    }
    }
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model

    View Slide

  44. Count up / down
    UniRx (+ Reactive Property) を使って MV(R)P
    // Presenter
    public class UpDownPresenter : MonoBehaviour
    {
    // View
    public Button UpButton;
    public Button DownButton;
    public Text ScoreText;
    // Model
    [InspectorDisplay]
    public IntReactiveProperty Score;
    private void Start()
    {
    this.UpButton.OnClickAsObservable().Subscribe(_ => this.Score.Value++);
    this.DownButton.OnClickAsObservable().Subscribe(_ => this.Score.Value--);
    this.Score.SubscribeToText(this.ScoreText);
    }
    }
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model
    View から Presenter へ
    user events を配信 (onClick など)

    View Slide

  45. Count up / down
    UniRx (+ Reactive Property) を使って MV(R)P
    // Presenter
    public class UpDownPresenter : MonoBehaviour
    {
    // View
    public Button UpButton;
    public Button DownButton;
    public Text ScoreText;
    // Model
    [InspectorDisplay]
    public IntReactiveProperty Score;
    private void Start()
    {
    this.UpButton.OnClickAsObservable().Subscribe(_ => this.Score.Value++);
    this.DownButton.OnClickAsObservable().Subscribe(_ => this.Score.Value--);
    this.Score.SubscribeToText(this.ScoreText);
    }
    }
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model
    user events を受信した Presenter が
    Model (Score) を update

    View Slide

  46. Count up / down
    UniRx (+ Reactive Property) を使って MV(R)P
    // Presenter
    public class UpDownPresenter : MonoBehaviour
    {
    // View
    public Button UpButton;
    public Button DownButton;
    public Text ScoreText;
    // Model
    [InspectorDisplay]
    public IntReactiveProperty Score;
    private void Start()
    {
    this.UpButton.OnClickAsObservable().Subscribe(_ => this.Score.Value++);
    this.DownButton.OnClickAsObservable().Subscribe(_ => this.Score.Value--);
    this.Score.SubscribeToText(this.ScoreText);
    }
    }
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model
    Model が state-change event を配信
    (ReactiveProperty のイベント ストリーム)

    View Slide

  47. Count up / down
    UniRx (+ Reactive Property) を使って MV(R)P
    // Presenter
    public class UpDownPresenter : MonoBehaviour
    {
    // View
    public Button UpButton;
    public Button DownButton;
    public Text ScoreText;
    // Model
    [InspectorDisplay]
    public IntReactiveProperty Score;
    private void Start()
    {
    this.UpButton.OnClickAsObservable().Subscribe(_ => this.Score.Value++);
    this.DownButton.OnClickAsObservable().Subscribe(_ => this.Score.Value--);
    this.Score.SubscribeToText(this.ScoreText);
    }
    }
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model
    state-change event を受信した Presenter が
    View (ScoreText) を update

    View Slide

  48. Model-View-(Reactive)Presenter
    UniRx (+ Reactive Property) を使って MV(R)P
    というものを試験的に導入し開発しています
    試験的というかもうガッツリ書き始めました
    実際、UniRx にピッタリのパターン
    UniRx readme: https://github.com/neuecc/UniRx#model-view-reactivepresenter-pattern
    是非 Reactive Property と共に導入し、フィードバックして頂けると助かります

    View Slide

  49. Conclusion

    View Slide

  50. UniRx
    UniRx を使ってみてください
    オレオレライブラリではない!
    学習コストは無駄にならない (多言語で使える概念)
    時間や回数の取り扱いがとても楽に
    今日のはほんの触りだけで、本気出した Rx はこんなもんじゃないです!
    Throttle とか Buffer とか、強力な Operator がたくさんあります

    View Slide

  51. Reactive UI
    Script を書く前提の環境
    Inspector での onClick 紐づけ等は無視してます
    (ノンコーディングでやりたい人向け? うちではあんまりやってない…)
    Control.XxxAsObservable ったら最強ね!
    OnClick, OnValueChange, … イベント ストリームお手軽生成
    初期値の供給 (UnityEvent.AsObservable と挙動が違う)

    View Slide

  52. Model-View-(Reactive)Presenter
    IObservable で繋がる M-V-(R)P
    Passive View
    Presenter
    (Supervising Controller)
    Model
    updates view
    state-change
    events
    user events
    update model
    Subscribe
    ToReactiveProperty
    ReactiveProperty
    UIControl.XxxAsObservable
    UnityEvent.AsObservable
    ObservableEventTrigger
    Subscribe
    SubscribeToText
    SubscribeToInteractable

    View Slide

  53. Study
    勉強用の資料 & 解説ページ等 (再掲)
    Reactive Programming by UniRx for Asynchronous & Event Processing
    開発者、弊社 CTO @neuecc による Rx + UniRx 解説資料
    Rx とは? なぜ Unity で Rx が良いのか? というのが解ります
    http://www.slideshare.net/neuecc/reactive-programming-by-unirxfor-asynchronous-event-processing
    未来のプログラミング技術をUnityで ~UniRx~
    @toRisouP 氏による Rx + UniRx 解説資料
    サンプル・図解が多く、めっちゃわかりやすい (おすすめ!)
    http://www.slideshare.net/torisoup/unity-unirx

    View Slide

  54. Study
    ReactiveX
    Rx の概念や、Observable、各 Operator の動作等を図解付きで詳しく解説したサイト (英語)
    http://reactivex.io/
    Reactive extensions入門
    @okazuki 氏による Rx 解説資料
    http://www.slideshare.net/okazuki0130/reactive-extensionsv01
    Rx入門
    @xin9le 氏による Rx 解説ページ
    http://blog.xin9le.net/entry/rx-intro

    View Slide