【小松教你手游开发】【unity系统模块开发】Unity5.5.2UI打包AssetBundle

之前已经有几篇文章写打包AssetBundle,但毕竟没有实际在项目中写过都写的比较浅。

刚好最近项目更新Unity5.5.2就顺便由我来更新ui打包流程

这里就把这次的经验写一下

这里还是稍微解释一下打包的基本目的:

打包ui就是把你做的界面打包出来成assetbundle包,讲道理你就把每个界面打成bundle包在游戏中你就可以直接加载来用,但是这样子的话你的每个bundle包就会非常的大,为什么呢,是因为这样子每个界面的bundle包里都包含这个界面用到的字体,贴图atlas,texture,shader还可以有你自己使用的动态组件。

这样子你的同一份资源都复制了很多份出来。

当然不能这样子做

所以我们就需要把这些atlas,font给剥离开来独立打包

不过新的打包方式让我们不用再手动剥离开来这些东西,也就是没有了剥离之后要重新引用的烦恼。

所要做的事就是把需要打包的东西改一改它的AssetBudnle名再一起build就好了

总的来说,就是把一个ui界面的下的atlas,font,texture,component记录下来,

通过修改这个ui.prefab,atlas,font,texture,compoent的预制件的bundle名,最后调一下打包函数就可以了

(有的项目texutre和shader是有自己写的管理类来加载,需要把引用置空的,这时候就需要实例ui.prefab,并把引用赋空,拷贝一份到另外一个文件夹中)

上一篇ui打包文章

http://blog.csdn.net/chrisfxs/article/details/55046339

而这次的流程是

1.清理数据,建立文件夹

2.遍历所有文件夹下的ui界面prefab

3.遍历所有prefab下的compoent(动态组件)

4.找出所有的资源(如atlas,font)用个list记录下来

5.修改这些资源和这个ui.prefab的assetbundle名

6.build

补充一点!

游戏加载assetbundle的时候要先加载atlas,font这些资源,最后加载ui资源

这样才能保证引用没有丢失

下面是代码


//#if UNITY_5_MODE
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using System.IO;

public class BuildAssetbundle
{
    public static string m_destFileName = "Assetbundle";

#if UNITY_ANDROID
    public static string PlatformExtension = ".android";
    public static string Extension = ".x.android";
    public static BuildTarget Target = BuildTarget.Android;
    public static string ASSETBUNDLE_PATH = Application.dataPath + "/../AndroidResources/StreamingAssets";
    public static string FULL_ASSETBUNDLE_PATH = ASSETBUNDLE_PATH + "/" + m_destFileName;
#elif UNITY_IOS
    public static string PlatformExtension = ".ios";
    public static string Extension  = ".x.ios";
    public static BuildTarget Target = BuildTarget.iOS;
    public static string ASSETBUNDLE_PATH = Application.dataPath + "/../IosResources/StreamingAssets";
#endif

#if BUILD_UI
    //需要打包的资源
    public static List<UIFont> fontList = new List<UIFont>();
    public static List<UIAtlas> atlasList = new List<UIAtlas>();
    public static List<GameObject> componentList = new List<GameObject>();
    public static List<GameObject> panelList = new List<GameObject>();

    public static void BuildOnePanel()
    {
        ClearAllBundleName();
        CleanTempData();

        GameObject[] selectGameObjects = Selection.gameObjects;
        UnityEngine.Object selectFloder = Selection.activeObject;
        if (selectGameObjects != null && selectGameObjects.Length != 0)
        {
            foreach (GameObject selGb in selectGameObjects)
            {
                string selGbPath = AssetDatabase.GetAssetPath(selGb);
                if (selGbPath.StartsWith(BuildUtils.PANEL_ASSET_PATH))
                {
                    if (selGbPath.EndsWith(BuildUtils.PREFAB_SUFFIX))
                    {
                        GameObject uiInstance = PrefabUtility.InstantiatePrefab(selGb) as GameObject;
                        CheckComponent(uiInstance);
                        FindRefrence(uiInstance.transform);

                        string prefabPath = BuildUtils.TEMP_PANEL_PREFAB_PATH + "/" + uiInstance.name + BuildUtils.PREFAB_SUFFIX;
                        PrefabUtility.CreatePrefab(prefabPath, uiInstance);
                        GameObject prefabAsset = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
                        panelList.Add(prefabAsset);

                        UnityEngine.Object.DestroyImmediate(uiInstance);
                    }
                    else
                    {
                        Debug.LogWarning("选择的资源 " + selGb.name + " 不是界面Prefab!");
                    }
                }
                else
                {
                    Debug.LogWarning("只能打包放在 " + BuildUtils.PANEL_ASSET_PATH + " 下面的界面Prefab");
                }
            }
            StartBuildGameObjects();

            BuildUtils.DeleteFileWithSuffixs(ASSETBUNDLE_PATH, new string[]{".manifest",""}, true, false);
            ShowBundleFolder();
            EditorUtility.DisplayDialog("提示", "打包完成!", "确定");
        }
        else
        {
            Debug.LogWarning("只能对 " + BuildUtils.PANEL_ASSET_PATH + " 下面的UI使用!");
        }
    }

