カートゥーンレンダリングの制作の流れ

今回の主な話題:カートゥーンレンダリングの制作の流れ、物理モジュールを採用していないけどなぜ物理エンジンの時間コストがある、SpriteAtlasのlate bindメカニズム、AndroidプラットフォームでのASTCの使用可能性、UIパフォーマンス分析。

 


制作

Q1: 最近Unityでキャラクターのカートゥーレンダリング効果を作成しました。現在の流は下記のように:1)プログラムがUnityでShaderを書いて効果を調整します。2)アーティストモデルの頂点カラーと法線などのアセットを3dmaxで変更し、プログラムに渡します。3)プログラムがアセットをUnityに導入して効果を検査します。現在、アセットを頻繁に変更し、エクスポートおよびインポートする必要があり、効率は比較的低いです。

だから私は次の2つの質問があります:

1.3ds maxでシェーダーを作成し、アートでモデルを変更した後、すぐに効果を確認できることはどうすればいいですか?

2.成熟した制作の流れとは何ですか?

これは難しいことではありません。レンダリングプログラマーにMayaまたはMaxのドキュメントを見てもらいましょう。基本的には数時間で完了します。MaxまたはMayaにはサンプルとドキュメントがあります。たとえば、Maxの場合はDirectX Shader Materialを使うことです。これを難しいものに考える必要はありません、ドキュメントを見てください。

本質的に、あなたが見るものを直接にあなたの目的になさせたいですと感じています、すべての仕事はこの目的のためのものだと思います。カートゥーレンダリングによるアートリリースのほとんどは、ストロークを制御するための頂点カラーのブラッシング、ライティングを改善するための頂点法線の変更などのカスタマイズを必要とします。したがって、シェーダーがMaxに実装すれば、常にインポートとエクスポートすることの代わりに、アーティストの制作流れも大幅に改善できます。一般的な流れは、エンジンプレビューエフェクトと同じのMax(またはMaya)をメンテナンスして、一つのカスタムの法線エディタツールを加えて(自有のツールは十分でないとアーティストが感じた場合、たとえば、Maxの法線エディタことは難しい)。これで、アートリリースを変更して、効果の一貫性を確保すれば大丈夫です。

 

最初の問題について、読書さんが一つの方法を提供しました:MaxにはHLSLで書けます、DX9/11のSampleがありますが、問題がたくさんあります。Driverに対してはNitrous Direct 3D 9をお勧めしますが、Gamma/LUTとSSAOを必ずオフにしてください。

参照ドキュメントへのURLを添付します:http://docs.autodesk.com/3DSMAX/16/ENU/3ds-Max-SDK-Programmer-Guide/index.html?url=files/GUID-0C7A600E-7954-42B0-86EE-586A379A2CAD.htm,topicNumber=d30e34269


UI

Q2:UIインターフェイスを開くと、Profilerのピーク値は、Canvas.SendWillRenderCanvasesがCPUコストの50%を消費し、Canvas.SendWillRenderCanvasesが80msを消費し、Graphic.Rebuildが72msを消費することを顕示しました。最適化する方法はありますか?

これは、多数のUIインターフェース要素の再構築コストです。提案は次のとおりです。

(1)まず、「動と静を分離」の原則を通じて、不要な静的UIメッシュが再構築に関係しているかどうかを確認します。

(2)UIインターフェースが複雑すぎるかどうか、UIレベルまたはメッシュの数が大きすぎるかどうか。

(3)UWAパフォーマンスレポートで対応するソリューションと関連動画を確認します。


物理

Q3:下図のように、物理モジュールに衝突ペアもRigidbodyも何も使用していませんが、なぜ物理モジュールの時間コストまだありますか?

問題主のUnityバージョンは何ですか?Unity 5.4バージョン以降の場合なら、Unityエンジンが物理システムを調整していたため、確かに正常ではありません。

Unity 5.4より前のバージョンの場合は、可能性があります。使用するかどうかに関係なく、物理モジュールがすべてのフレームで実行されるため、アイドリングとして理解できます。これに関して、問題主にレポートにある「重要なパラメータ分析」⇨「エンジンパフォーマンスパラメータ」の「Physics.Processing」または「Physics.Simulate」ページを確認することをお勧めします。このページには、これら2つの関数のコール回数が含まれています。多くの場合、物理モジュールはあまり使用されていなくても、20msごとに(デフォルトで)実行されるため、同じフレームで何度も実行されます(下図のように)。だから、物理モジュールには一つの特性があります。プロジェクトが重っていると、もっと重くさせます。この場合、問題主は他のモジュールを最適化するだけで済みます。他のモジュールの時間コストが減りますと、物理モジュールの時間コストも自然的に降ろします。


アセット管理

Q4: 最近、Unity 2018.1.0 Beta 13バージョンで問題が発生しましたが、以前のバージョンでも同じ問題が発生する可能性があると思います。Unity 2017の新しいSpriteAtlasをSpriteのパッケージ化に使用し、AssetBundleを生成しました。この方式はtagとは異なることがわかりました。遅延バインディングも処理する必要があるため、SpriteAtlasManager.atlasRequestedのコールバックを自分で実現する必要があります。

そのため、SpriteAtlasのすべてのInclude Buildを削除し、AssetBundleをパッケージ化しましたが、SpriteAtlasManager.atlasRequestedの実現に問題が発生しました。これは、同期インターフェースを使用すると、つまり、AssetBundle.LoadFromFileとAssetBundle.LoadAssetのインターフェースがSpriteAtlasをロードし、SpriteAtlasManager.atlasRequested内部に直接actionをコールバックすると問題は発生しません;非同期インターフェースを使用すると、つまりAssetBundle.LoadFromFileAsyncとAssetBundle.LoadAssetAsyncを使用し、ロード完了後にactionをコールバックします(つまりSpriteAtlasManager.atlasRequested以外)と、画像がロードできないことを導きます。エディターまたはパッケージ(私がテストしましたのは Windowsパッケージ)も、UGUIのインターフェースをぼやけさせます。

公式に聞きましたけど返事はありませんでした。

https://forum.unity.com/threads/spriteatlasmanager-atlasrequested-is-not-invoked-in-editor.524801

だから、これがUnityのバグなのか、それとも私の理解または操作に問題はありませんか?

まず、「このメソッドはタグとは異なることがわかりました。遅延バインディングを処理する必要があります。」は違います。ここでは「必要」ではありません。[Include in build]をオンにすると、bindingを自分で処理する必要がなく、直接ロードしてインスタンス化するだけで大丈夫です。ただこのバグを注意するだけで、今はBundleのアトラスを冗長になさせる可能性があります。https://answer.uwa4d.com/question/5a822325847802258a06509e

