AssetBundleをダウンロードするMonoメモリ問題

1)AssetBundleをダウンロードするMonoメモリ問題

2)Unity 2019の実行中に、Hierarchyのプレハブアセットを取得するパス

3)複数のSubmeshesモデルをマージした後の表示問題

4)ToLuaのアクセスTime.deltaTimeは0

5)CacheServerは接続が切れる


 

Memory

Q:コルーチン+ UnityWebRequestを使用してBundleをダウンロードするときに割り当てられたメモリは解放できません。

 

ダウンロード手順は次のとおりです。

1.コルーチン+ UnityWebRequestを使用してBundleをダウンロードする。

2.BinaryWriterを使用して、UnityWebRequest.downloadHandler.dataのデータをマシンに書き込みます。

3.UnityWebRequestのDispose関数をコールします。

4.Resources.UnloadUnusedAssets()、UnityWebRequest.ClearCookieCache()、およびSystem.GC.Collect()をコールします。

 

各Bundleをダウンロードするたびに上記のプロセスを実行しますが、Profilerで実機をデバッグした結果、割り当てられたメモリを解放できないことを検出します。これにより、Monoメモリがどんどん大きくなります。

 

A:以前にも同様の問題が発生しました。当時使用しているUnityのバージョンは2018.4.31です。

以前のWWWであろうと現在のWebRequestであろうと、そのメンバーであるDownloadHandlerを使用してダウンロードしたのです。「.data」プロパティにアクセスすると、実際には「GetData()」関数のラッパーにアクセスします。この関数はnative-memory data bufferのコピーに返します。これは根本的な原因です。

最適化できる一つ目は、「。data」の使用を減らし、一時変数でキャッシュすることです。

2つ目は、DownloadHandlerを置き換えることです。UnityはさまざまなDownloadHandlerを提供しています。当時は画像をダウンロードしていたため、DownloadHandlerTextureを使用しました。問題に応じて、DownloadHandlerAssetBundleを試すことができます。

参照:https://docs.unity3d.com/ScriptReference/Networking.DownloadHandlerAssetBundle-ctor.html


 

Editor

Q:アーティストは、エディターの実行時にシーンGameObjectインスタンスに対応するプレハブのパスを取得したいと考えています。Unity2017では、var pRoot = PrefabUtility.GetPrefabParent(go); return AssetDataBase.GetAssetPath(pRoot)を介してランタイムプレハブパスを取得できました。

 

最近2019にアップグレードしたところ、インターフェイスが更新されていることがわかりました。PrefabUtility.GetPrefabInstanceHandle(targetGameObject)、PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)、およびその他のインターフェイスは、Unityの実行中にHierarchy内のGameObjectパスを取得できません。

問題点は、実行状態です。つまり、[再生]をクリックして、Hierarchyのプレハブストレージパスを取得します。 PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)は、再生をクリックせずに取得できます。再生後したらProjectのプレハブストレージパスのみが取得できるようになりました。

 

A:PrefabUtility.GetNearestPrefabInstanceRoot:最も近いプレハブインスタンスのRootを取得します。

PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot:プレハブパスを取得します。

if (PrefabUtility.IsPartOfPrefabInstance(seletedGo))
{
    string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(seletedGo);
}

GetPrefabAssetPathOfNearestInstanceRootはパスを取得できるが、「PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)」インターフェイスは、Prefab部分ではなく、インスタンスを渡します。

そうでない場合は、Editorでスクリプトをハングアップするか、他の方法でマッピングを作成してから、Runtimeで実行します。


 

Mesh

Q:Skinmeshのマージ機能をテストしたところ、Meshに複数のSubmeshesが含まれていると、マージが成功した後はレンダリング効果が表示できなくなりました。

 

テストされたMeshにSubmeshesが含まれていない場合、マージして表示できます。 CombineMeshesは、Submeshesを含まないMeshのみをマージできますか?問題はどこにあるのかわかりませんか?解決策はありますか?

 

注:「r.sharedMesh.CombineMeshes(combineInstances.ToArray()、false、false);」を使用してすべてのマテリアルを取得するか、「r.sharedMesh.CombineMeshes(combineInstances.ToArray()、true、false);」を使用して一枚のテクスチャマテリアルをコンバインするか、複数のSubmeshesを持つモデルはコンバインのみ可能で、レンダリングして表示できません。複数のSubmeshesがないモデルは、正常にコンバインし表示できます。

 

A:テストした結果、複数のSubmeshesを含むモデルを通常どおり表示するには、CombineInstanceごとに三角形の面を再指定する必要があることがわかりました。

このコードのように:

foreach (SkinnedMeshRenderer smr in allSkineMeshList)
    {
        for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++)
        {
            CombineInstance ci = new CombineInstance();
            ci.mesh = smr.sharedMesh;
            ci.mesh.triangles = smr.sharedMesh.triangles; //ここで再指定

            ci.subMeshIndex = sub;
            ci.transform = matrix * smr.transform.localToWorldMatrix;
            combineInstances.Add(ci);
        }

    }

 

Lua

Q:ToLuaでUnityのTime.deltaTimeにアクセスしたら、常にnilであり、Lua変数に割り当てられた値も0です。

PS:静的バインディングはToLuaがUnity APIにアクセスする前に実行されており、Luaは他のAPIに通常どおりアクセスできます。

 

ToLuaでアクセスしたTime.deltaTimeが0であるのはなぜですか?

A:Luaのバインディングは、Lua仮想マシンの起動後に書き込む必要があります。

 


 

Editor

Q:クライアントがCache Serverパネルを開いてConnectionをテストすると、接続できないことがわかります。次に、サーバーのコンソールをクリックすると、Enterをクリックしたら次のことが表示されます。

その後、クライアントは再接続できます。フォーカスが失われたように感じますが、その理由は何ですか。

 

A:Windowsでは、サーバーのコンソールを右クリックしてプロパティ/デフォルトを設定し、「クイック編集モードのチェックを外します」。


 

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

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

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