    public static void BuildAllPanel(bool hint)
    {
        ClearAllBundleName();

        if (!hint || EditorUtility.DisplayDialog("提示", "确定打包 " + BuildUtils.PANEL_ASSET_PATH + " 下所有界面?", "确定", "取消"))
        {
            CleanTempData();

            string[] files = Directory.GetFiles(BuildUtils.PANEL_ASSET_PATH);
            if (files.Length != 0)
            {
                foreach (string file in files)
                {
                    if (file.EndsWith(BuildUtils.PREFAB_SUFFIX))
                    {
                        GameObject uiInstance = PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(file)) as GameObject;
                        string ui_panel_prefab_name = Path.GetFileNameWithoutExtension(file);
                        CheckComponent(uiInstance);
                        FindRefrence(uiInstance.transform);

                        string prefabPath = BuildUtils.TEMP_PANEL_PREFAB_PATH + "/" + uiInstance.name + BuildUtils.PREFAB_SUFFIX;
                        PrefabUtility.CreatePrefab(prefabPath, uiInstance);
                        GameObject prefabAsset = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
                        panelList.Add(prefabAsset);

                        UnityEngine.Object.DestroyImmediate(uiInstance);
                    }
                }

                StartBuildGameObjects();
                BuildUtils.DeleteFileWithSuffixs(ASSETBUNDLE_PATH, new string[]{".manifest",""}, true, false);
            }
            if (hint)
            {
                ShowBundleFolder();
                EditorUtility.DisplayDialog("提示", BuildUtils.PANEL_ASSET_PATH + " 下的界面界面全部打包完成!", "确定");
            }
        }
    }

    /// <summary>
    /// 对每一个要打包的Prefab保存组件信息,找出Atlas、Font等//
    /// </summary>
    /// <param name="com">COM.</param>
    static void FindRefrence(Transform com)
    {
        PrefabHierarchyInfo info = com.gameObject.AddComponent<PrefabHierarchyInfo>();
        info.transforms = com.gameObject.GetComponentsInChildren<Transform>(true);
        info.myuianchors = com.gameObject.GetComponentsInChildren<MyUIAnchor>(true);
        UILabel[] uilabels = com.gameObject.GetComponentsInChildren<UILabel>(true);
        UISprite[] uisprites = com.gameObject.GetComponentsInChildren<UISprite>(true);
        UITexture[] uitextures = com.gameObject.GetComponentsInChildren<UITexture>(true);

        foreach (UILabel lab in uilabels)
        {
            UIFont font = lab.bitmapFont;
            if (font == null)
            {
                Debug.LogWarning(com.gameObject.name + " 下出现未使用UIFont或者没有知道字体的UIlabel, " + lab.gameObject.name);
                continue;
            }

            string uifontPath = AssetDatabase.GetAssetPath(font);
            if (!uifontPath.StartsWith(BuildUtils.UIFONT_PREFAB_PATH))
                Debug.LogWarning("使用了没有放在" + BuildUtils.UIFONT_PREFAB_PATH + " 目录下的UIFont:" + uifontPath);

            if (!fontList.Contains(font))
            {
                fontList.Add(font);
            }

            lab.text = "";
        }
        foreach (UISprite sp in uisprites)
        {
            UIAtlas atlas = sp.atlas;

            if (atlas == null)
                continue;

            string atlasPath = AssetDatabase.GetAssetPath(atlas);
            if (!atlasPath.StartsWith(BuildUtils.ATLAS_PREFAB_PATH))
                Debug.LogWarning("使用了未放在" + BuildUtils.ATLAS_PREFAB_PATH + "目录下的Atlas:" + atlasPath);

            sp.RecordAtlasName = atlas.name;

            if (!atlasList.Contains(atlas))
                atlasList.Add(atlas);
        }

        foreach (UITexture t in uitextures)
        {
            t.mainTexture = null;
            t.shader = null;
        }

        com.parent = null;
    }

    /// <summary>
    /// 对找出的需要打包资源打包//
    /// </summary>
    private static void StartBuildGameObjects()
    {
        EditorUtility.UnloadUnusedAssetsImmediate();

        AssetbundleCommonFun.SetAssetBundlesName<UIFont>(fontList, Extension, false);
        AssetbundleCommonFun.SetAssetBundlesName<UIAtlas>(atlasList, Extension, false);
        AssetbundleCommonFun.SetAssetBundlesName<GameObject>(componentList, Extension, false);
        AssetbundleCommonFun.SetAssetBundlesName<GameObject>(panelList, Extension, false);

        AssetDatabase.Refresh();
        BuildAll();

        CleanTempData();
        ClearAllBundleName();

    }

    //在一次打包过程中,出现过的Component,检测多个Panel里面的(DynamicComponent)重名//
    static List<string> componentNames = new List<string>();
    //支持无限深度的Component嵌套
    static void CheckComponent(GameObject go)
    {
        string prefabPath = "";
        Dictionary<uint, List<Transform>> allComponent = new Dictionary<uint, List<Transform>>();
        FindComponents(go.transform, 0, ref allComponent);
        uint[] indexs = new uint[allComponent.Keys.Count];
        allComponent.Keys.CopyTo(indexs, 0);
        System.Array.Sort(indexs);
        for (int i = indexs.Length - 1; i >= 0; i--)
        {
            foreach (Transform com in allComponent[indexs[i]])
            {
                FindRefrence(com);

                prefabPath = BuildUtils.TEMP_COMPONENT_PREFAB_PATH + "/" + com.name + BuildUtils.PREFAB_SUFFIX;
                PrefabUtility.CreatePrefab(prefabPath, com.gameObject);
                GameObject prefabAsset = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject;
                componentList.Add(prefabAsset);
            }
        }

        for (int i = indexs.Length - 1; i >= 0; i--)
        {
            foreach (Transform com in allComponent[indexs[i]])
            {
                UnityEngine.Object.DestroyImmediate(com.gameObject);

            }
        }
    }

    /// <summary>
    /// 递归寻找动态组件//
    /// </summary>
    /// <param name="tf">Tf.</param>
    /// <param name="index">Index.</param>
    /// <param name="dict">Dict.</param>
    static void FindComponents(Transform tf, uint index, ref Dictionary<uint, List<Transform>> dict)
    {
        if (tf.name.Contains("(DynamicComponent)"))
        {
            foreach (Transform sonTf in tf)
            {
                if (componentNames.Contains(sonTf.name))
                {
                    UnityEngine.Debug.LogError(tf.name + " 子物体中出现同名的动态组件 " + sonTf.name);
                    UnityEngine.Object.DestroyImmediate(sonTf);
                    continue;
                }
                if (!sonTf.name.Contains("(DynamicComponent)"))
                {
                    componentNames.Add(sonTf.name);
                    if (!dict.ContainsKey(index))
                        dict.Add(index, new List<Transform>());
                    dict[index].Add(sonTf);
                    if (sonTf.childCount > 0)
                        FindComponents(sonTf, index + 1, ref dict);
                }
                else
                {
                    if (sonTf.childCount > 0)
                        FindComponents(sonTf, index + 1, ref dict);
                }
            }
        }
        else {
            foreach (Transform sonTf in tf)
            {
                if (sonTf.childCount > 0)
                    FindComponents(sonTf, index + 1, ref dict);
            }
        }
    }

    static void CleanTempData()
    {
        fontList.Clear();
        atlasList.Clear();
        componentList.Clear();
        componentNames.Clear();
    }