問題主がlate bindingをやりたい場合、説明から伝えたいのは、SpriteAtlasManager.atlasRequestedに必ず直接にactionをコールバックしますと有効ですが、非同期を使用した後(数フレーム後に相当)にコールバックしますと無効になりました。

再現のために例を作成しましたが、類似な問題は発生していませんでした。テストコードは下記のように。UI Prefab(あるSpriteを使いました)と対応するSpriteAtlasに依存パッケージ化され、prefabBundleとsaBundleとして記録されました。ロードされたコードは以下の通りで、バージョンは2017.2.2です。

IEnumerator Start ()
    {
        var loadOp = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + prefabBundle);
        yield return loadOp;
        var prepre = loadOp.assetBundle.LoadAsset<GameObject>("prop_parachute");
        GameObject.Instantiate(prepre);
    }
    void OnEnable()
    {
        SpriteAtlasManager.atlasRequested += RequestLateBindingAtlas;
    }
    void OnDisable()
    {
        SpriteAtlasManager.atlasRequested -= RequestLateBindingAtlas;
    }
    void RequestLateBindingAtlas(string tag, System.Action<SpriteAtlas> action)
    {
        StartCoroutine(LoadFromAssetBundle(tag, action));
    }
    IEnumerator LoadFromAssetBundle(string tag, System.Action<SpriteAtlas> action)
    {
        var loadOp = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + saBundle);
        yield return loadOp;
        var loadOp2 = loadOp.assetBundle.LoadAssetAsync<SpriteAtlas>(tag);
        yield return loadOp2;
        var sa = loadOp2.asset as SpriteAtlas;
        action(sa);
    }

アセット管理

Q5: 現在、AndroidプラットフォームでASTCの使用可能性はどうですか?公式ドキュメントによると、いくつかの主流のGPUはASTCをサポートするための高い要件を持っていません。Android端末でASTCを使用するときに注意が必要なことは他にありますか?

ASTC圧縮方式に関しては問題ありません。テクスチャサイズの要求しなく、複数の品質レベルがサポートされています。しかし、問題はOpenGL ES 3.2以降のみサポートしています、つまりRedmi 2やXiaomi 4など、大部分のローエンドおよびミッドレンジコンピューターにはできません。iOSプラットフォームのiPhone 6以降でサポートします。サポートされていない結果は、テクスチャが自動的にRGB24 / RGBA32に変換されることです。そのため、私たちのプロジェクトはASTCを試しましたが、ETC2を再び使用しました。


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

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

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

材質(テクスチャ)間のパフォーマンスへの影響

今回の主な話題:材質(テクスチャ)間のパフォーマンスへの影響、パーティクルシステムが放出点を継続的に変更することのパフォーマンスの最適なソリューション、低解像度のDepthTextureのレンダリング方法、Unityでのオブジェクトのリアルタイムライティングのパフォーマンスコスト。


制作

Q1:質問があります。私たちのプロジェクトには、放出点を常に変更する必要のあるパーティクルシステムがあります。worldspaceモードで確かに特定の効果を達成できますが、現在、単一フレーム内に複数の位置から同時に粒子を放出する必要があります。複数の同じParticle Systemで確かに目的を達成できますが、少し浪費と感じて、頻繁に作成および廃棄を導く可能性があります。全部キャッシュしますと合計数が非常に大きいので、一つのParticle Systemでこの効果を実現できる方法がありませんか?

このドキュメントを参照できます。

https://docs.unity3d.com/ScriptReference/ParticleSystem.Emit.html

ParticleSystemのEmit方法でパーティクルを発射したら、1つのフレームで異なるEmitParamを使用してEmitを複数回コールできます。そうすれば、パーティクルシステム自体は移動する必要はありませんが、Emitの位置パラメーターは毎回異なります。


アセット管理

Q2:

シーン1:一枚の512x256テクスチャ。

シーン2:二枚の256x256テクスチャ。

上記のどちらのコストが高いと聞きたいです。

 

更に、同じキャラクターに。

シーン1:一つのシェーダーと一枚の512x256テクスチャ。

シーン2:二つのシェーダーと二枚の256x256テクスチャ。

この場合には、どちらのコストが高いと聞きたいです。判決の根拠と原因は何ですか?

メモリに関しては、設定が同じ場合、2つは同じはずです(長さと幅が等しいことが必要な一部の圧縮形式を除く)。

両者のCPUコストはほとんど同じです。一つの材質に対して、一枚と二枚の差別はサンプル回数にあります。一枚のテクスチャはテクスチャのバインドコストを一回減らします。理論的に、削減された時間のかかるコストはnsレベルであるから、ほとんどの場合、CPU端末の違いは無視できます。材質が二つある場合、影響されたものは多くなります。より多いDraw CallやRenderState切り替えなどを引き起こす可能性がありますから、Atlas Packingを採用して最適化する必要があります。

GPUコストについて、テクスチャのShaderサンプルを一つ追加すると、必ずより多くの計算が必要になります。それてShader InstructionとCyclesも間違いなく多くなります。しかし、それは本当により多くの実際のコストをもたらすでしょうか?絶対ではありません。GPUの圧力は、ShaderのInstructionだけでなく、同時に、このShaderによってレンダリングされるランタイムのピクセル数にも依存します。自体の比率が小さい場合、サンプリングを1つ増やしても少なくても、実に違いはありません。


レンダリング

Q3: 低解像度のDepthTextureをレンダリングしたいのですが、何か便利な方法はありますか?

一つの方法は、低解像度のRenderTextureを自分で作成し、Shader Replacementを使用してDepthTextureをレンダリングすることです(ShaderはUnityのShadowCaster実現を参照できます)。

もう一つは_LastCameraDepthTextureで他の低解像度カメラ(存在する場合)によってレンダリングされたDepthTextureにアクセスします。


レンダリング

Q4: Unityでライトの受け取り、シャドウの生成、シャドウの受け取りのパフォーマンス状況を了解したいです。これを尋ねる理由は、上記の3つのUnityのパフォーマンスコストを分かりたいです。また、携帯端末で上記3つまたは一部の可能性はありませんか?

問題主が言った「ライトの受け取り」はReal timeのライトの受け取りですか?そうなら、パフォーマンスコストは予測できません。なぜなら、これはレンダリングシーンの複雑さ、光を受け取るオブジェクトの数などに大きく関係して、簡単に「オンにすれば時間がかかり、絶対にオンにしません」と理解できません。この文を参照できます:インディーズゲーム「Abi」のシーンCPUコスト分析

