Unity UIの表示と非表示(共存)関係最適化処理案

今回の主な話題:Unity UIの表示と非表示(共存)関係に関する最適化処理案、UWA GOT OnlineのLua分析、シーンがAssetbundleするとパッケージサイズが増加する、iPhoneの下部にある水平バーを非表示にする方法、NativeコードにSkinnedMeshRendererのボーンTransformをどうやって設置する。


UI

Q1: Unity UIの表示と非表示(共存)関係の最適化案に関して、一般的にどうやって処理しますか?

1、状況説明

シーン1:ポップアップウィンドウAに1つのボタンがあります。クリックすると、ポップアップウィンドウBを開き、ポップアップウィンドウAを閉じる(または閉じない)ことができます。

シーン2:ポップアップウィンドウCに1つのボタンがあります。クリックすると、全画面パネルを開き、他のすべてのUIが非表示(破棄)になります。

……

2、問題説明

類似な問題はOverdrawのインジケーターに影響します。表示と非表示の関係が適切に行われていないと、レンダリングの拡大率が高くなりすぎます。また、UI表示ロジックが不合理になり、管理が困難になります。

先輩たちはこのような問題をどのように処理しますか?

このような問題は、プロジェクトごとに具体的な要求が違う可能性があります。プランナーのロジック性がより強い、責任を取るUIプランナーもいる場合、最善の方法はプランナーに要件を整理させ、プログラムが戦略を作成することをお勧めします。

ここで説明した要件には、通常、次の問題が含まれます。

一、閉める方法

1、無制限に戻します。つまり、繰り返す開ける3つのインターフェイスABCがある場合、何度も開いた後、戻るボタンを介して開いた順序で同じ回数を戻ってから、メインインターフェイスに戻れます。(崩壊3はこのようなものであることを覚えました。)

2、インターフェイスを閉じます。一番目の方法と違って、ABCを複数回開いても、1回閉じる限りインターフェイスは閉じられます。

二、オープンメソッド

AからBを開き、Aを閉じる必要があるかどうか、つまり、Bを閉じた後にAに戻るか、メインインターフェイスに戻るかを指定します。ここにも「ABが両方フルスクリーン」、「ABが両方ポップアップウィンドウ」、「ABの1つがフルスクリーン、もう1つがポップアップウィンドウ」の状況に関します。

三、特殊効果、3Dモデルのレイヤー問題

2D + 3Dの表示状況では、複数のUIにインターリーブ問題がある可能性があります。これにも考慮する必要があります。

四、ステージ終了時の表示UI

ステージから出ると、入る前の状態を表示する必要がありますか。

五、ナビゲーション共有

すべてのUIが同じナビゲーションを共有するのか、それとも各インターフェースが別々に行われるのか。

よく見られるのは以上です。要件が明確になったら、管理方法を見ていきます。

私たちのプロジェクトのやり方はスタックを管理することであり、そのほとんどはフルスクリーンUIであり、これが前提です。全てのUIを1つのスタックに、フルスクリーンのUIを1つのスタックに、またはフルスクリーンUIに一番上のスタックのみが表示されます。私たちのプロジェクトでは、ポップアップUIがフルスクリーンUIの下にある状況はほとんどないため、この部分の個体的なOverdrawには耐えます。これはプランナーとのコンセンサスであります。

アンインストールは配置によってコントロールされます。システムに複数のインターフェイスがある場合、システムのエントリインターフェイス、つまりシステムのメインインターフェイスが閉じられる時に、このシステムのすべてのUIをアンインストールします。通常、システムにはいくつかの共有アトラスがありますから、ロジック上はより合理です。もちろん、具体的にどのようなシステムまたは重要さにも関係あります。イベントにある運営サイトにログインする際のインターフェイスなどは、閉じられるところにアンロードされます。

SetActive方式を使用して遮られたUIを表示/非表示にするためのいくつかの注意事項を追加します。

1、OnEnable / OnDisableに重要なロジックを書くないでください。

2、Updateに書いたロジックに注意してください。

3、NGUIのButtonの状態が異常になる状況に遭うことがあります。

 

フルスクリーンページ(以下、フルスクリーンと呼びます)とウィンドウページ(以下、ウィンドウと呼びます)を区別しました。フルスクリーンとウィンドウの両方がUIを独占するという大前提があります。開いた後は、下の方はクリックできません。同時に表示されるフルスクリーンディスプレイは1つだけです。ウィンドウが同時に重なりすぎないようにします。フルスクリーンを開くと、前のフルスクリーンページが閉じます。ウィンドウを開くと、ウィンドウは現在のフルスクリーンに依存します。ウィンドウはフルスクリーンのSubItemであり、どこで開いたウィンドウでも、フルスクリーンのノードの下に作成されます(フルスクリーンノードの構造は統一されています)。現在のフルスクリーンを閉じると、依存するすべてのウィンドウが解放されます。ウィンドウを閉じるときは、自分だけを離すと同時に、フルスクリーンの引用を削除します。