#endif

    #region tools
    static void BuildAll()
    {
        EditorUtility.ClearProgressBar();

        AssetbundleCommonFun.CreatePath(ASSETBUNDLE_PATH + "/Assetbundle");
        BuildPipeline.BuildAssetBundles(ASSETBUNDLE_PATH + "/Assetbundle", BuildAssetBundleOptions.ChunkBasedCompression, Target);

    }

    //[MenuItem("[AssetBundles]/Build Bundles Independent")]
    static void BuildBundlesIndependent()
    {
        List<Object> list = new List<Object>();
        list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));

        int count = list.Count;
        string temp_path;
        List<string> pathList = new List<string>();

        foreach (Object o in list)
        {
            if (o == null)
            {
                continue;
            }

            AssetbundleCommonFun.ChangeTextureFormat(o);
            temp_path = AssetDatabase.GetAssetPath(o);
            if (!pathList.Contains(temp_path))
            {
                pathList.Add(temp_path);
            }
        }

        BuildIndependent(pathList);
    }

    static void BuildIndependent(List<string> pathList)
    {
        string OutPutFolder = ASSETBUNDLE_PATH + "/Assetbundle";
        AssetbundleCommonFun.CreatePath(OutPutFolder);
        AssetBundleBuild temp_build;
        List<AssetBundleBuild> abbs = new List<AssetBundleBuild>();

        int count = pathList.Count;
        int index = 0;

        foreach (string item in pathList)
        {
            if (item == null)
            {
                index++;
                continue;
            }

            EditorUtility.DisplayProgressBar("Build Bundles Independent", item, (float)index / (float)count);

            if (!string.IsNullOrEmpty(item))
            {
                temp_build = new AssetBundleBuild();
                temp_build.assetBundleName = AssetbundleCommonFun.GetBundleName(item, Extension);
                temp_build.assetNames = new string[] { item };
                abbs.Add(temp_build);
            }

            index++;
        }

        BuildPipeline.BuildAssetBundles(OutPutFolder, abbs.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression, Target);

        string mainConfigPath = OutPutFolder + "/" + Path.GetFileName(OutPutFolder);
        if (File.Exists(mainConfigPath))
        {
            File.Delete(mainConfigPath);
        }

        AssetbundleCommonFun.ExportModifyFilesInfo(ASSETBUNDLE_PATH + "/Assetbundle");

        EditorUtility.ClearProgressBar();
        EditorUtility.DisplayDialog("提示", "操作结束", "OK");
    }

    //[@MenuItem("[AssetBundles]/Set Name for self")]     此功能不开放
    static void SetNameForSelf()
    {
        List<Object> list = new List<Object>();
        list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
        int count = list.Count;
        int index = 0;
        foreach (Object o in list)
        {
            if (o == null)
            {
                index++;
                continue;
            }

            string path = AssetDatabase.GetAssetPath(o);

            AssetbundleCommonFun.SetBundleName(path, Extension);

            index++;
            EditorUtility.DisplayProgressBar("Set Assetbundle Name", path, (float)index / (float)count);
        }

        EditorUtility.ClearProgressBar();
        EditorUtility.DisplayDialog("提示", "操作结束", "OK");
    }

    //[@MenuItem("[AssetBundles]/Set Assetbundle Name")]     此功能不开放
    static void SetName()
    {
        List<Object> list = new List<Object>();
        list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
        int count = list.Count;
        int index = 0;
        foreach (Object o in list)
        {
            if (o == null)
            {
                index++;
                continue;
            }

            string path = AssetDatabase.GetAssetPath(o);

            AssetbundleCommonFun.SetBundleName(path, Extension);

            index++;
            EditorUtility.DisplayProgressBar("Set Assetbundle Name", path, (float)index / (float)count);
        }

        EditorUtility.ClearProgressBar();
        //EditorUtility.DisplayDialog("提示", "操作结束", "OK");
    }

    //[@MenuItem("[AssetBundles]/Clear Selected AssetbundleName")]
    static void ClearName()
    {
        List<Object> list = new List<Object>();
        list.AddRange(Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets));
        int count = list.Count;
        int index = 0;
        foreach (Object o in list)
        {
            if (o == null)
            {
                index++;
                continue;
            }

            string path = AssetDatabase.GetAssetPath(o);

            AssetbundleCommonFun.SetBundleName(path, "", true);

            //AssetbundleCommonFun.SetDependenciesName(path, "", false, true);

            index++;
            EditorUtility.DisplayProgressBar("Clear Assetbundle Name", path, (float)index / (float)count);
        }

        EditorUtility.ClearProgressBar();
        //EditorUtility.DisplayDialog("提示", "操作结束", "OK");
    }

    //[@MenuItem("[AssetBundles]/Clear All AssetbundleNames")]
    static void ClearAllBundleName()
    {
        string[] allBundleNames = AssetDatabase.GetAllAssetBundleNames();
        List<string> hasBundleNameAssets = new List<string>();
        foreach (string n in allBundleNames)
        {
            foreach (string p in AssetDatabase.GetAssetPathsFromAssetBundle(n))
            {
                hasBundleNameAssets.Add(p);
            }
        }
        float idx = 0f;
        foreach (string asset in hasBundleNameAssets)
        {
            AssetbundleCommonFun.SetBundleName(asset, "", true);
            EditorUtility.DisplayProgressBar("清除所有Bundle名称", "当前处理文件:" + Path.GetFileName(asset), idx++ / hasBundleNameAssets.Count);
        }
        EditorUtility.ClearProgressBar();
        AssetDatabase.RemoveUnusedAssetBundleNames();
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
        //EditorUtility.DisplayDialog("提示", "操作结束", "OK");
    }

    /// <summary>
    /// 显示Bundle文件夹//
    /// </summary>
    static void ShowBundleFolder()
    {
        string path = FULL_ASSETBUNDLE_PATH +"/assets";
        path = path.Replace("/", "\\");
        Debug.Log(path);
        System.Diagnostics.Process.Start("explorer.exe", "/select," + path);
    }
    #endregion
}
//#endif

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