「シャドウの生成」と「シャドウの受け取り」は、ただリアルタイムシャドウ機能の2つのオプションであります。UWAパフォーマンスレポートでShadows.RenderShadowMapとShadows.PrepareShadowMapを注意して、プロジェクトの具体的なパフォーマンス時間コストを確認しますとお勧めします。

現在、リアルタイムライティングとリアルタイムシャドウは、多くのモバイルプロジェクトで広く使用されています。

最後に、UWAブログには素敵なリアルタイムシャドウに関する記事がたくさんあります。それらをチェックして、問題主に役に立ちますと思っています。


管理

Q5: 私たちのプロジェクトは設立の初期段階にあり、MonoとIL2CPPの間にためらっています。Unity ILCPPとMonoどちらがより良いですか?本当にIL2CPPのパフォーマンスが大きな変化はありますか?使ったことのある人が教えてください!

IL2CPPとMonoどちらかどうかが、現段階では主にAndroidでの選択です。

まず、プロジェクトの初期段階にこの問題を考える必要はなく、今のIL2CPPの成熟度限り、気にせずいつでも利用できます。初期段階では、パッケージをより早くできるために、Monoを使って出させます。公式バージョンまたはパフォーマンスおよび互換性テスト用のバージョンをIL2CPPの方がよりいいです(もちろんそれは.netでdllコードのホットアップデートがない場合)。

下記の内容は自分がプロジェクトからやってみた、まだは得たものです。

まとめ:

Monoの利点:

1)十分にテストされました;

2)パッケージ化速度は早いです;

3)パッケージサイズは小さいです;

4)AndroidでDLL動的ローディングアセンブリのホットアップデートをサポートします(使ったことはありませんが、IL2CPPがまったくサポートしていないことは確認です)。

IL2CPPの利点:

1)Monoメモリが上昇するだけで下降しないという問題はありません。

2)C#側の計算集約型アルゴリズムのパフォーマンスはN倍に急上昇しました(同じマップのパス検索や自動建物位置計画などのアルゴリズムの速度が3倍以上に増加しました)。

3)Luaホットアップデートには問題はなく、リフレクションコールと導出コール両方ども完全にサポートされています(利点ではないかもしれませんが、確かに予想外です)。

そしてIL2CPPの問題は:

1)ビルド時間が非常に長いです。WindowsバージョンのAndroid NDKツールチェーンのパフォーマンスがどのように低下​​するのでしょうか。AMD 16コアと32スレッドを使って、NDKはコンパイル時に並列化を完全にサポートします。

2)IL2CPPを採用した後、ARMv7バージョンのみがコンパイルされると、一部のシミュレーターはゲームを起動できません。FAT(ARMv7 + x86)を使ったら大丈夫です、シミュレーターでも非常にスムーズに実行されます。もちろん、パッケージのサイズは20 MB大きくなりました(私たちのc#コードが多すぎるかな...)。

Monoモードで64ビットをサポートすることはできなくなりました。将来的には、IL2CPPが唯一のオプションとなります。Unityは現在、よくやっています。

 

補充します。Androidが2019年にGoogle Playにリリースしたい場合、64ビットライブラリを提供する必要があり、IL2CPPのパスしか使用できないことです。

さらに、IL2CPPにはAndroidにまだ一つの問題があります。それは「Failed to extract resources needed by Il2CPP」。これは、現時点での使用を妨げる唯一の問題であるはずです(2017.3にも再現することがありました)。

https://forum.unity.com/threads/failed-to-extract-resources-needed-by-il2cpp-unity-5-4-0f3.419593/

この問題について簡単に説明します。Androidでは、毎回起動する時にUnityはIL2CPPが必要なアセット(assets / bin / Data / Managedにあり、Monoのconfig及び各種のmetaデータ)を解凍します。問題は、この操作が失敗する可能性もあります。実際、Unityはapkから直接読み取れば大丈夫です。Unity公式がこの問題を早く解決することを祈ります。


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

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

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

Unity物理エンジンPhysxのパフォーマンスを向上させる方法

今回の主な話題:Unity物理エンジンPhysxのパフォーマンスを向上させる方法、Unityがスクリプトを自動的にコンパイルすることを禁止する方法、Texture2DArrayを使うときにMipmap効果をオンにする。


物理

Q1:Unity物理エンジンPhysxのパフォーマンスを向上させる方法は何ですか?シーンにリジッドボディのある人形オブジェクトを100個入れ、十分に衝突させて、ローエンドマシンでは10フレーム未満しか実行できないことがわかりました。

充分な物理計算が必要な場合、これらの小さな人々が混雑していると、多数の物理的衝突が発生する可能性が高く、その結果、物理時間コストが非常に長くなります。

最適化する前に、問題主がいくつかの基本的な物理数値の推奨値を了解する必要があります。すべての設備が100個の自由に作成されたスキンモデルをスムーズに実行できることではありません。

さらに、問題主が実機での具体的な時間かかるボトルネックが本当の物理にかかりますかどうかを確認する必要があります。100個キャラクターがいますから、メッシュの量が多い場合、レンダリングの時間コストも無視できません。Unity Profilerで実機のパフォーマンスのボトルネックを確認することをお勧めします。

最後に、この100個キャラクターの一人一人に正確な物理計算を必要としていますか?光線の交差や距離の判定などの性能/価格比率の高い判定方法で純粋な物理的衝突を置き換えることができますか?これには、問題主がデザインからの視点から考えることが必要です。

 

PhysX APIを直接コールする方法はないため、所謂物理エンジンのパフォーマンスを最適化することは、実には関連するコンポーネントのパフォーマンスを最適化することです。最初に、RigidBodyではなくCharacterControllerを優先に使用すべきです。次に、MeshColliderの使用を出来る限りに避け、代わりにBoxCollider、SphereCollider、CapsuleColliderを使用してみてください。避けられない場合は、Convexをフックしてください。もちろん、もっとも良い最適化は物理的な衝突を使用しないことです。射線は多くの問題を解決できますが、射線はコストがないではありません。射線のコストはシーン内の面の数に明確に関連しています。もちろん、射線のmaxDistanceとLayerMaskを設定すると、必要のないコストを節約できます。一番いいのは、簡単な物理モデルを使用して問題を記述し、自分でコードを書いて実現することです。


エディター

Q2:何かUnityがスクリプトを自動的にコンパイルすることを禁止する方法はありませんか?

Preferences > General > Auto Refreshのチェックを外すこともできますが、そうすれば、アセットが外部で変更されても、自動的に再インポートされないため、ある程度の影響があります。

そして、これら2つの関数(EditorApplication.LockReloadAssemblies / UnlockReloadAssemblies)を試すこともできます。ドキュメントを参照してください。

https://docs.unity3d.com/ScriptReference/EditorApplication.LockReloadAssemblie


レンダリング

Q3: Texture2DArrayを使用すると、Mipmap効果がないことがわかりました。Mipmapを効果的にする方法を教えてください。 元のテクスチャはMipmapがオンになっています。

Texture2DArrayを作成するとき、最後から2番目のパラメーターに注意する必要があります。trueに設定しますと、Mipmapは有効にさせます。ドキュメントを参照してください。

https://docs.unity3d.com/ScriptReference/Texture2DArray-ctor.html


制作

Q4:今は外部で生成された一枚のTextureがmainTexとしてレンダリングできますが、内容を取得して保存したいのに、GetPixelsはTexture2Dの関数なので、そのようなTextureの内容はどうやって取得できますか?

最初にGraphics.Blitを介して内容をRender Textureに描画し、次にReadPixelsでRenderTextureから一枚のTexture2Dを生成します。sourceTexが元のTexture、tex2Dが最終的なTexture 2Dであると仮定したら、コードは下記のように:

RenderTexture renderTexture = new RenderTexture(sourceTex.width, sourceTex.height, 32);
Graphics.Blit(sourceTex, renderTexture);
Texture2D tex2D = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.RGBA32, false);
RenderTexture oldRT = RenderTexture.active;
RenderTexture.active = renderTexture;
tex2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
tex2D.Apply();
RenderTexture.active = oldRT;

