NDataを使用してUnity3DでMVVMを適用する





こんにちは この投稿では、お気に入りのハブであるUIを数回使用することで生産性を向上させたプラグインについてお話したいと思います。 私が作業しているリンクは、Unity3D + NGUI + NDataです。 必要に応じて、IoC + DIを使用できますが、iOS、Android、WinPhoneで動作する理想的なオプションはまだ見つかっていません。



パターンについては、 こちらまたはこちらをご覧ください 。 このアプローチの利点の1つは、データバインディングです。 ビューをデータに関連付け、このデータが目的のビューに変更されたときに自動的に通知します。



NDataプラグインに関する情報は、Webサイトで見つけることができます。 そして、はい、それは45ドルかかります)



(上の写真では、Unity3d + NGUI + NDataを使用して収集した最後のゲームの1つ)



そうだった



以前は、ユーザーインターフェイスを作成するには、視覚要素のコンポーネント(UILabel、UISprite、UIGridなど)へのリンクを含む1つまたは複数のクラス(GUIManager、MenuView、GameViewetc。)を作成する必要がありました。 さらに、このコンポーネントをどこかで更新する必要がありました。 ビューの私の変更は同じクラスで発生しました。 しかし、次のような同様のアクションが現れ始めました。

-bool型の変数に応じて要素を表示/非表示

-文字列型の変数が変更された場合、テキストを更新します

-条件が満たされている場合(たとえば、Points> 5)、要素を表示/非表示にします



つまり 私はいつも同じタイプのコードを書かなければなりませんでした。 考えが始まり始めた、これをどのように単純化できるか。 そして...



NDataの紹介



私の友人はかつてNDataについて教えてくれました。 そして、彼が2つのコンポーネントと1つのプロパティを使用してグリッド内の要素のリストを埋め、管理することを示したとき、私は驚きました。 これが開発スピードです!



機能のリストを引用します。 サイト:

-ネイティブ.NETフォーマット機能を備えた双方向テキストバインディング(マルチバインディングを含む)。

-スライダーの双方向フロートバインディング。

-UIコントロールの表示状態とチェック状態をコードのプロパティにバインドできる柔軟なバインド(ブール値にバインドされたチェックボックスの双方向モードでも)。

-コード内でアクションをトリガーするボタンのコマンドバインディング。

-リストコントロールを添付アイテムテンプレートプレハブとコード内のアイテムのコレクションに接続するためのアイテムソースバインディング。

-Visual StudioおよびMono Developの通知可能なプロパティとコレクションのコードスニペット。

-バインディング検証用のエディタースクリプト。



ご覧のとおり、ほとんどすべてのアプリケーションは、このバインダーのリストに基づいて構築できます。 実際、私は最近やっています。



すべてが本当にスムーズであるとは限りません。 プラグインをインポートした後、エラーが発生し、修正する必要があります。 プラグインのインストール方法、コンポーネントの操作方法などをvidos記録しました



バインディングとは何ですか? これは通常のMonoBehaviourスクリプトで、指定されたUI要素をリフレクションを通じてコード内の変数に関連付けます。 変数は特別なジェネリック型(たとえば、Property)で作成され、この変数の変更について通知する機能が追加されます。





(変数のテキストをUILabelのテキストにバインド)





(ボタンを押すイベントをメソッドにバインド)



グリッドの例:

1.グリッド/テーブルに詰め込みたいビューのコレクション(+ビュー自体)を作成します

private readonly EZData.Collection<ProductItemContext> _privateItems = new EZData.Collection<ProductItemContext>(false); public EZData.Collection<ProductItemContext> Items { get { return _privateItems; } }
      
      







2.バインディングを介してテーブル/グリッドにバインドし、テーブル要素のビューをアタッチするプレハブを割り当てます。





3.コードのどこかで、コレクション(Add、Remove、Clear、GetItem(n))を操作し、すべての変更が画面に表示されます。

 ... Items.Add(new ProductItemContext(prod)); ...
      
      







テンプレート/スニペットからレディコードを挿入できます



悲しみ



これがアプリケーションの速度に影響を与えなければ、すべてが非常に素晴らしいでしょう)同じVisibilityBindingは、オブジェクトの階層全体を通過し、UIWidgetをオフにします。 つまり GetComponents()は常にひきつりますが、これは悲しいことです。

 ... private void SetVisible(Transform tr, bool visible) { foreach(var collider in tr.GetComponents<Collider>()) { collider.enabled = visible; } foreach(var widget in tr.GetComponents<UIWidget>()) { widget.enabled = visible; } } ...
      
      







テキストの変更を確認する方法を次に示します。

 void Update(){ if(_characterName != NewCharacterName){ _characterName = NewCharacterName; } }
      
      





ソースコードは何か他のものを言っていますが、原理は同じです。



最適化のための私のハックはすべて、変換とゲームオブジェクトがキャッシュされるCachedMonoBehaviourからのNguiBaseBindingクラスの継承で終わりました。 GetComponent定数を最適化する方法があります:要素が静的で、そのコンポーネントをキャッシュできることを示すバインダーのフラグを作成し、フラグによってキャッシュからコンポーネントを取得する独自のGetComponent実装を作成します。 しかし、松葉杖の松葉杖のように見えます)



一般に、可視性を頻繁に変更する必要がある状況では、いくつかの超越座標に要素を転送する方が簡単です。たとえば、多くの要素を含むウィンドウをオフにしてからx:10000 y:10000 z:0階層全体を調べてコンポーネントを探す必要はありません)。



合計



UIの収集がより楽しく簡単になりました。 バインダーのリストは、ほぼすべてのクエリを網羅しています。 突然何かがなくなった場合、独自のバインディングを簡単に追加できます。これは非常に簡単です。 おもちゃとビジネスアプリケーションの両方に使用します。



もちろん、これは「黄金の弾丸」ではありませんが、このソリューションの汎用性は驚くべきものです。 私はこれをUniject(IoC + DI、WinPhoneで実際には動作しない)と組み合わせて使用​​するため、長い間NullReferenceExceptionを忘れていました(オブジェクトの作成/破棄、オブジェクトへの参照の設定について心配する必要はありません)。モデル/サービス/ビューを簡単に置き換えることができます。



Khabrahabrovtsy、インターフェース開発の経験を共有してください!



ご清聴ありがとうございました!



PS ゲームのリリース後、これが変態のゲームである/変態のゲームである/名前が世界で最悪である/頑固な熊などであるという悲鳴がたくさんありました 誰もが悪名高いPedobirだけに関連付けられた名前を持っているとは思いませんでした)ハーモニー以外に共通点はありますか? 名前を変更しました)



All Articles