public class AssetbundleCommonFun
{
#if UNITY_ANDROID
    private static string strLocalFileName = "Android_LocalFilesInfo.asset";
#elif UNITY_IOS
    private static string strLocalFileName = "Ios_LocalFilesInfo.asset";
#endif

    private static List<string> componentList = new List<string>();
    static AssetImporter m_importer = null;

    public static void ClearAllBundleName()
    {
        string[] allBundleNames = AssetDatabase.GetAllAssetBundleNames();
        List<string> hasBundleNameAssets = new List<string>();
        foreach (string n in allBundleNames)
        {
            foreach (string p in AssetDatabase.GetAssetPathsFromAssetBundle(n))
            {
                hasBundleNameAssets.Add(p);
            }
        }
        float idx = 0f;
        foreach (string asset in hasBundleNameAssets)
        {
            SetBundleName(asset, "", false);
            EditorUtility.DisplayProgressBar("清除所有Bundle名称", "当前处理文件:" + Path.GetFileName(asset), idx++ / hasBundleNameAssets.Count);
        }
        EditorUtility.ClearProgressBar();
        AssetDatabase.RemoveUnusedAssetBundleNames();
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
    }

    public static void CreatePath(string path)
    {
        string NewPath = path.Replace("\\", "/");

        string[] strs = NewPath.Split(‘/‘);
        string p = "";

        for (int i = 0; i < strs.Length; ++i)
        {
            p += strs[i];

            if (i != strs.Length - 1)
            {
                p += "/";
            }

            if (!Path.HasExtension(p))
            {
                if (!Directory.Exists(p))
                    Directory.CreateDirectory(p);
            }

        }
    }