Shader

Q5: TerrainのShaderをカスタマイズしようとしていますが、中にあるShaderの最後にこのような2行があります。この中の「Dependency」は何かできますと聞きたいです。または後に指定されたShaderは何かできますか?

Dependency “AddPassShader” = “Hidden/TerrainEngine/Splatmap/Diffuse-AddPass”

Dependency “BaseMapShader” = “Diffuse”

Unityのドキュメントはこれの役割を説明すべきではありませんが、このブログでは明確な説明があります。

https://alastaira.wordpress.com/2013/12/07/custom-unity-terrain-material-shaders

これは、Terrainが4つ以上のテクスチャを使用する場合、Unityはこの中のAddPassShaderを使用して二回レンダリングをして、blendします。BaseMapShaderはローエンドのグラフィックスカードで使用され、一枚のテクスチャのみを使用してShaderを表示します。


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

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

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

Unityベイク問題

今回の主な話題:UIアトラスの静的分離、Unityベイク問題、Unityレンダリング異常、Animation.RebuildInternalState。


UI管理

Q1: Unityの静的アトラスと動的アトラスの分離についていくつか質問があります。 当社のUI作成方法は以下になります。

●Prefab(UIHero)

●Prefabの静的アトラス(UIHeroAtlas)

●アバターなどのPrefabにおける可能な動的アトラス(UIHeroIcon)

生成されたBundle:

●PrefabはBundleを一つ(静的画像を含む)

●動的アトラスはBundleを一つ

後で、動的バッチでいくつかのDrawCallsを削減するために、静的アトラスに2〜3枚の画像があり、動的画像に小さな辺の背景として使用されます。次に、アーティストはそれを動的アトラスに配置します。これにより、画像が重なると、それと動的アトラスもDrawCallになります。

私たちの質問は、ABを使用してUI-prefabをロードするときに、動的アトラス(UIHeroIcon)を全体的にロードしますか?または、UIHeroIcon全体をロードするではなく、これらの2つの静的画像だけをロードしても、動的HeroIconはロードされませんか?この方式でUIHeroIcon動的アトラスをホットアップデートしますと、UIHero-prefabがこの2つの静的画像をロードできない状況を導く可能性がありますか?どのように選ぶべきですか?

 

1.ロードしますかどうかはあなた次第です。Unityは依存リストのみを提供し、ロードするかどうかは自分で制御します。

2.UIHeroIcon全体をロードしません。

3.こちらのDrawCallの数はほとんど同じです。ただし、前景は色々な可能性があり、アーティストが採用する方法も違います。私の理解では、静的アトラスに2つのSpriteAとBがあり、次に動的アトラスにAとBをコピーします。 重なっている場合、UIの深度が異なると、マージできない場合があります。 アセット構造も重要です。そうしないと、後でメンテナンスする時には 面倒になります。

 

UWAからの補充:上記の回答の3番目を補充します。DrawCallがどれだけ節約できるかを評価することをお勧めします。たとえば、10人のMOBAの場合、チームバトル中に10個のIconが重なるときがあります。それならDrawCallが20個になる可能性もあります。ローエンドの機器の場合、20個のDrawCallを節約できなら、価格/性能比は良いです。最悪の状況も10個未満の場合、そうする必要はありません。


レンダリング

Q2: Unity5.3でベイクして生成されたLightingData.asset、Lightmap-0_comp_dir.exr、Lightmap-0_comp_light.exrは別々に何かをできますか?パッケージ化およびロード時に実際に使用されるファイルはどれですか、またはすべて必要ですか?

LightingData.assetの紹介はこの2つのドキュメントで確認できます。

https://docs.unity3d.com/Manual/LightmapSnapshot.html

https://answer.uwa4d.com/question/5a4f4367e041ef3c50c9ce64

簡単に言うと、中に保存されたのはシーン内のLightmapの影響を受ける各オブジェクトの関する情報です。Editorでこのファイルは非常に大きい場合がありますが、実機では、precomputed giを使わない場合に携帯にパッケージ化のこの部分のデータは小さいすべきです(オブジェクトに対して、主なLightmap情報はlightmapIndexとlightmapScaleOffsetであります)。

なお、この部分の情報はシーンファイルにバインドされており、個別に管理することはできません。だからデフォルトでは、Lightmapはシーンでのみロードできます。ライトマップを動的にロードしたい場合は、この記事を参照してください:http://www.xuanyusong.com/archives/3807(中国語注意);後の2つの.exrファイルは、ライト情報を格納するテクスチャであり、_dirはライトの方向情報で、_lightはライトの強さ情報(最も簡単なモードでは一枚のみ必要です)。これらのファイルは実行時に必要ですが、exrはHDRをサポートする形式で、携帯では他の形式に変換され、サイズはexrとは異なります。


アニメーションシステム

Q3: Camera.RenderのAnimation.RebuildInternalStateは時間がかかり、頻繁にコールされますが、どのような状況でコールされますか?

UWA:このアイテムには2つの主な理由があります。

(1)問題主のプロジェクトは古いバージョンのアニメーションシステムを使用しています。

(2)Animationコンポーネントを含むGameObjectsで頻繁にActiveまたはInstantiate操作を実行します。通常、この状況は特殊効果、UI HUD、キャラクター/モンスターなどでよく見られます。

