今回の主な話題:パッケージサイズを最適化する方法、パッケージ化に付属のUnityAdsファイルを削除する方法、不透明なオブジェクトのレンダリング順序、Shadows.CullDirectionaShadowCastersのコスト分析、PC版のモニター解像度の取得方法。
アセット管理
Q1: 現在、プロジェクトの初期段階で出力されたAPKは数GBであり、廃棄されたリソースの一部はまだ整理されていないことがわかっています。一般的に、皆さんはパッケージサイズの最適化に何をしていますか?一部のゲームは、小さいパッケージ+リソースパッケージをダウンロードすることでやります。これも予備案にします。単純にパッケージ本体を最適化する体系的な経験はありますか? これには、リソース関連のものやその他のものを含めることができます。
①
最近、私もパッケージの問題を処理しています。自分経験について話します。
1)皆さんがよく言っている冗長リソースを削除すること+リソース形式を設定することはもう説明しません。フォーラムにこれについて記事も多いし、この部分が最も大きな影響を与えます。
2)アトラスを合理的に計画し、空白をできるだけ少なくします。移動してサイズを一つのレベルに縮小できます。TexturePackerを使用してパッケージ化するチームは、急進的に特別シーンで回転とTrimmingを使用して、アトラスをパッケージ化できます。
3)UIサイズを合理的に対処します。一般的にUIがMipmapを開かないために、UIサイズを自分でコントロールするほうがいいです。大きな背景画像やアイコンに対して、9マスまたは対称を使用して、残りの部分を生成します。
4)ABIは、プロジェクトの要件に応じてX86アーキテクチャを削除できます。IL2CPPプロジェクトの削減は明らかです(通常、一つのIL2CPPコードの同じサイズに削減します)。そして、インポートされたプラグインを含むプロジェクト内のC#コードの総量を合理的にコントロールすることで、生成されるIL2CPPコードのサイズを効果的に削減できます。
5)視野角が固定されている場合は、3DモデルテクスチャのMipmapを直接閉じて、適切なテクスチャサイズを直接選択すればいいです。 アートに関しても、モデルのサイズを縮小するために、目に見えない部分を削除することもできます。
実際、プロジェクトのすべての部分が多かれ少なかれパッケージ本体に影響を与え、詳しく話したい場合、1日も足りません。計画フォームもパッケージ本体にも影響するため、80/20の原則に従って最も影響力のある部分を見つけて解決し、効果が最も明白になるようにすることをお勧めします。
②
単純なパッケージの最適化には、次の3つの基本ポイントを実行する必要があると思います。
1)すべての冗長なリソースを排除します。
2)適切なリソース圧縮形式を設定します。
3)リソース(UIの9マステクスチャなど)を合理的に生成します。
以上に関しては、UWA公式ブログ(https://blog.jp.uwa4d.com) で多くの記事を検索できるので、ここでは説明しません。
基本パッケージ+リソースパッケージを動的にダウンロードすることは、基本的に、プレーヤーができるだけ早くゲームに参加できるようにするためのものです。
③
すべてのAssetBundleパッケージを圧縮し、UWAのリソース検出と分析ツールを使用して、冗長ファイル/非圧縮ファイルが多いかどうかを確認できます。
④
リソースの冗長性を検査すること以外に、Android App Bundleを試すこともできます。
https://developer.android.com/platform/technology/app-bundle を参考してください。
Unity2017.4.17f1ではもうサポートされています。
構築
Q2: 図に示すように、BuildReportにはportrait.jpgとlandscape.jpgの2つのファイルがあり、UnityAdsによって提供されているようですが、UnityAdsを使用していません。また、これら2つの画像がどこにあるかを見つけることもできないし、ファイルも非常に大きいです。これら2つのファイルを削除する方法を知っている人はいますか。 どうもありがとう。
UnityインストールディレクトリDataResourcesPackageManagerEditormanifest.jsonを見つけ、manifest.jsonファイルのdependenciesをクリアし、安全のためにフォルダー内のいくつかの圧縮ファイルも削除します。これにより、Unity 2017.4.1バージョンでリソースのインポート時にportrait.jpgおよびlandscape.jpgでスタックする問題も解決できます。
レンダリング
Q3: 不透明オブジェクトがレンダリングされた時には、一体どのように並べ替えられますか。時々に、正確な順序に付けられていない場合があるのはなぜですか。いつも前から後ろの順番だと思っていましたが、今日よく見てみると、そうではないようです。原因はわかりません。
以下は、テストシーンのスクリーンショットです。
シーンには3つのCubeがあります(赤色には拡大縮小があります)。nameは右から左に1、3、2です。カメラは右端にあります。2つの緑色のオブジェクトは同じマテリアルですが、赤色のオブジェクトは別のマテリアルです。2つのShaderは色のみが違って、他には完全に同じで、ShaderはStandardです。現在、赤いオブジェクトが右に配置されると、レンダリングは前から後ろの順序で完全にレンダリングされます(つまり、1-3-2)。
そして、赤いオブジェクトの位置を左に少し調整しました。
まだ2つの緑のCubeの間にあり、レンダリング順序は1-2-3になります(つまり、前のCubeが最初にレンダリングされ、最後のCubeがレンダリングされ、真ん中の赤いCubeが最後にレンダリングされます)。前後の順序に従わなくなります。
さらに奇妙なのは、この位置関係の下で、赤いCubeのマテリアルを緑の立方体と同じに変更すると、レンダリング順序が前から後ろに再びプログラムされることです。
よくわからないので、聞きたいです。
①
原則はいくつあります。
1)自分で決めた場合には、自分で決めることができます。(Camera Depth、Render Queueなど)
2)まずは結果が正しいことを確認します。
3)次にパフォーマンスが可能な限り良好であることを確認します。
不透明なオブジェクトに対して、z testがあるため、任意の順序でレンダリングでき、結果は常に正しいので、主に3次第です。主要な原因は2つあります。
1)(ハードウェア)early-zに適しています。互いに遮られているオブジェクトに対して、通常、最初にカメラに近いオブジェクトを描画し、次にカメラから遠いオブジェクトを描画します。これにより、early-z時に後にレンダリングされたオブジェクトを直接Cullingできます(最初にレンダリングされたオブジェクトに遮られました)。お互いに遮られないものにはどうしてもいいです。これもGPUにも関連しています。TBDRのpowerVRなどのより高級なハードウェアCullingがある場合、自分で並べ替えを行う必要はありません。ハードウェアは自動的に処理(HSR)して完璧なCullingを行います。
2)レンダリング状態の切り替えを可能な限り減らします。ABCDがあり、AとDのレンダリング状態(Mesh、Shader、Texture、Uniform、Blend Settingなど)、BとCのレンダリング状態は同じように仮定したら、ADBCはよりいいで、レンダリング状態が1回だけ切り替えられる(AD→BC)、そうでない場合は2回(A→BC→D)です。レンダリング状態の切り替えコストも異なるため、通常はFBO、Shader、Texture、Uniform降順で配置されます。
1と2が衝突する場合は、Unityがどちらのソートパフォーマンスが優れているかを評価する方法によって異なります。
②
不透明なレンダリングの並べ替えは、距離に基づで前から後までだけでなく、多くのことに関連しています。大きなレイヤーは、Camera的Depth、Sorting Layers、SortingOrder、RenderQueueです。
レンダリング順序に影響を与える多くの方面があります。たとえば、最初のPassが最初にレンダリングされ、ベイク処理の場合はLightMapIndexも影響します。もう一つのはMaterialが同じかどうかです。Materialが同じである場合、Passも影響されます。パッチ処理がオンにすると、パッチにも影響があります。
レンダリング
Q4: QualitySettingがShadow TypeもNo Shadowに変更した後、なぜShadows.CullDirectionalShadowCastersにまだコストがありますか?
一般的には、Shadows.CullDirectionalShadowCastersコストはないはずです。UnityのBugの疑いがあります。
解決策は次のとおりです。QualitySettingのShadow TypeをNo Shadowに変更したら、シーンにあるDirectional lightのShadow typeをNo Shadowに設定します。Profilerを観察し、確かに消えました。Unityバージョンは2017.4.15f1であります。
画像解像度
Q5: PC版はどのようにしてモニターの解像度を取得しますか? 私はPCバージョンを以下のように望んでいます:
1)初期解像度はモニターの解像度を超えてはなりません。
2)プレーヤーが境界線をドラッグでき、ウィンドウの比率を確認できるようにサポートします。
できるかどうかがわからないこと:起動時にモニターの解像度に従って強制的に設定し、解像度変更イベントを監視して、毎回16:9に設定します。
可能です。
1)ゲームの初期化スクリプトで、Screen.SetResolutionをコールして目標解像度を設定します。
2)WM_DISPLAYCHANGEを使用して解像度変更メッセージを監視し、Screen.SetResolutionを再度コールします。
Windowsイベントを監視することはめんどくさいと心配する場合は、優雅ではない方法があります。一つのタイマーを使用して、画面の解像度が変更されたかどうかを検出できます。ここでは、自分でWndProcを実現する必要があります。以下を参考できます。
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析と最適化ソリューション及びコンサルティングサービスを提供している会社でございます。
UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com