    public static string SetBundleName(string path, string name, bool isForce = false)
    {
        if (!isForce)
        {
            if (Directory.Exists(path))
            {
                return null;
            }
        }

        string dictName = Path.GetDirectoryName(path);
        string fileName = Path.GetFileNameWithoutExtension(path);
        string extension = Path.GetExtension(path);

        dictName = dictName.Replace("UIResources_temp", "UIResources");

        if (!isForce)
        {
            if (extension.Equals(".dll") || extension.Equals(".cs") || extension.Equals(".js") || (name != "" && fileName.Contains("atlas") && !extension.Equals(".prefab")))
            {
                return null;
            }
        }

        m_importer = AssetImporter.GetAtPath(path);

        if (name != "")
        {
            m_importer.assetBundleName = dictName + "/" + fileName + name;
        }
        else
        {
            m_importer.assetBundleName = "";
        }
        AssetDatabase.Refresh();

        return m_importer.assetBundleName;
    }

    public static string GetBundleName(string path, string name, bool isForce = false)
    {
        string retBundleName = null;

        if (!isForce)
        {
            if (Directory.Exists(path))
            {
                return retBundleName;
            }
        }

        string dictName = Path.GetDirectoryName(path);
        string fileName = Path.GetFileNameWithoutExtension(path);
        string extension = Path.GetExtension(path);

        if (!isForce)
        {
            if (extension.Equals(".dll") || extension.Equals(".cs") || extension.Equals(".js") || (name != "" && fileName.Contains("atlas") && !extension.Equals(".prefab")))
            {
                return null;
            }
        }

        if (name != "")
        {
            retBundleName = dictName + "/" + fileName + name;

            //Object tex = AssetDatabase.LoadAssetAtPath(path, typeof(Object));

            //if (tex is Texture2D)
            //{
            //    SetTexture(tex as Texture2D);
            //}
        }

        Debug.Log("Asset name: " + fileName);

        AssetDatabase.Refresh();

        return retBundleName;
    }