プログラムには、フルスクリーンの開く順序を記録するためのスタックがあります。フルスクリーンを開くたびに、一つのtypeをスタックに圧縮し、戻る時にはスタックにある順序で正常に戻ると、ターゲットのフルスクリーンにロールバックできます。つまりスタックからターゲットタイプに到達するまでです。フルスクリーンを開くときは、デフォルトで開くか、UIDataでターゲットのフルスクリーンデータを設定できます。ターゲットフルスクリーンを開いた後、tagの切り替えやウィンドウの開きなど、UIDataのデータに従ってフルスクリーンを初期化できます。

 

UIの表示に最適化を行いすぎないでください。多すぎる最適化とカプセル化は逆に簡単な問題を複雑化させます。時間もかかる、ロジックを混乱させ、学習コストも増加します。最も原始的なソリューションを使用して複数のLayerを分割し、それらを表示する必要がある場合は直接SetActiveを行います。一つの簡単な、関連なく、理解しやすい表示システムだけが、様々な要件に満たさせられます。


Lua

Q2: UWAGOT Onlineツールを使用して、Luaメモリを検出しました。このようにDestroyed総数が0を超えていますが、このデータから何かですかもわからずものにどのように処理しますか?

Destroyedことは、Unityによって「破棄」されたが、またCacheに引用されているオブジェクトの数を意味します。総数が安定している場合、問題は大きくありません。しかし、それが増え続ける場合は、確かにそれをローカルすることを試みる必要があります。

SLuaに組み込んであるMemory Profilerは、この部分のデータの強化バージョンと見なすことができます。Destroyed前に、各オブジェクトの関連コンポーネントまたはGameObjectの名前を記録し、トラブルシューティングに便利です。ToLuaまたはXLuaの場合、SLuaの実現を参照して自分で作成する必要があるそうです。原理は似ているため、コピーする方が簡単です。

これらの2つの関数は、SLuaコードで直接検索でき、アイデアを確認できます。

ObjectCache.GetAlreadyDestroyedObjectNames();
ObjectCache.GetAllManagedObjectNames();

アセット管理

Q3: 最近、プロジェクトでシーンをAssetBundle(以下、AB)にパッケージ化すると、パッケージのサイズが非常に大きくなることがわかりました。分析の結果、アセットの重複が問題であることが判明しました。 具体的な状況は次のとおりです。

シーンA、B、CはそれぞれPrefab Mを引用しています(MにはテクスチャT1、T2などの他のアセットが含まれています)。現時点では、私たちのパッケージ戦略によって分析すると、最終的にAu、Bu、Cu、Muの4つのABパッケージが印刷され、問題がないはずです。しかし、これら4つのパッケージを確認したところ、テクスチャT1やT2などの共有依存Mにあるアセットは、これらの4つのABパッケージに削除されて引用のみが保存されたではなく、それぞれに1つのコピーがあり、パッケージサイズをより多くなさせます。最後に、自分が実験した結果は、シーンをパッケージするとき、Mにあるアセットを単独にパッケージする場合、つまり、A.u,B.u,C.u,M.u,T1.u,T2.uをパッケージ出す状況にのみ、アセットの重複が避けられます。

ただし、明らかに、   この方法でABをパッケージ化する粒度は細かすぎます。私たちのプロジェクトには多くのアセットがあるため、ABをパッケージ化する数は急激に増加しますが、あまり良い方法ではありません。目前、この問題はシーンABでのみ発生します。他のタイプのABのパッケージ化は繰り返しません。 Unity 2017.4.1f1(64ビット)バージョンを使用しています。

このような問題に遭ったことはありませんか?どうすればいいですか?

Sceneに対して、Prefabは元々Clonefor Sceneであり、Refではないため、パッケージ化する際にPrefabとはまったく関係がありません。例えば、Scene A、B、CがPrefabDを引用し、パッケージ化時にDのコピーがA、B、およびCに複製されます(Editorで編集する場合のみ、ref + changeとして保存されます)。つまり、Prefab Dは完全にパッケージ化する必要はまったくなく、パッケージ化されていても、シーン内のcloneとは関係ありません。したがって、pfbを共有ユニットとして使用することはできません。また、Prefabとsceneが引用するTextureはRefであり、これは共有ユニットとして使用できます。

1つの解決策は、Unity 2018にアップグレードすることです。新しPrefabメカニズムにより、SceneのPrefabはcloneではなく、Refになさせます。これは、他の人が言及しました、私自身はテストしたことはありません。


UI

Q4: iPhone Xの下部にある水平バーを非表示にする方法は?

バージュン2017にこの二つのオプションがあります。

上記のオプションがない場合は、エクスポートされたXcodeプロジェクトのこちらを変更できます。(このコードがない場合は、追加するだけでいいです。)


Animation

Q5: 要件があるため、NativeコードにSkinnedMeshRendererのボーンTransformを設置したいです(Unityバージョンに制限はありません)。現在見られる方法は、OptimizeGameObjectを使用せずに各ボーンのTransformを直接変更することです。OptimizeGameObjectの場合にボーンノードを設定する方法はありますか?

DynamicBoneとOptimizeGameObjectが共有できないと同じに、一般的な方法は無いはずです。少数のボーンノードを設定したい場合、先にExportすることが試せます。しかし、多数またはランダムなボーンノードである場合、おそらく到達する方法はありません。


UWA公式サイト:https://jp.uwa4d.com

UWA公式ブログ:https://blog.jp.uwa4d.com

UWA公式Q&Aコミュニティ(中国語注意)https://answer.uwa4d.com