これについて、開発チームに上記の2つの点を確認することをお勧めします。


UI管理

Q4:UIの最適化に、各アトラスのメモリ使用量はパフォーマンスに影響が大きいですが、またはアトラスの数(draw call)の方に影響が大きいですか?たとえば、8 枚の1024アトラスと2枚の 2048アトラスはどちらが優れていますか?

実には、どちらが優れているかを示す統一された標準はありません。たとえば、4つの1024テクスチャが常に同じUIに表示され、同時にロードおよびレンダリングされる場合、通常は一枚の2048に合併することはもっと合理です。また、1〜2枚のテクスチャが同時に表示される状況も少ない場合、2048のテクスチャに合併することはメモリの浪費です。

この極端な状況に対する方法は問題主が考えることができますと思いますが、この部分は必要次第です。「どちらはいい」を判断できません。具体的な選択基準は、プロジェクトのメモリがより緊張であるか、UIのDrawCallがより緊張であるかによって異なります。

個人的な提案は、メモリに常駐する可能性のある汎用的なアセットに対して、最大2048または4096の一枚など、より大きいアトラスサイズ制限を与えることができます。単一ゲーム内の特有アトラスについては、UIを1024以内に提案します。使用量が3 枚の1024のレベルに達すると、2048のテクスチャサイズが採用できます。理論的に、1枚のテクスチャを加えると 1つのDrawCallしか増加しないことができますが、2枚のため2048テクスチャを使用すると、余白が増えたり、不当な合併が発生したりして、メモリ使用量が無駄になります。


レンダリング

Q5: Unity 5.5.2f1バージョンのプロジェクトで、いくつかのモデルがCull BackのShaderを使用するとき、レンダリングが異常になりました。新しいUnlit Shaderを作成し、Cull Backタグを追加しました。このShaderを使用してキャラクターをレンダリングすると、下記の問題が見つかりました。

Cull BackをCull OffまたはCull Frontに変更しても、効果は正常に戻りました。

ですから、モデルの表と裏が逆になっていると思いますが、同社のアーティストが「3dmaxのメッシュの表と裏は法線方向によって決定され、法線方向は正しいため、モデルアセットの問題ではありません。」と言いました。

だから、シェーダーを変更し、法線をフラグメントシェーダーの出力として使用すると、次の結果が得られます。

上の画像を見ると、法線に問題はないようですが、原因は何ですか?

三角形のfrontとbackは法線で決定ではなく、三角形の3つの頂点がスクリーンに投影される順序によって決まります。デフォルトでは、glesは反時計回りの面をfront、時計回りの面をbackとして認めています。上記の法線方向は正しいですが、face cullingとは関係ありません。問題を見ると、アーティストが出力した時に三角形の面の頂点の順番が逆になっているようですので、変更すれば問題を解決できます。

face cullingに関してはこの二つの関数を参照できます。

https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glCullFace.xml

https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glFrontFace.xml

実には、face cullingと法線は逆になっていることは違う現象であります。

1.face cullingの場合、そのShaderにCull Offの文を追加します。表示が上記のように正常である場合、それは面が逆になったと説明しました。

2.法線が逆になった場合、モデルを選択すると右下隅のプレビュー(またはシーンに直接lightを加えます)に黒で表示されます。なぜですか?dot(lightdir、normal)、法線が反転しているため、この値は基本的に0であり、diffuseとこの値の掛け算の結果も0になります。


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

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

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

Texture2DArray

今回の主な話題:Texture2DArray、遠距離オブジェクトの物理シミュレーション、パーティクルシステムのCPU / GPUコスト、StreamingAssetsディレクトリの圧縮パッケージの読み取り方法。


パーティクルシステム

Q1:パーティクルシステムのコストをどのように区別しますか?どの部分がCPUにあり、どの部分がGPUにありますか? 空のパーティクル(レンダリングを含むすべてのモジュールを無効にする)にはコストがありますか? あったら、どこに反映されますか?

現在のUnityエンジンのネイティブ機能について、パーティクルシステムでのステータスの更新(パーティクルの位置、方向、トリガーイベントなど)はすべてCPU側のコストであり、具体的には、ParticleSystem.UpdateやParticleSystem.EndUpdateAllなどの関数で示されます。UWAパフォーマンスレポートで次の2つの画面をチェックできます。

関するリンク

関するリンク

同時に、 パーティクルシステムがレンダリング中に、CullingやDraw CallオペレーションなどのCPU側の準備も必要です。次の図に示すように、これらもCPUコストの一部です。

GPU側での時間コストは他のMeshレンダリングと同じで、主にALU、Bandwidth、Overdrawと関します。ただし、他の一般的なシーンのレンダリングと違いのは、GPU側のパーティクルシステムの圧力は常にOverdrawに反映されます。下図のように。

上の画像は「キワメ」のパフォーマンスレポートからのものです。完全なデータを参照して、この部分の理解を深められます。

空の粒子のコストは理論的には非常に小さいですが、UWAはまだそれをテストしていません。問題主は自分でテストできます。


アセット管理

Q2: Unity 5.5バージョンを使っています。プロジェクトはLZ4のAssetBundleを使用しているため、StreamingAssetsに直接配置すると、パッケージが大きすぎになります。今は、すべてのAssetBundleを一つの圧縮パッケージにパックし、StreamingAssetsに入れて、プレーヤーが最初にインストールされたときに、PersistentDataPathディレクトリにコピーして解凍しますようにしたいです。しかし、AndroidプラットフォームのStreamingAssetsディレクトリにある圧縮されたパッケージの読み方がわかりません。ご指摘ください!

直接にCを使ってunzipライブラリを実現しました。ゲームを始まるときに、Apkを開きます。後で、unzipライブラリで必要なファイルをキャッシュディレクトリに解凍し、読み取ります。読み取ったデータに対しで、必要がない場合は定期的にクリーンアップします。

 