    static void FindComponents(Transform tf, uint index, ref Dictionary<uint, List<Transform>> dict)
    {
        if (tf.name.Contains("(DynamicComponent)"))
        {
            foreach (Transform sonTf in tf)
            {
                if (componentList.Contains(sonTf.name))
                {
                    Debug.LogWarning("same name component...");
                    UnityEngine.Object.DestroyImmediate(sonTf);
                    continue;
                }
                if (!sonTf.name.Contains("(DynamicComponent)"))
                {
                    Debug.Log("找到组件" + sonTf.name + "深度" + index);
                    componentList.Add(sonTf.name);
                    if (!dict.ContainsKey(index))
                        dict.Add(index, new List<Transform>());
                    dict[index].Add(sonTf);
                    if (sonTf.childCount > 0)
                        FindComponents(sonTf, index + 1, ref dict);
                }
                else
                {
                    if (sonTf.childCount > 0)
                        FindComponents(sonTf, index + 1, ref dict);
                }
            }
        }
        else
        {
            foreach (Transform sonTf in tf)
            {
                if (sonTf.childCount > 0)
                    FindComponents(sonTf, index + 1, ref dict);
            }
        }
    }

    public static void SetTexture(Texture2D tex)
    {
        string path = AssetDatabase.GetAssetPath(tex);
        TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;

        if (importer != null)
        {
            if (!(importer.textureType == TextureImporterType.NormalMap || importer.normalmap))
                importer.mipmapEnabled = false;
            importer.npotScale = TextureImporterNPOTScale.ToNearest;
            importer.textureType = TextureImporterType.Default;
            importer.spriteImportMode = SpriteImportMode.None;
            importer.isReadable = false;

            if (path.Contains("_alpha8"))
            {
                importer.textureFormat = TextureImporterFormat.Alpha8;
            }
            else
            {
                importer.textureFormat = SetTextureFormat(tex, importer);
            }
            importer.maxTextureSize = 8192;

            AssetDatabase.ImportAsset(path);
        }
    }

    static TextureImporterFormat SetTextureFormat(Texture t, TextureImporter importer)
    {
        TextureImporterFormat TextureFormat;
#if UNITY_IPHONE
        if (fun(t.width) && fun(t.height))
        {
            if (importer.DoesSourceTextureHaveAlpha())
            {
                TextureFormat = TextureImporterFormat.PVRTC_RGBA4;
            }
            else
            {
                TextureFormat = TextureImporterFormat.PVRTC_RGB4;
            }
        }
        else
        {
            TextureFormat = TextureImporterFormat.ETC2_RGBA8;

        }

#elif UNITY_ANDROID
        if (fun(t.width) && fun(t.height))
        {
            if (importer.DoesSourceTextureHaveAlpha())
            {
                //importer.alphaIsTransparency = true;
                TextureFormat = TextureImporterFormat.ETC2_RGBA8;
            }
            else
                TextureFormat = TextureImporterFormat.ETC_RGB4;
        }
        else {
            if (importer.DoesSourceTextureHaveAlpha())
            {
                //importer.alphaIsTransparency = true;
                TextureFormat = TextureImporterFormat.RGBA16;
            }
            else
                TextureFormat = TextureImporterFormat.RGB16;
            Debug.LogWarning("Texture " + t.name + " 尺寸不为2的幂次方,无法使用ETC压缩,当前使用 " + TextureFormat.ToString());
        }
#else
        TextureFormat = TextureImporterFormat.RGBA32;
#endif
        return TextureFormat;
    }

