Creating AssetBundles创建资源包小工具

本文介绍了一款用于Unity3D项目的资源打包工具,能够帮助开发者轻松地将资源打包成.unity3d格式,支持不同类型的资源文件,并提供了多种打包选项以满足不同的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

在最近对AssetBundles打包为.unity3d,发现打包时有些小麻烦,于是就做了一个小工具,由于本人接触的不深入,有很多的不足和考虑不周的地方,希望大侠们多多指教,在这里分享一下。有问题直接留言谈论,我也多多向大侠学习。

现在对于AssetBundles的动态加载资料方法也在博客中有,http://blog.youkuaiyun.com/fanglrui/article/details/9114765可以学习到,在这里就不多说了。

下面是这个编辑窗口,对于窗口编辑在博客中也有相关资料。http://blog.youkuaiyun.com/fanglrui/article/details/9152847

 

创建文件夹名称:这个就是你所创建的文件夹的名字。路径是在项目文件夹下,例如项目文件名/创建的文件夹名(AssetBundlesPro/AssetBundles)。

 

要打包的对象名:这个是填写assets里的资源对象,可以是路径。例如:打包对象在resources里面的energy模型。(resources/energy,选择的类型就是.fbx格式)。

 

保存名称:就是打包的文件名字了。

 

当然这里可以扩展,比方说扩展出一种配置文件的格式,在打包的时候一块带有自己定制的配置文件。对于这一块由于时间工作的问题没有具体去想。正是这样做的原因是,可以在看得见的情况下去手动输入,减少一些繁琐的事情,当然还有一种做法,很方便。先贴出这个窗口编辑的代码,有不足之处,不妥当的地方,多指教。

 

using UnityEngine;
using System.Collections;
using System;
using UnityEditor;

/// <summary>
/// 打包为.unity3d格式
/// </summary>
public class ExportUnity3D : EditorWindow
{
    /// <summary>
    /// 资源对象名称
    /// </summary>
    private string myTargetPathString = "";
    /// <summary>
    /// 创建的文件夹名称
    /// </summary>
    private string mySavePathString = "AssetBundles";
    /// <summary>
    /// 要保存的文件名称
    /// </summary>
    private string myFileName = "";
    /// <summary>
    /// 菜单选择的ID
    /// </summary>
    private static int typeFileindex;
    private static string[] strType = { ".prefab", ".fbx", ".mat", ".tga", ".png", ".cs", ".unity" };

    [MenuItem("Window/Export unity3d file")]
    static void Init()
    {
        typeFileindex = 0;
        ExportUnity3D exportWindow = (ExportUnity3D)EditorWindow.GetWindow(typeof(ExportUnity3D));
        exportWindow.Show();
    }

    void OnGUI()
    {
        GUILayout.Label("填写打包为unity3d格式的对象", EditorStyles.boldLabel);
		EditorGUILayout.Space();
        mySavePathString = EditorGUILayout.TextField("创建文件夹名称(路径):", mySavePathString);
		EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal();
        myTargetPathString = EditorGUILayout.TextField("要打包的对象路径:", myTargetPathString);
        typeFileindex = EditorGUILayout.Popup(typeFileindex, strType,GUILayout.Width(65));
        EditorGUILayout.EndHorizontal();		
		EditorGUILayout.Space();
        myFileName = EditorGUILayout.TextField("保存名称:", myFileName);		
		EditorGUILayout.Space();
        if (GUILayout.Button("打包"))
        {
            ExportResource(mySavePathString, myTargetPathString, myFileName);
        }
    }

