[Unity优化]UGUI图集的使用

参考链接:

http://www.xuanyusong.com/archives/3304

http://www.xuanyusong.com/archives/3315


Sprite Packer的使用:

http://liweizhaolili.blog.163.com/blog/static/1623074420131151303310/


关键点:

1.在unity5中,Statistics面板中的Batches即为drawcall。并且,新建一个空场景,drawcall的初始值为2,所以一般drawcall的计算要从2开始

2.在导入图片时,最好就是一个图集对应一个文件夹,文件夹的名字即为图集的名字

[Unity优化]UGUI图集的使用_第1张图片

using UnityEngine;
using UnityEditor;
using System.IO;

public class AutoSetPackingTag : AssetPostprocessor {

    void OnPostprocessTexture(Texture2D texture)
    {
        string atlasName = new DirectoryInfo(Path.GetDirectoryName(assetPath)).Name;
        TextureImporter textureImporter = assetImporter as TextureImporter;
        textureImporter.textureType = TextureImporterType.Sprite;
        textureImporter.spritePackingTag = atlasName;
        textureImporter.mipmapEnabled = false;
    }

}

3.需要打包成图集的图片不能放在Resources文件夹内,也就是说,我们无法通过Resources.Load的方式加载图片。对此,有两种解决方法:

a.将图片保存到prefab中,prefab放到Resources文件夹内。不过当需要加载的图片比较多时,这种方法就比较麻烦。可以使用ScriptableObject把图片序列化保存,这样会比较方便一些

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

public class SpriteScriptableObject : ScriptableObject {

    public List<Sprite> list = new List<Sprite>();
    //字典无法被序列化
    public Dictionary<string, Sprite> nameSpriteDir = new Dictionary<string, Sprite>();

    public void ReadData(string dataDir)
    {
        list = new List<Sprite>();
        string[] filePaths = Directory.GetFiles(dataDir);
        foreach(string s in filePaths)
        {
            if (!s.EndsWith(".meta"))
            {
                Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(s);
                list.Add(sprite);
                Debug.Log(sprite.name);
            }
        }
    }

    public void Init()
    {
        for (int i = 0; i < list.Count; i++)
        {
            nameSpriteDir.Add(list[i].name, list[i]);
        }
    }

}

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Reflection;
using System;

public enum ScriptableObjectType
{
    SpriteScriptableObject,
}

public class CreateScriptableObject : EditorWindow {

    static string dataDir;
    static string outputDir = "Assets/";
    static string name;
    static ScriptableObjectType scriptableObjectType;

    [MenuItem("Window/CreateScriptableObject")]
    static void Init()
    {
        EditorWindow.GetWindow(typeof(CreateScriptableObject));
    } 

    void OnGUI()
    {
        EditorGUILayout.BeginHorizontal();
        dataDir = EditorGUILayout.TextField("数据目录", dataDir);
        if (GUILayout.Button("拾取路径")) dataDir = AssetDatabase.GetAssetPath(Selection.objects[0]);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        outputDir = EditorGUILayout.TextField("输出目录", outputDir);
        if (GUILayout.Button("拾取路径")) outputDir = AssetDatabase.GetAssetPath(Selection.objects[0]);
        EditorGUILayout.EndHorizontal();

        name = EditorGUILayout.TextField("名字", name);
        scriptableObjectType = (ScriptableObjectType)EditorGUILayout.EnumPopup("类型", scriptableObjectType);

        if (GUILayout.Button("输出"))
        {
            //Type.GetType对于继承UnityEngine.Object的类会返回空
            //string className = scriptableObjectType.ToString();
            //Debug.Log(className);
            //Type t = Type.GetType(className);
            //if (t == null) Debug.Log("null");
            switch (scriptableObjectType)
            {
                case ScriptableObjectType.SpriteScriptableObject :
                    SpriteScriptableObject so = ScriptableObject.CreateInstance<SpriteScriptableObject>();
                    so.ReadData(dataDir);
                    AssetDatabase.CreateAsset(so, outputDir + name + ".asset");
                    break;
                default:
                    break;
            }
            AssetDatabase.Refresh();
        }     
    }

}

[Unity优化]UGUI图集的使用_第2张图片


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

public class NewBehaviourScript1 : MonoBehaviour {

    public Image[] images;

	// Use this for initialization
	void Start () 
    {
        SpriteScriptableObject sso = Resources.Load<SpriteScriptableObject>("2");
        sso.Init();
        Debug.Log(sso.list.Count);
        Debug.Log(sso.nameSpriteDir.Count);

        images[0].sprite = sso.nameSpriteDir["a"];
        images[1].sprite = sso.nameSpriteDir["b"];
        images[2].sprite = sso.nameSpriteDir["c"];
	}
	
}


b.使用AB包的形式。将同一个图集的小图的AB包名字设置为相同的,即可将这些小图打包到同一个AB包中

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class NewBehaviourScript : MonoBehaviour {

    public Image[] images;

	// Use this for initialization
	void Start () 
    {
        AssetbBundleManager.Instance.Load(@"file:///" + Application.dataPath + "/AB/", "2.unity3d",
            (ab, name) =>
            {
                Sprite a = AssetbBundleManager.Instance.GetAsset<Sprite>(ab, "a");
                images[0].sprite = a;
                Sprite b = AssetbBundleManager.Instance.GetAsset<Sprite>(ab, "b");
                images[1].sprite = b;
                Sprite c = AssetbBundleManager.Instance.GetAsset<Sprite>(ab, "c");
                images[2].sprite = c;
            });
	}

}

4.图集占内存的计算:对于一张1024*1024的RGBA图集,占4M内存(1024*1024*4)

5.如果把带透明通道和不带透明通道的小图打包到同一图集,unity会把它分成两组


你可能感兴趣的:(图集)