UnityのAPIでは、WWW(新しいバージョンのUnityWebRequestに対応)だけが非Bundleファイルにアクセスできますが、このインターフェースは非同期であります。さらに、.bytes操作は、より高いMonoメモリの割り当てを生成し、Monoメモリのピーク値を上昇させやすいです。だから、ある方法はAndroidのJava APIを介して読み取ることです。YusongMOMOさんがこの記事(https://www.tuicool.com/articles/fAnYJ3I)で使ったJavaインターフェースを参照できます


アセット管理

Q3: Unity 2017.2fバージョンを使用しています。PrefabのImage要素は、Sprite Atlasフォルダー内の画像を直接使用しています。今はPrefabとSprite Atlasを別々に違うAssetBundleにパッケージして、Sprite Atlasのinclude buildオプションも削除します。ツールでPrefabとSprite AtlasのBundleを確認し、Prefabが配置されているBundleはImage要素が使用したSpriteマップも中にパッケージします。また、Sprite Atlasが配置されているBundleには、Atlasマップが含まれるだけでなく、元の画像がすべてこのBundleに含まれています。これはどうしてですか?

UWAがテストした後、Unity 2017.2と2017.3に問題主が述べた問題が存在していますと分かりましたが、一部の操作でこの問題を回避することもできます。まず、私が普通だと思うことについて話します。

include in buildはBundleのパッケージすることに影響ありませんはずです。そしてPrefabのBundleにSpriteAtlasの存在もずっとありませんはずです。ただし、include in buildを有効にしない場合、2つのBundleが正常にロードされ、Prefabがインスタンス化されると、late bindingを行う必要があるため、Spriteは表示されません。

次に、発生したバグについて話しましょう。

1、Bundleを初めてパッケージするとき(する前にBundleディレクトリを空にする)、include in buildがオンにしますと、atlasはprefabのbundleにパッケージされます(問題主の問題のように);

2、ただし、Bundleを初めてパッケージするとき、include in buildはオフの場合、それは正常です(AtlasはprefabのBundleにありません)。

おもしろいのは、再びBundleをパッケージするとき、include in buildが開かれているかどうかに関係なく、結果が前回と同じであることです。だから、避ける方法は:     最初に、Bundleディレクトリをクリアし、include in buildを閉じてBundleを1回パッケージし、次にinclude in buildを開いて2回目にパッケージします。 その結果、AtlasはPrefabのBundleに含まれず、Atlasのinclude in buildがオンになります。


レンダリング

Q4: ドキュメントによると、GLES3 Metalはすでにサポートされています。最も発想しやすいのは地形のスプラットレイヤーです。4層のスプラットの場合は、代わりにTexture2DArrayを一つ使用できます。利点はbindのコストを減らすことです。Splatのサンプリングの数も減らせるらしいですが、自分のテストと理解によるとダメです。Texture2DArrayのsliceはお互いにblendingしませんから。この理解は正しいですか?

Texture2DArrayを使用して、4層のスプラット地形を置き換えます。XCodeからコストを確認しますと、削減はありませんから、この方法で地形を作る意味は小さくなりました。AssetStoreにはMegaSplatと呼ばれるプラグインがあり、Texture2DArrayを使用して多くのレイヤーのミキシングを実現しています。頭に浮かぶTexture2DArrayを使用できるもう1つの場所は、シーンマップです。 たとえば、シーンで複数の1024テクスチャまたは複数のlightmapを使用している場合、StaticBatchingはテクスチャが異なるために合併できませんが、Texture2DArrayで実現できます。またはUIにあるiconみたいに、一つのTexture2DArrayに合併してDrawCallの合併を実現させられます。

現在のTexture2DArrayの最も不利な点は、コードでしか作成できないことです、エディターからのサポートはありません。Texture2DArrayをオフラインに作る場合は、異なるプラットフォーム用に複数のアセットを準備する必要があります。皆さんは共有できるTexture2DArrayに関する経験がありませんか?

UWAはTexture2DArrayを了解しました、複数の2Dテクスチャを1つのオブジェクトに合併するようです。そして、一度だけバインドしますと複数の2Dテクスチャをサンプリングできます。確かにサンプリングする場合には、一回に確定なsliceを一つしかサンプリングできませんが、blendを完了するには別のShaderコードも必要です。

問題主が「Splatのサンプリングの数も減らせるらしいですが、自分のテストと理解によるとダメです。」と言いました。彼が伝いたいのは「すべてのスライスを毎回収集する必要があるわけではなく、一部だけをサンプリングすることもできます。」と思います。元に表現したいのは「一回に一つのsliceしかサンプリングしません。」と思います。

Texture2DArrayを使って4層のSplat地形を置き換えました。xcode から見ると、コストは減少してありませんから、現在では、こうやって地形を作る意味はあまり大きではありません。

パフォーマンスだけから見ると、Texture2DArrayは実際にTexture2Dよりもテクスチャバインディングのコストだけを減らすことになり、ゲームエンジンのバッチ処理に影響を与える可能性があります。他のメソッドは通常のTexture2Dと同じです。Texture2DArrayはTexture3Dと比べてLOD処理に違います。Texture3Dはスライスを削減しますが、これはTerrainをレンダリングするときにやりたいものではありません。次に、Texture2DArrayはフィルタリング時にUとVでのみそれを行い、Texture3Dはdでも行うので、この部分もTexture2DArrayはTexture3Dよりもパフォーマンスが優れています。これらの要因がTerrainのレンダリングにTexture2DArrayを推奨する理由かもしれません。問題主は実験を通じて、Texture2DArrayレンダリングのTerrainがコストを削減しないことを示しました。これは、通常、1つのシーンに1つの地形があるのみの可能性もあります。4つのテクスチャを結び付けることと比べて一つを結び付けるがかかった時間は数ミリ秒だけ節約して、そして毎フレームにするではありませんので、効果は明ら​​かではありません。

UWAは簡単な実験で説明します。下図はTexture2DとTexture2DArrayを使用して地形のレンダリング結果とGLES APIコールであります。設備はSamsung S6です。

Texture2D:

Texture2DArray:

このうち、GLES APIコールが赤枠でテクスチャバインディングAPIコールを表し、緑枠でレンダリングAPIコールを表します。WTは、APIコールの時間コストをナノ秒で表します。Texture2D図からすべてのテクスチャバインディングは5回でありことがわかりまして、材質の5回のテクスチャバインディングに対応します。しかし、Texture2DArrayには2回しかありません、splatテクスチャと4レイヤー混合テクスチャのバインディングに対応します。図から見られますのは、1回glBindTextureの時間コストはやく1000~10000ns、すなわち最大0.01ms。だから3回glBindTextureと3回glActiveTextureの時間を加えても最大0.06msで、簡単に見られません。


物理

Q5:私たちのチームは一つの超巨大地形のMMOゲームを開発しており、シーンにいるキャラクターやマンスターが多いです。Unityエンジンは遠い場所(500Mまたは1KM以上)にあるGameObjectに物理模擬を行いますか?この部分の物理模擬コストを減らす設置はありませんか?

オブジェクトがActiveであり、Rigidbody(Character Controller)をマウントすると、Sleeping状態にはなりませんなら、確かにUnityエンジンは遠い場所にあるGameObjectに物理模擬を行います。Unityエンジンには、距離に応じて物理システム を調整する計算はありませんが、自分でコントロールできます。例えば、Culling Groupまたは自分でGameObjectの距離を計算するでRigidbodyのActiveとDeactiveをコントロールして、全体的の物理システムの時間コストを節約します。


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

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

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

C#コンパイルの最適化

今回の主な話題:C#コンパイルの最適化、IPAパッケージサイズの問題、Unityパッケージのスピードアップ、AssetBundleのインクリメンタルパッケージ化。


アセット管理

Q1: 現在、プロジェクトのAPKサイズは約120MBで、パッケージ化の平均時間は20〜25分です。Build中のほとんどの時間は「Building Scene0」と「Building additional assets」二パートにかかります。Unityはこれら2つの段階で一体何をしていますか?この段階で時間を節約する方法はありますか?また、ハードウェアから考える場合、パッケージ速度を効果的に向上させる方法は?ハードディスクのR/W速度とCPUのパフォーマンスを向上させることに、どのようなメリットがもたらされますか?

私たちはAssetBundleの方式を使っています。現在、600MBくらいのパッケージ、アセットをあまり変更しない場合、Androidパッケージは約10分で出来ますが、前には7〜8分で十分でした。C#コードを変更しません、ただのPatchなら5〜7分くらいで出来ます。

私たちが使用しているAndroidパッカーの価格は約150,000です。これには複数のCPUが搭載されており、シングルコアCPUのパフォーマンスが可能な限り高いことが保証されています。SDDが必要であり、その他は不要です。

使っているCPUは:Intel(R)Xeon(R)CPU E5-2683 v3 @ 2.00GHz 2.00 GHz

テクスチャ圧縮についても注意すべき点があります。以前はテクスチャ圧縮によってよく苦しさめていました、高品質は遅すぎます。後で、DevとPubのバージョンを区別しました。Devバージョンはローカルテクスチャ圧縮にFastを使用し、公開に使用されるPubバージョンは最高品質を使用します。速度は相当早くなりました〜アーティストに多くのテクスチャ変更がある場合でも、Devバージョンはすぐにパッケージ出来ます。

 

私はずっと前にGithubでこれを見つけました。

pvrtextool_wrapper:https://github.com/fxgames/pvrtextool_wrapper

Unityのパッケージ化はpvrtextoolをコールします。このwrapperで元のプログラムを置き換えますと、開発バージョンの 圧縮品質を強制的に高速モードに設定でき、テクスチャ圧縮品質パラメーターを変えずに大量の時間を節約できます。Mac Proが高すぎると思っている方は、この方法を試すことができます。

 

Building SceneはUnityのパッケージシーンアセットであり、Building additional assetsはUnityがResourcesをパッケージする中のアセットであります。私たちのプロジェクトは600 MBに近く、毎回パッケージ化には50分以上かかるため、悲惨です。下記の方法をやってみられます:

1)AssetBundleの形式ですべてのアセットを使用します。初回以外、次回からパッケージされたのは変更と増分のあるアセットのみです。なぜなら、Resourcesの毎回の出版はアセットを再びパッケージしますからです。これで変更されていないアセットのパッケージ化の時間コストを節約出来ます。

