在Unity

时间:2017-07-15 12:06:46

标签: c# performance unity3d optimization

我已经交换了一些 Sprite 对象,转而使用 Meshes 没有纹理,因为它们占用的内存较少。

然而,当检查我的 Profiler 时,即使在交换之后,使用的纹理内存也完全相同。

所以我决定强行卸载这些纹理,但事情并不顺利。 我对这段代码的意图是通过它们所在的 GameObject 的名称找到所有纹理(因为我只是通过检查员拖动场景中的精灵,他们的名字匹配。我知道哪些GO-s查找只包含 MeshFilter ),然后手动卸载它们。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class DumpUnused : MonoBehaviour
{
    private TextureContainer swappedTextures = new TextureContainer();
    private IEnumerator Start()
    {
        RemoveSwappedTextures();
        var unloader = Resources.UnloadUnusedAssets();
        while (!unloader.isDone)
        {
            yield return null;
        }
    }
    private void RemoveSwappedTextures()
    {
        //getting all my scene objects that has a mesh filter.
        /*
         * NOTE: I swapped my sprites for generated meshes. 
         * However, the texture memory used didn't decrease so I bet they are still loaded.
         * The textures I used as sprites had the same name as the assets themselves as assets were 
         * just dragged on the scene.
         */
        var sceneObjects =
           UnityEngine.Object.FindObjectsOfType<GameObject>()
            .Where(g => g.GetComponent<MeshFilter>() != null);
        //we have the repaced gameobjects.

        //now to get the used textures by their names:
        foreach (var item in sceneObjects)
        {
            //getting everything, even assets
            var strToFind = GetOriginalName(item.name);
             swappedTextures.Append(
             Resources.FindObjectsOfTypeAll<Texture2D>()
             .Where(t => t.name.Equals(strToFind)
             ));
        }
        foreach (var text2Unload in swappedTextures)
        {
            //destroy the loaded textures.
            DestroyImmediate(text2Unload);
        }
        swappedTextures = null;
    }

    private string GetOriginalName(string name)
    {
        /*
         * getting the original asset name by the "unity populated name".
         * reason: say I have a "backGr" named texture. 
         * if I copy paste it all over the place, unity makes their name
         * "backGr (1)", "backGr (2)" and so on.
         * So I search until the first whitespace and anything before that
         * is the original name of the texture.
         */

        string str = "";
        char c;int i = 0;
        for (c = name[i]; i < name.Length && c != ' '; i++)
        {
            str += c;
        }
        return str;
    }

    public class TextureContainer : List<Texture2D>
    {
        //made only for convenience
        public void Append(IEnumerable<Texture2D> textures)
        {
            foreach (var _t in textures)
            {
                this.Add(_t);
            }
        }
    }
}

我认为它没有做我想要的原因是因为使用的纹理内存完全相同,并且使用的总内存甚至更高比以前更高。

所以,除非在场景中纹理较少的情况下Unity使用更多纹理记忆是正常的,我想我在某处搞砸了。

问题是,如何使这项工作?如果我走错路,按名称卸载纹理的最佳做法是什么?

0 个答案:

没有答案