    /// <summary>
    /// 打包方法
    /// </summary>
    void ExportResource(string path, string filePathName,string fileName)
    {
        if (path != "" && filePathName != "" && fileName != "")
        {
            System.IO.Directory.CreateDirectory(path);

            BuildAssetBundleOptions options = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets;
            BuildPipeline.PushAssetDependencies();

            if (strType[typeFileindex] != ".unity")
            {
                object asset = AssetDatabase.LoadMainAssetAtPath("Assets/" + filePathName + strType[typeFileindex]);
                Debug.Log(asset);
                if (asset == null || asset == "Null")
                {
                    this.ShowNotification(new GUIContent(filePathName + strType[typeFileindex] + "-此资源不存在!"));
                    return;
                }
                BuildPipeline.BuildAssetBundle(AssetDatabase.LoadMainAssetAtPath("Assets/" + filePathName + strType[typeFileindex]), null, path + "/" + fileName + ".unity3d", options);                    
            }
            else
            {
                Debug.Log("Scenec!!!");
                string[] str = { "Assets/" + filePathName + strType[typeFileindex] };
                //string path =  EditorUtility.SaveFilePanel("build bundle", "", "*", "unity3d");
                BuildPipeline.BuildStreamedSceneAssetBundle(str, path + "/" + fileName + ".unity3d", BuildTarget.WebPlayerStreamed);
            }
            this.ShowNotification(new GUIContent(filePathName + strType[typeFileindex] + " -打包成功!!"));
        }
        else
        {
            this.ShowNotification(new GUIContent("所填写的内容不能为空!!"));
        }
    }
}


对于第二种方式,就是在创建和保存时可以自己去选择目录。主要就是这个方法EditorUtility.SaveFilePanel ("Save Resource","","New Resource","unity3d");和EditorUtility.SaveFilePanel ("Save Resource","", "New Resource","unity3d");

具体的方式在http://docs.unity3d.com/Documentation/ScriptReference/BuildPipeline.BuildAssetBundle.html有具体的说明。可以根据上面写成一个窗口的方式,写为窗口的好处就是方便那么一点点。

 

 方便学习,发现了更加方便的打包方式。下面是学习的一些代码,根据自己的需求修改了一下下。这个的原文地址忘记了,属于转载内容。共同学习一下。

using UnityEngine;
using UnityEditor;
using System.IO;

public class Buildunity3d
{
    /*
    [@MenuItem("Build/AssetBundles PC")]
    static void ExportAssetBundles()
    {
        // Get the selected directory
        //获取选择的目录
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);
        Debug.Log("Selected Folder: " + path);
        if (path.Length != 0)
        {
            path = path.Replace("Assets/", "");
            string[] fileEntries = Directory.GetFiles(Application.dataPath + "/" + path);
            foreach (string fileName in fileEntries)
            {
                string filePath = fileName.Replace(" ", "/");
                int index = filePath.LastIndexOf("/");
                filePath = filePath.Substring(index);
                Debug.Log(filePath);
                string localPath = "Assets/" + path;
                if (index > 0)
                    //localPath += filePath;
                    Debug.Log(localPath);
                Object t = AssetDatabase.LoadMainAssetAtPath(localPath);
                if (t != null)
                {
                    Debug.Log(t.name);

                    if (!Directory.Exists(Application.dataPath + "/Build"))//判断文件夹是否已经存在
                    {
                        Directory.CreateDirectory(Application.dataPath + "/Build");//创建文件夹
                    }
                    string bundlePath = "Assets/" + "Build/" + t.name + ".unity3d";
                    Debug.Log("Building bundle at: " + bundlePath);
                    // Build the resource file from the active selection.
                    //从激活的选择编译资源文件
                    BuildPipeline.BuildAssetBundle
                    (t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);
                }
            }
        }
    }//*/

    [MenuItem("Build/Build AssetBundle From Selection - Track dependencies")]//(包含依耐关系)
    static void ExportResource()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {            
            // Build the resource file from the active selection.
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets);
            Selection.objects = selection;
            FileStream fs = File.Open(path + ".log", FileMode.OpenOrCreate);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine("文件 " + path + " 中的内容如下:");
            foreach (Object obj in Selection.objects)
            {
                sw.WriteLine("Name: " + obj.name + "Type:" + obj.GetType());
                if (obj.GetType() == typeof(Object))                {
                    Debug.LogWarning("Name: " + obj.name + ", Type: " + obj.GetType() + ". 可能是unity3d不能识别的文件,可能未被打包成功");
                }
            }