2)良質なコンピューターを作り、CPUをより強いCPUに変え、ハードディスクをSSDに交換します。

上記の2つのポイントにより、パッケージを出す時間を節約できます。これも、弊社現在使用している方法です。


アセット管理

Q2:パッケージ化を二回しました、どちらのファイルも変更されていませんが、AssetBundleの内容は変更されました。その原因は、そこに含まれるスクリプトの内容に違いがあるように感じます。Manifestファイルには、CRCとAssetFileHashに変更がありますと表示しています。ファイルはもうUWA Q&A公式Webサイトにアップロードされています。最初のパッケージは完全パッケージで、二番目のパッケージは増分パッケージです。

完全パッケージの流れは下記のように:

1、Revertアセット

2、 すべての BundleNameのアセットをClearします

3、規則によって全体のBundleNameを設定します

4、 BuildPipeline.BuildAssetBundles(outputPath, abBuilds, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);を使用してパッケージします

5、ファイルに対してBundleNameのマッピングテーブルを生成します

 

増分パッケージの流れは下記のように:

1、Revertアセット

2、 すべての BundleNameのアセットをClearします

3、マッピングテーブルによってアセットBundleNameを設定します

4、規則によって他のアセットのBundleNameを設定します

5、BuildPipeline.BuildAssetBundles(outputPath, abBuilds, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);を使用してパッケージします

6、ファイルに対してBundleNameのマッピングテーブルを生成します

主な問題は、パッケージする前にUIのPrefabを事前処理すると、一部のコントロールにスクリプトコンポーネントを追加したことが分かりました。この変更されたPrefabはアップロードされないため、毎回にこの操作を行います。毎回追加されるスクリプトコンポーネントに割り当てられるFileIdは異なりますから、毎回異なるファイルになります。チェックしたときにこの部分が無視されました。

また、Unity 5.x以降のBuildAssetBundleOptions.DeterministicAssetBundleがデフォルトのオプションであり、特に追加する必要がないことがUnity公式に確認されました。


その他

Q3:出力されるAppStore.ipaがDevelopment.ipaより相当大きいです。なぜこれが発生するのか理解したいと思います。

出力環境:

xcode:9.2

unity:5.6.3p2

 

データのスクリーンショット:


まず、コードはswift + obj-cメソッドを使用し、エクスポート時にALWAYS_EMBED_SWIFT_STANDARD_LIBRARIESがYesに設定されます。スクリーンショットからわかるのは、主にはAppStoreがDevelopmentよりSwiftSupportの内容を増加します。私がパッケージしたAppStore.ipaはDevelopment.ipaより約50MB大きくなっています。 この問題をどのように回避できますか?

AppStoreパッケージにはデフォルトでsymbolsを添付しており、クラッシュログをシンボル化するために使用され、アップロード後に削除されます。最終、ユーザーがダウンロードしますのはこのIPAのサイズではありません。


その他

Q4:C#に一つの関数内容がマクロ定義で囲まれ、コンパイル時に空き関数になりますが、外部からのコールがあり、コンパイル時にこのコールを最適化しませんか?たとえば、入力パラメーターは、いくつかの関数コールを行ってから戻り値を渡すことです。この操作のコストはそのままありますが、定数を入れば、コンパイルされて最適化されますか?

コンパイラーは、マクロでラップしたコードのみを最適化し、対応するマクロは定義されません。

例えば:

if UNITY_EDITOR

Debug.Log(“hello uwa”);

else if UNITY_iOS

Debug.Log("good uwa");

endif

if UNITY_EDITORにのはエディターでのみ有効になり、パッケージ化後に最適化されます。

 

[Conditional]

 