    static bool fun(int v)
    {
        bool flag = false;
        if ((v > 0) && (v & (v - 1)) == 0)
            flag = true;
        return flag;
    }

    public static void ExportModifyFilesInfo(string path)
    {
        string extension = "";
        string[] retFils = Directory.GetFiles(path, "*.manifest", SearchOption.AllDirectories);
        //LocalFilesInfo filesInfo = ScriptableObject.CreateInstance<LocalFilesInfo>();

        foreach (var item in retFils)
        {
            File.Delete(item);
        }
    }

    private static void FileCopy(string sourceFileName, string destFileName)
    {
        string dictName = Path.GetDirectoryName(destFileName);

        CreatePath(dictName);

        File.Copy(sourceFileName, destFileName);
    }

    private static string GetMD5HashFromFile(string fileName)
    {
        try
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            file.Close();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }
        catch (System.Exception ex)
        {
            throw new System.Exception("GetMD5HashFromFile() fail, error:" + ex.Message);
        }
    }

    public static void ChangeTextureFormat(Object obj)
    {
        Object[] dependObjects;
        dependObjects = EditorUtility.CollectDependencies(new Object[] { obj });

        foreach (Object val in dependObjects)
        {
            if (val is Texture2D)
            {
                SetTexture(val as Texture2D);
            }
        }

        AssetDatabase.Refresh();
    }

    public static void SetAssetBundlesName<T>(List<T> list, string Extension, bool needRefresh) where T : Object
    {
        for (int i = 0; i < list.Count; i++)
        {
            SetAssetBundleName(list[i], Extension, needRefresh);
        }
    }

    public static void SetAssetBundleName<T>(T asset, string Extension, bool needRefresh) where T : Object
    {
        string path = AssetDatabase.GetAssetPath(asset);
        SetBundleName(path, Extension, needRefresh);
    }
}

原文地址:http://blog.51cto.com/13638120/2084946

时间: 2024-12-10 08:03:43

【小松教你手游开发】【unity系统模块开发】Unity5.5.2UI打包AssetBundle的相关文章

【小松教你手游开发】【unity实用技能】角色头部跟随镜头旋转

这个在端游上比较场景,在角色展示的时候,当摄像头在角色身边上下左右旋转时,角色头部跟随镜头旋转.如天涯明月刀等. 这个在手游上比较少见,不过实现也没什么区别. 首先一般情况下,找到模型的头部节点,直接用lookAt指向camera就可以了,不过一般需求不会这么简单. 比如说,超过头部扭动极限,头部需要插值回到原始点:当镜头从外部回到极限内,需要插值回来.这时候lookat就没法使用. 更有情况,头部本身坐标系不在世界坐标轴上, 可能旋转了90多或者输出的prefab就是歪的等等,这些情况都没办法

【小松教你手游开发】【unity实用技能】根据上一个GameObject坐标生成的tips界面

开发游戏,特别是mmo手游的时候经常需要开发的一个需求是,点击某个装备,在它附近的位置生成一个tips界面,介绍装备功能和各种信息. 像上面红色框框里的这个. 这个主要的问题是 根据点击的GameObject对应生成这个详情界面时,详情界面位置需要合理摆放(不能显示不到,不能遮挡等) 基本的思路是, 首先找到GameObject的position, 把手机屏幕大概分成四个象限,知道这个GameObject大概在这个屏幕的哪个象限(左上,左下,右上,右下) 根据象限来判断详情界面应该在GameOb

【小松教你手游开发】【unity系统模块开发】热更