            sw.Flush();
            fs.Flush();
            sw.Close();
            fs.Close();

            /*
            BuildAssetBundleOptions.CollectDependencies 包含所有依赖关系,应该是将这个物体或组件所使用的其他资源一并打包
            BuildAssetBundleOptions.CompleteAssets 强制包括整个资源。例如,如果传递网格到BuildPipeline.BuildAssetBundle函数并使用CompleteAssets,它还将包括游戏物体和任意动画剪辑,在同样的资源。

            应该是,下载一部分,其余一并下载

            BuildAssetBundleOptions.DisableWriteTypeTree 禁用写入类型树,在资源包不包含类型信息。指定这个标识将使资源包易被脚本或Unity版本改变,但会使文件更小,更快一点加载。这个标识只影响默认包含的类型信息的平台资源包。

            BuildAssetBundleOptions.DeterministicAssetBundle 确定资源包,编译资源包使用一个哈希表储存对象ID在资源包中。

            这使您可以重建的资产包,并直接引用资源。当重建资源包对象,在重建之后保证有相同的ID。由于它是一个32位的哈希表空间,如果在资源包有许多对象,这将增加潜在哈希表冲突。

            Unity将给出一个错误,而不在这种情况下编译。哈希表是基于资源的GUID和对象的自身ID。

            DeterministicAssetBundle加载被标准资源包慢,这是因为线程后台加载API通常期望对象排序的方式,这会使读取加少寻址。

            */
            //GC
            System.GC.Collect();

        }
    }

    [MenuItem("Build/Build AssetBundle From Selection - No dependency tracking")]//(不包含依耐关系)
    static void ExportResourceNoTrack()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path, BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);
            FileStream fs = File.Open(path + ".log", FileMode.OpenOrCreate);
            StreamWriter sw = new StreamWriter(fs);            
            sw.WriteLine("文件 " + path + " 中的内容如下:");
            foreach (Object obj in Selection.objects)
            {
                sw.WriteLine("Name: " + obj.name + "Type: " + obj.GetType());
                if (obj.GetType() == typeof(Object))                {
                    Debug.LogWarning("Name: " + obj.name + ", Type: " + obj.GetType() + ". 可能是unity3d不能识别的文件,可能未被打包成功");                    
                }
            }
            sw.Flush();
            fs.Flush();
            sw.Close();
            fs.Close();
        }        
        //GC
        System.GC.Collect();
    }

    //------------------------------------------------------------------------------------------------------------------
    //单独打包文件夹中的每个文件为*.unity3d文件,放在原来的位置
    [MenuItem("Build/Build AssetBundles From Directory of Files")]
    static void ExportAssetBundleEachfile2Path()
    {
        //在项目视图从选择的文件夹生成资源包
        //记住,这个函数不跟踪依赖关系,也不是递归
        // Get the selected directory
        //获取选择的目录
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);
        string unity3dFileName;
        Debug.Log("Selected Folder: " + path);
        if (path.Length != 0)
        {
            int pos = path.LastIndexOf('/');
            if (pos == -1)
            {
                return;
            }
            unity3dFileName = path.Substring(pos + 1, path.Length - pos - 1);
            Debug.Log("unity3dFileName: " + unity3dFileName);
            path = path.Replace("Assets/", "");
            string[] fileEntries = Directory.GetFiles(Application.dataPath + "/" + path);
            foreach (string fileName in fileEntries)
            {
                string filePath = fileName.Replace(" ", "/");
                int index = filePath.LastIndexOf("/");
                filePath = filePath.Substring(index);
                Debug.Log(filePath);
                string localPath = "Assets/" + path;                
                if (index > 0)
                    //localPath += filePath;
                Debug.Log(localPath);
                Object t = AssetDatabase.LoadMainAssetAtPath(localPath);
                if (t != null)
                {
                    Debug.Log(t.name);
                    //string bundlePath = "Assets/" + path + "/" + t.name + ".unity3d";
                    string pathSelect = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
                    Debug.Log("Building bundle at: " + pathSelect);
                    // Build the resource file from the active selection.
                    //从激活的选择编译资源文件
                    BuildPipeline.BuildAssetBundle
                    (t, null, pathSelect, BuildAssetBundleOptions.CompleteAssets);
                }
            }
        }
        //GC
        System.GC.Collect();
    }


    [MenuItem("Build/Build AssetBundles by Directory")]
    static void ExportAssetBundleByDirectory()
    {
        //一次选择多个文件夹,分别打包,生成的unity3d文件按文件夹名字命名且放在文件夹中,同时生成.log文件
        int dirs = Selection.objects.Length, i;
        string[] filters = new string[]{//过滤不打包的文件类型
            ".unity3d",".log",".db",};

        for (i = 0; i < dirs; i++)//处理所选文件夹
        {
            string path = AssetDatabase.GetAssetPath(Selection.objects[i]);
            string unity3dFileName;
            if (path.Length != 0)
            {
                int pos = path.LastIndexOf('/');
                if (pos < 0) pos = 0;
                unity3dFileName = path.Substring(pos);
                //获取文件列表
                string[] fileEntries = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);//仅本级目录
                //过滤文件类型
                int size = 0;
                bool[] enable = new bool[fileEntries.Length];
                for (int how = 0; how < fileEntries.Length; how++)
                {
                    bool filterFlag = false;
                    foreach (string s in filters)
                    {
                        if (fileEntries[how].EndsWith(s, System.StringComparison.OrdinalIgnoreCase))
                        {
                            filterFlag = true;
                            break;
                        }

                    }
                    enable[how] = filterFlag;
                    if (!filterFlag) size++;
                }
                if (size != 0)
                {
                    Object[] objects = new Object[size];
                    //载入文件
                    int id = 0;
                    for (int k = 0; k < fileEntries.Length; k++)
                    {
                        if (enable[k] == false)
                        {
                            string fileName = fileEntries[k];
                            string localPath = fileName.Replace("", "/");
                            objects[id] = AssetDatabase.LoadMainAssetAtPath(localPath);//AssetDatabase.LoadAllAssetsAtPath不知为何不能用?
                            id++;
                        }

                    }

                    //打包
                    if (id != 0)
                    {
                        string str = path + unity3dFileName + ".unity3d";
                        BuildPipeline.BuildAssetBundle(objects[0], objects, str, BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);
                        FileStream fs = File.Open(path + unity3dFileName + ".log", FileMode.OpenOrCreate);
                        StreamWriter sw = new StreamWriter(fs);
                        sw.WriteLine("文件 " + str + " 中的内容如下:");
                        foreach (Object obj in objects)
                        {
                            sw.WriteLine("Name: " + obj.name + "Type: " + obj.GetType());
                            if (obj.GetType() == typeof(Object))
                            {
                                Debug.LogWarning("Name: " + obj.name + ", Type: " + obj.GetType() + ". 可能是unity3d不能识别的文件,可能未被打包成功");
                            }
                        }

                        sw.Flush();
                        fs.Flush();
                        sw.Close();
                        fs.Close();
                        Debug.Log("打包成功! " + str);
                    }

                    else
                    {
                        Debug.LogError("没有可打包的文件! 目录:" + path);
                    }
                }
                else
                {
                    Debug.LogError("没有可打包的文件! 全部被过滤, 目录:" + path);
                }
            }
        }
        //GC
        System.GC.Collect();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值