上記の回答によると、IL2CPPでマクロ定義と条件付きコンパイルの違いを測定しました。コードは下記のように。

コンパイル後に生成されるC ++コードは図のように

どちらも関数の定義を生成することがわかりますが、違いのは:

(1)マクロ定義は関数定義のコードを削除しますが、コールサイトでのパラメーター転送は最適化されないため、関するコールコストを完全に排除することはできません。

(2)条件付きコンパイルは、関数のコールステートメントを直接削除し、関するコールオーバーヘッドが生成されなくなりますが、関数定義のコードはそのまま残ります。


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

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

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

半透明レンダリングがパフォーマンスへの影響

今回の主な話題:半透明レンダリングがパフォーマンスへの影響、PSSメモリが一部のモデルでの急上昇、Action関数のパフォーマンス、ShaderVariantCollection生成設定。


レンダリング

Q1: UWAパフォーマンスレポートには、半透明レンダリングのパフォーマンスコストについて特に説明があります。「一般的に、 UI、シーン、粒子などの原因が高いパフォーマンスコストを導きます。」という文が書いてあります。わかりたいのは、UI(ほとんどのUIは半透明部分があります)が半透明度にどの程度影響を与えますか?UIを作成する際の注意事項はありますか?

ほとんどのモバイルプロジェクトに対して、この影響は大きいです。 半透明レンダリングのCPU側には、注意すべき2つの主なポイントがあります。

(1)UI Draw Call;(2)UI再構築。

UI Draw Callが高いほど、レンダリングの時間コストも高くなります。だから、UWAパフォーマンスレポートのCPUパフォーマンス詳細分析ページに、UI Draw Callの使用状況を確認することをお勧めします。一般的に、モバイルゲームに対して、ピーク値を40以下にコントロールすることをお勧めします。UI Draw Callを減らすため、主には図集をAtlasにパッケージすることやインターリーブを回避することなどです。具体的には自分でグーグルできます。

また、UI再構築も可能な原因であり、主にメインスレッドのselfウェイトコストに現れます。UIが再構築のメッシュが大きい場合、この状況はよく見られます。だから、できる限りに必要のないUIメッシュ再構築を避けってください。これもR&DチームがUI作成時に特に注意すべきところであります。


メモリ

Q2: 最近、Meizu Pro5でゲームを実行するとPSSメモリが急上昇することがわかりました。UWA GOTでテストしましたが、アセットメモリは増加していません。そしてこの問題はMeizu Pro5でのみ発生し、他のモデルではこの問題はありません。どうすれば解決できますか?

一つ簡単なプロジェクトを探しました、下記の図に、NPCの名前と影は同時に顕示出来ません、そうしないとPSSは急上昇します。

下図のように、GfxDriverメモリは増加し続き、1秒あたり約2MBであり、増加しているだけで減らすことはありません。長時間実行すると、Meizu Pro5がクラッシュします。

GfxDriverとPSSが一緒に上昇する場合、GPUにバグがある可能性が高いです。 以下のみを提案できます:

(1)特定のマシンに「UIシャドウ」を追加しないようにし、製作から避けます;

2)Unityの上位バージョンでデモを実行して、メモリ問題が修正されるかどうかを確認します。

その後、問題主がUnityのバージョンを5.4.5から5.5.6にアップグレードしてから、auto graphics apiを選択した後、メモリ増加の問題が解決されました。


その他

Q3:new Action(Function)と直接にFunction関数を導入することとの違いは何ですか?たとえば、下記の2つの関数の違いは何ですか?

void Method(Action action)
{
}
void MethodCallBack()
{
}
void Start()
{
//Method(new Action(MethodCallBack)) と Method(MethodCallBack) の違いは何ですか?どちらのパフォーマンスはより高いですか?
}

理論的には同じです。Method(MethodCallBack)がコンパイルされる時に、コンパイラーは自動的にnew Actionをパッケージしますから、コンパイルの結果から見ると同じです。

この2つの書き方はプロジェクトに時々コールされる場合は問題ありませんが、頻繁にコールされる場合は、外部でActionを定義し、そのActionをMethodに渡して再利用することをお勧めします。すなわち、

Action act = New Action(MethodCallBack);
void Start()
{
Method(act);
}

アニメーション

Q4: 古いアニメーションシステムを使用しており、アニメーションは個別にパッケージされて、実行時にアニメーションはAddClipを介してモデルに追加されますが、AddClipはRebuildInternalStateをトリガーしてピークを発生させます。このピークはどうやって解決できますか?そしてこの問題は古いシステムだけに起こしますか?

RebuildInteralStateはMecanimにもありますが、名前は違いて、「Animator.Initialize」になりました。両者の機能とトリガータイミングはほぼ同じです。

AddClipは確かに時間をかかります。これは以前からそうであったので、特別な要件がない場合は、できるだけシーンがカットするときにAddClipを置き換えることをお勧めします。Runtime(特に戦闘中)にはAddClipを頻繁にコールすることは推薦しません。


アセット管理

Q5:UWAでShaderVariantCollectionに関するすべての資料を確認した後、一つのShaderを事前にロードするShaderVariantCollectionを作りたいです。Shaderのバリアントが多いのため、そしてメンテナンスが便利のために、すべてのShader.keywardsの組み合わせを見つけるツールを作成したいです。ShaderVariantを生成するとき、 1つのパラメーターはPassTypeです。Material.GetTag( "LightMode"、true)で検索する場合、2つの問題があります。

1)一つのShaderに複数のSubShaderまたはPassが異なるLightModeを使用していますが、GetTag(“LightMode”, true)で最初の一つのみ見つかります。

2)一部のShaderにはTags{“LightMode”=XXX}を設定することはありませんが(主にサードパーティのプラグイン)、どうすればいいですか?

私はこちらにツールスクリプトを探します:https://paste.ubuntu.com/26462717

反射をやってみられます。KeywordとPasstypeを同時に見つけることができます。

static MethodInfo GetShaderVariantEntries = null;
public static List<string> GetShaderKeywords(this Shader target)
{
if (GetShaderVariantEntries == null)
GetShaderVariantEntries = typeof(ShaderUtil).GetMethod(“GetShaderVariantEntries”, BindingFlags.NonPublic | BindingFlags.Static);

        int[] types = null;
        string[] keywords = null;
        object[] args = new object[] { target, new ShaderVariantCollection(), types, keywords };
        GetShaderVariantEntries.Invoke(null, args);
        keywords = args[3] as string[];
        List<string> result = new List<string>();
        foreach (string keyword in keywords)
        {
            foreach (string t in keyword.Split(' '))
            {
                if (!result.Contains(t))
                    result.Add(t);
            }
        }
        return result;
    }

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

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

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