Recommended
PDF
ピクサー USD 入門 新たなコンテンツパイプラインを構築する
PDF
Unity開発で使える設計の話+Zenjectの紹介
PDF
PDF
Unityでパフォーマンスの良いUIを作る為のTips
PDF
PPTX
PDF
聖剣伝説3でのUE4利用事例の紹介~Making of Mana | UNREAL FEST EXTREME 2020 WINTER
PDF
【Unity】より良い表現のためのライティング戦略
PDF
個人製作インディーゲーム”ジラフとアンニカ” のUE4 制作事例紹介 | UNREAL FEST EXTREME 2020 WINTER
PDF
出張ヒストリア ブループリントを書くにあたって大切なこと
PDF
PDF
PDF
【Unity道場 2017】PlayMakerによる初めてのUnityプログラミング
PDF
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
PDF
Unreal Engine 4.27 ノンゲーム向け新機能まとめ
PPTX
[CEDEC2018] UE4アニメーションシステム総おさらい
PPTX
PDF
猫でも分かるUE4.22から入ったSubsystem
PDF
「Press Button, Drink Coffee」 UE4における ビルドパイプラインとメンテナンスの全体像
PPTX
UE4 MultiPlayer Online Deep Dive: 実践編1 (Byking様ご講演) #UE4DD
PDF
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
PPTX
PDF
Unityで始めるバージョン管理 Git LFS 入門編
PDF
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~
PDF
UE4 MultiPlayer Online Deep Dive 実践編2 (ソレイユ株式会社様ご講演) #UE4DD
PDF
PDF
【Unity】Scriptable object 入門と活用例
PPTX
[CEDEC2018] UE4で多数のキャラクターを生かすためのテクニック
PPTX
PDF
More Related Content
PDF
ピクサー USD 入門 新たなコンテンツパイプラインを構築する
PDF
Unity開発で使える設計の話+Zenjectの紹介
PDF
PDF
Unityでパフォーマンスの良いUIを作る為のTips
PDF
PPTX
PDF
聖剣伝説3でのUE4利用事例の紹介~Making of Mana | UNREAL FEST EXTREME 2020 WINTER
PDF
【Unity】より良い表現のためのライティング戦略
What's hot
PDF
個人製作インディーゲーム”ジラフとアンニカ” のUE4 制作事例紹介 | UNREAL FEST EXTREME 2020 WINTER
PDF
出張ヒストリア ブループリントを書くにあたって大切なこと
PDF
PDF
PDF
【Unity道場 2017】PlayMakerによる初めてのUnityプログラミング
PDF
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
PDF
Unreal Engine 4.27 ノンゲーム向け新機能まとめ
PPTX
[CEDEC2018] UE4アニメーションシステム総おさらい
PPTX
PDF
猫でも分かるUE4.22から入ったSubsystem
PDF
「Press Button, Drink Coffee」 UE4における ビルドパイプラインとメンテナンスの全体像
PPTX
UE4 MultiPlayer Online Deep Dive: 実践編1 (Byking様ご講演) #UE4DD
PDF
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
PPTX
PDF
Unityで始めるバージョン管理 Git LFS 入門編
PDF
シェーダーを活用した3Dライブ演出のアップデート ~『ラブライブ!スクールアイドルフェスティバル ALL STARS』(スクスタ)の開発事例~
PDF
UE4 MultiPlayer Online Deep Dive 実践編2 (ソレイユ株式会社様ご講演) #UE4DD
PDF
PDF
【Unity】Scriptable object 入門と活用例
PPTX
[CEDEC2018] UE4で多数のキャラクターを生かすためのテクニック
Similar to UniRxことはじめ
PPTX
PDF
PDF
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
PDF
PPTX
未来のプログラミング技術をUnityで -UniRx-
PPTX
UniRx勉強会 reactive extensions inside(公開用)
PDF
UniRx - Reactive Extensions for Unity
PDF
PDF
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
PDF
PDF
Reactive extensions入門v0.1
PDF
PDF
PDF
PDF
Prism + ReactiveProperty入門
PPTX
PDF
PDF
PPTX
PDF
Xamarin で ReactiveUI を使ってみた
UniRxことはじめ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Rxではない実装
class Hoge : MonoBehaviour {
public int Count { get; private set; }
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown ) {
++Count;
}
}
}
19. Rxではない実装
class Hoge : MonoBehaviour {
public int Count { get; private set; }
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown ) {
++Count;
}
}
}
20. Rxでの実装
class Hoge : MonoBehaviour {
public int Count { get; private set; }
public void Start() {
IObservable<Unit> mouseDown = gameObject.OnMouseDownAsObservable();
mouseDown.Subscribe( _ => ++Count );
}
}
21. Rxでの実装
class Hoge : MonoBehaviour {
public int Count { get; private set; }
public void Start() {
IObservable<Unit> mouseDown = gameObject.OnMouseDownAsObservable();
// ↑マウスが押された時にUnitが流れてくるメッセージストリームを取得
mouseDown.Subscribe( _ => ++Count );
}
}
22. Rxでの実装
class Hoge : MonoBehaviour {
public int Count { get; private set; }
public void Start() {
IObservable<Unit> mouseDown = gameObject.OnMouseDownAsObservable();
// ↑Unitとは何でもないものを表す(後々出てくるストリームの合成で型をあわせる為に必要)
mouseDown.Subscribe( _ => ++Count );
}
}
23. Rxでの実装
class Hoge : MonoBehaviour {
public int Count { get; private set; }
public void Start() {
IObservable<Unit> mouseDown = gameObject.OnMouseDownAsObservable();
// ↓イベントが流れてきたら処理を実行する
mouseDown.Subscribe( _ => ++Count );
}
}
24. 25. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now;
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown && nextCountUp <= DateTime.Now ) {
++Count;
nextCountUp = DateTime.Now + countUpIntervalSpan;
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
}
}
26. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now; // 次回カウントアップまでの秒数管理.
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown && nextCountUp <= DateTime.Now ) {
++Count;
nextCountUp = DateTime.Now + countUpIntervalSpan;
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
}
}
27. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now;
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0); // 押されているかどうかの判定.
if ( mouseDown && nextCountUp <= DateTime.Now ) {
++Count;
nextCountUp = DateTime.Now + countUpIntervalSpan;
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
}
}
28. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now;
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown && nextCountUp <= DateTime.Now ) { // 間隔の制御.
++Count;
nextCountUp = DateTime.Now + countUpIntervalSpan;
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
}
}
29. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now;
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown && nextCountUp <= DateTime.Now ) {
++Count; // 目的の処理.
nextCountUp = DateTime.Now + countUpIntervalSpan;
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
}
}
30. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now;
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown && nextCountUp <= DateTime.Now ) {
++Count;
nextCountUp = DateTime.Now + countUpIntervalSpan; // 次のカウントアップ時間の予約.
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
}
}
31. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime nextCountUp = DateTime.Now;
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown && nextCountUp <= DateTime.Now ) {
++Count;
nextCountUp = DateTime.Now + countUpIntervalSpan;
}
else if ( false == mouseDown ) { nextCountUp = DateTime.Now; }
} // ↑離された場合のカウントアップ予約解除処理
}
32. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count );
}
}
33. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() { // ↓マウスの状態ストリーム.
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count );
}
}
34. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown // ←マウスが押されたら.
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count );
}
}
35. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
// ↑一定周期でメッセージが流れるストリームに切り換えて.
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count );
}
}
36. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
// ↓マウスが離されるまで.
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count );
}
}
37. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
// ↓マウスが離されたらもう一度押されるのを待つ.
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count );
}
}
38. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpIntervalSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown
.SelectMany( _ => Observable.Interval( countUpIntervalSpan ) )
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count ); // ←処理.
}
}
39. 40. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime? beginCountUp = null;
private TimeSpan countUpHoldSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown ) {
if ( beginCountUp.HasValue ) {
if ( beginCountUp <= DateTime.Now ) { /* 一定間隔でカウントアップする処理 */ }
} else {
beginCountUp = DateTime.Now + countUpHoldSpan;
}
} else { beginCountUp = null; }
}
41. Rxではない実装
class Hoge : MonoBehaviour {
private DateTime? beginCountUp = null;
private TimeSpan countUpHoldSpan = TimeSpan.FromSeconds( 1 );
public void Update() {
bool mouseDown = Input.GetMouseButtonDown(0);
if ( mouseDown ) {
if ( beginCountUp.HasValue ) {
if ( beginCountUp <= DateTime.Now ) { /* 一定間隔でカウントアップする処理 */ }
} else {
beginCountUp = DateTime.Now + countUpHoldSpan;
}
} else { beginCountUp = null; }
}
42. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpHoldSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown.Delay( countUpHoldSpan )
.SelectMany( _ => Observable.Interval( TimeSpan.FromSeconds( 1 ) ) )
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count ); // ←処理.
}
}
43. Rxでの実装
class Hoge : MonoBehaviour {
private TimeSpan countUpHoldSpan = TimeSpan.FromSeconds( 1 );
public void Start() {
var mouseDown = gameObject.OnMouseDownAsObservable();
var mouseUp = gameObject.OnMouseUpAsObservable();
mouseDown.Delay( countUpHoldSpan )
.SelectMany( _ => Observable.Interval( TimeSpan.FromSeconds( 1 ) ) )
.TakeUntil( mouseUp ).RepeatUntilDestroy( this )
.Subscribe( _ => ++Count ); // ←処理.
}
}
44. 45. 46. 47. 48. 49. SkipUntil/TakeUntilの動き
var s = new Subject<int>();
s.SkipUntil( x => ( 0 == ( x % 2 ) )
.TakeUntil( x => ( 0 != ( x % 2 ) )
.Subscribe( x => Debug.Log(x) );
s.OnNext( 1 );
s.OnNext( 2 );
s.OnNext( 3 );
s.OnNext( 4 );
結果 :
50. 51. 52. SkipUntil/TakeUntilの動き
var s = new Subject<int>();
s.SkipUntil( x => ( 0 == ( x % 2 ) )
.TakeUntil( x => ( 0 != ( x % 2 ) )
.Subscribe( x => Debug.Log(x) );
s.OnNext( 1 );
s.OnNext( 2 );
s.OnNext( 3 );
s.OnNext( 4 );
結果 :
2で割り切れるまで読み飛ばす
2で割り切れる間は続ける
2だけが出力?
53. SkipUntil/TakeUntilの動き
var s = new Subject<int>();
s.SkipUntil( x => ( 0 == ( x % 2 ) )
.TakeUntil( x => ( 0 != ( x % 2 ) )
.Subscribe( x => Debug.Log(x) );
s.OnNext( 1 );
s.OnNext( 2 );
s.OnNext( 3 );
s.OnNext( 4 );
結果 :
出力なし
54. 55. SkipUntil/TakeUntilの動き
var s = new Subject<int>();
s.SkipUntil( x => ( 0 == ( x % 2 ) )
.TakeUntil( x => ( 0 != ( x % 2 ) )
.Subscribe( x => Debug.Log(x) );
s.OnNext( 1 );
s.OnNext( 2 );
s.OnNext( 3 );
s.OnNext( 4 );
理由 :
SkipUntilで待っている間も
TakeUntilの条件は
常にチェックされている。
56. 57. 58. 59. 60. 61. 62. AddTo
public static IDisposable AddTo(this IDisposable disposable, GameObject
gameObject);
public static IDisposable AddTo(this IDisposable disposable, Component
gameObjectComponent)
public static IDisposable AddTo(this IDisposable disposable,
ICollection<IDisposable> container, GameObject gameObject)
public static IDisposable AddTo(this IDisposable disposable,
ICollection<IDisposable> container, Component gameObjectComponent)
public static T AddTo<T>(this T disposable, ICollection<IDisposable>
container)
63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. public event Action SomeEvent;
があった場合、
Observable.FromEvent(
h => SomeEvent += h, h => SomeEvent -= h
)
を行えばストリームに変換できます。
イベントをストリームに変換する
92. public delegate void SomeEvent();
public SomeEvent someEvent;
があった場合、
Observable.FromEvent<SomeEvent>(
h => ()=>h(), h => SomeEvent += h, h => SomeEvent -= h
) // デリゲートに変換
を行えばストリームに変換できます。
デリゲートをストリームに変換する
93. var s = new Subject<T>();
を定義して
s.OnNext(...);
で配信することができます。
s.OnCompleted();
でストリームの終了ができます。
Subjectでメッセージを配信
94. 95. 96. Rxではない実装
private int? previousValue = null;
void Update() {
var value = 監視したい値;
if ( previousValue.HasValue && previousValue.Value != value ) {
/* 処理 */
}
previousValue = value;
}
値の監視
97. 98. var rp = new ReactiveProperty<T>(初期値);
があれば
IObservable<T> rpAsObservable { get { return rp; } }
で配信することができます。
配信タイミングは rp.Value = 値; などで値が書き換わった時。
ReactiveProperty<T>
99. var rp = new ReactiveProperty<T>(初期値);
また、ストリームとして以外でも
rp.Value でその時点での値が取得できます。
ReactiveProperty<T>
100. private ReactiveProperty<T> ValueProperty;
public IObservable<T> ValueAsObservable {
get { return ValueProperty; }
}
public T Value {
get { return ValueProperty.Value; }
private set { ValueProperty.Value = value; }
}
は鉄板だと思います!ぜひスニペットに登録を!
ReactiveProperty<T>
101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. UniRxの作者様のブログ
株式会社グラニ 河合 宜文 様 @neuecc
http://neue.cc/category/programming/rx
その他
http://blog.xin9le.net/entry/rx-intro
http://qiita.com/toRisouP
その他お勧めな解説サイト
112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. Editor's Notes #12 ご覧のように様々な言語でサポートされています #20 マウスの状態を取得して、カウントアップ #22 メッセージストリームを取得
Unitについては次のページ #42 コメントアウト部分に先ほどまでの処理が入ります。
これだけの追加実装が必要です。 #44 Delayというオペレータだけで実現可能です。 #50 Subjectというものがありますが、
これはメッセージを流すものです。
詳しくは後で説明するので
一旦そういうものとして認識しておいてください。 #53 1,2,3,4と流した時に2だけが出力されるかとおもいきや・・・ #70 関数型云々については #71 関数型云々については #72 関数型云々については宗教戦争になるので
納得出来ない方は流していただけるとありがたいです。 #91 ここでは細かい構文については触れません。
細かい構文については別途ググってください。 #106 Rx以外でも使えます。