现在的手游项目如果没个热更新迭代根本跟不上, 特别是像我们项目做mmo的更是需要经常改动代码. 而现在的项目一般会选择用lua的方式实现热更新 不过我们项目由于历史原因没有使用,用的是另外一种方案 在项目里的所有GameObject都不挂脚本(NGUI脚本就通过代码的方式挂上),自己写的脚本都不继承Mono并打成dll,然后通过一个启动脚本去打开这些dll. 不过这样就有个问题,ios不能热更... 不管怎么样,先来讲讲这种方案要怎么做. 首先有两部分,一部分是打包,一部分是解包. 而包又分为资

【小松教你手游开发】【unity实用技能】unity发包优化(android一键发包)

unity本身的发包其实还是挺方便的,国外的游戏基本都用unity本身的发包. 但在国内的游戏有这么多渠道,这个迭代的速度的情况下,就需要一套更高效的发包方式. 接下来讲具体步骤,如果你们项目有热更新会更麻烦一点. 发包优化的目标是做到一键发包,一般发包机会是一台独立的机子,所以 第一步,更新svn 第二步,配置打包信息.根据不同渠道接入不同sdk 第三步,build apk. 因为我们项目暂时还是测试,所以还没做根据不同渠道接入不同sdk.具体思路是写个xml,在上面填写各种配置信息,版本号,

【小松教你手游开发】【unity系统模块开发】Unity Assetbundle打包笔记

*最近项目更新了Unity5.5.2,顺便更新了项目的ui打包,也更新一下这边的笔记 首先打包分为两部分,一部分是打包成Assetbundle包,一部分是从Assetbundle包解包出来成为可用的资源. 首先说第一部分 打包 所有资源都可以打包,甚至不是资源(一些数据)也可以打包,只要你需要. 打包出来的东西都可以直接用,一个字体,一个Texture,一个Prefab,一个场景,都是一打出来成Assetbundle包就可以直接用,但是为什么大家还是要各自开发自己的打包流程呢? 最重要的原因就是

【小松教你手游开发】【系统模块开发】unity 数据储存到本地为二进制文件(聊天记录本地储存)

unity游戏开发中有很多需要把数据储存到本地,官方有好几个方式可以使用,下面简单介绍一下. 一.Stream::Write,Stream::WriteLine 这个方法是打开数据流就开始写字符串,可以指定长度写,也可以一行一行的写.具体参考http://blog.csdn.net/dingxiaowei2013/article/details/19084859和雨松大神的http://www.xuanyusong.com/archives/1069 这种方法最简单,一行一行的写,一行一行的读,

【小松教你手游开发】【unity系统模块开发】unity网络层读写

在unity做强联网游戏的时候一般会选择用tcp来做通信(据说有一种udp的传输具有更高的效率),而接收信息的方法上一般会选择新建一个线程循环读取. 今天在我们项目上看到另外的一种方法.这里记录一下. 首先建立tcp连接 #using System.Net.Sockets; TcpClient tcpClient = new TcpClient(); tcpClient .BeginConnect(address,port,new AsyncCallback(this.OnConnect),re

【小松教你手游开发】【unity实用技能】拓展函数(给系统代码添加可直接使用的接口)

拓展函数的意思是给一些没有源码的脚本添加上你自己写的接口并可以直接调用. using UnityEngine; using System.Collections; namespace ExtensionMethods { public static class MyExtensions { public static void SetLocalPositionX(this Transform transform, float x) { Vector3 newPosition = new Vect

【小松教你手游开发】【系统模块开发】做一个3d旋转菜单

在unity做一个3d旋转菜单,像乱斗西游2的这种: 暂时有两种方法可以实现: 一.当做是2d界面,通过定义几个固定点的坐标.大小.透明度,还有每个点的panel depth大小,把数据存储下来,在手机滑动的过程中计算滑动划过的距离和这个panel大小的比值,乘以两个点之间的距离,获得坐标点移动的距离,通过改变x轴改变位置,同理改变大小和透明度. 这个方法我自己做2d游戏的时候实现过,做起来比较简单,没有什么可拓展性可言,并且会有很多限制,比如拖动过程中很难转变方向.要自己实现运动中的弹性(这里