みなさんこんにちは! Unity3dでUniRxに関する記事を書きたいとずっと思っていました。 RXプログラミングの小さな哲学から始めましょう。 たとえば、ゲームを開発する場合、ボタンを作成し、このボタンのクリックイベントを監視し、何らかのコードでそれに応答します。
リアクティブプログラミングはすべて同じで、ステロイドのみです。つまり、すべてのデータストリームを作成できます。 また、それらを見て反応します。 更新、OnCollisionEnter、コルーチン、イベント、マウス入力、キーボード入力、ジョイスティック入力はすべてスレッドです。
私たちを取り巻くのは流れだけです。
さらに、これらのストリームを結合、作成、フィルタリングするための素晴らしい機能セットが提供されています。 これは、「機能的な」魔法が発生する場所です。 ストリームは別のストリームとして使用できます。 複数のスレッドでさえ、別のスレッドのデータとして使用できます。 2つのストリームを結合できます。 ストリームをフィルタリングして、関心のあるイベントのみを含む別のストリームを取得できます。 あるストリームから別のストリームにデータ値をマップできます。
ストリーム
この例では、キーストロークを追跡し、イベントに変換します。
void Start () { Observable.EveryUpdate()
マルチスレッド
この例では、thread-eで重いメソッドを実行し、メインスレッド-eで既に取得した結果を使用しています。
Observable.Start (() => {
したがって、長い計算を実行してネットワークを操作すると非常に便利です。
HttpRequest
ネットワークでの作業について説明しているので、httpリクエストでの作業の小さな例を示します。
var request = ObservableWWW.Get("http://api.duckduckgo.com/?q=habrahabr&format=json") .Subscribe(x => {
コルーチンここでは、3つのコルーチンを同時に起動し、ストリームに変換して、1つのストリームに結合します。 次に、このストリームにサブスクライブします。
void Start () { Observable.WhenAll (
コルーチンを1つずつ実行することもできます
Observable.FromCoroutine (AsyncA)
非同期シーンの読み込み
SceneManager.LoadSceneAsync ("HeavyScene")
ロード画面で簡単なシーンを最初にロードし、既にロードしている場合、それを使用することは非常に便利です
重いシーンを非同期でロードすると、ロード画面のアニメーションはフリーズしません。
非同期リソースの読み込み
void Start () { SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer> (); Resources.LoadAsync<Sprite> ("sprite")
この方法で、プレハブ、テキストリソースなどをロードできます。
また、重いプレハブやスプライトをロードする必要がある場合に使用すると非常に便利です。ゲームのロード中にゲームの速度が低下しないため、ゲームの応答性が向上します。
タイマー
void Start () { Observable.Timer (System.TimeSpan.FromSeconds (3))
メッセージブローカー
UniRxのメッセージブローカーは、RXベースのパブリッシャー/サブスクライバーシステムであり、タイプでフィルターされています。
パブリッシャー-サブスクライバー(英語のパブリッシャー-サブスクライバーまたは英語のパブ/サブ)-パブリッシャー(英語のパブリッシャー)と呼ばれるメッセージ送信者が、サブスクライバー(英語のサブスクライバー)にメッセージを送信するためのプログラムコードに直接結び付けられていないメッセージ送信用の動作デザインテンプレート。 代わりに、メッセージはクラスに分割され、サブスクライバーについての情報は含まれていません。 同様に、サブスクライバーは特定のパブリッシャーから抽象化された1つ以上のクラスのメッセージを処理します。
ゲームを開発するときに、直接アクセスできないコンポーネントのメソッドを呼び出す必要がある場合があります。 もちろん、DIまたはシングルトンを使用できますが、すべては特定のケースに依存します。 そして、これは多くのオブジェクトでメソッドを呼び出す必要があるとき、または単にMessageBrokerを使用したいときです。
上記で説明したように、フィルタリングはタイプごとに行われ、各サブスクライバーのクラスの束を作成しないように、フィールドが含まれるMessageBaseクラスを作成しました。 System.Object)キャストする必要があるデータを転送します。 また、このクラスには、MessageBaseを作成して返す静的メソッド(Create)があります。
MessageBase
public class MessageBase { public MonoBehaviour sender {get; private set;}
また、すべてのメッセージのIDが現在保存されているデバッグを簡素化するために、ServiceShareDataクラスも作成しました。 これは、開発プロセス中にメッセージリークやコードの混乱が生じないようにするために必要です。
ServiceShareData
public class ServiceShareData { public const int MSG_ATTACK = 1001; }
メッセージ送信の例
MessageBroker.Default .Publish (MessageBase.Create ( this,
Publishメソッドは、タイプでフィルタリングされたクラスをディスパッチします。 ここでは、送信者this、フィルタリングされるID、および理論上は何でもよいデータの最後にMessageBaseを送信します。
メッセージ受け入れの例
public CompositeDisposable disposables; void OnEnable () { disposables = new CompositeDisposable(); MessageBroker.Default .Receive<MessageBase>()
Receiveメソッドには、タイプごとの汎用フィルターがあります。 すでにメッセージIDでフィルタリングしている場所。 サブスクライバー(メッセージの受信者)は、メッセージのIDに応じてデータをキャストすることを理解することが重要です。
MVP
古典的なMVPパターンの例。 Modelは、データの保存およびデータの逆シリアル化などのシリアル化に役立ちます。 このデータを表示するために表示します。 さて、ビジネスロジックを担当するプレゼンター。
モデル
public class SomeModel { public ReactiveProperty<int> count { get; private set; } public SomeModel () { count = new ReactiveProperty<int> (0);
ご覧のとおり、この場合はReactivePropertyがあります。これは、サブスクライブして対応できる変更に対するステロイドのintです。
表示する
public class SomeView : MonoBehaviour { public Text someText; public Button someButton; public void RenderCount (int count) {
ビューにはテキストとボタンがあります。 ボタンをアニメーション化し、データを表示する方法も同様です。 アニメーションの場合、DoTweenアセットが使用されます。
発表者
public class SomePresenter : MonoBehaviour { public SomeView someView;
ご覧のとおり、まず変更のみを描画するために、reactivePropertyの変更をサブスクライブします。
次に、ボタンにサブスクライブします。クリックすると、OnClickメソッドが呼び出され、このボタンのinstanceId(Unity3dがその一意性を保証します)をプッシュします。
OnClickでは、このintanceIdのチェックがあり、クリックするとカウント(reactiveProperty)を増やしてボタンをアニメーション化します。
質問やコメントをお待ちしております。
読むことをお勧めします:
github.com/neuecc/UniRxgist.github.com/staltz/868e7e9bc2a7b8c1f754www.reactivemanifesto.orgソースコード