Unity 简单打包脚本

打包脚本

这个打包脚本适用于做demo,脚本放在Editor目录下

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

public class BuildAB
{
    [MenuItem("Tools/递归遍历文件夹下的资源并打包")]
    public static void BuildDirectory()
    {
        //需要打包的文件夹路径
        string path = Application.dataPath + "/Res";
        List<string> list = new List<string>();
        GetFilePath(path, ref list);

        List<AssetBundleBuild> mult = new List<AssetBundleBuild>();
        for (int i = 0; i < list.Count; i++)
        {
            string assetName = list[i].Replace(Application.dataPath, "Assets").Replace("\\", "/");
            string bundleName = Path.GetFileNameWithoutExtension(assetName);

            AssetBundleBuild ab = new AssetBundleBuild();
            ab.assetBundleName = bundleName;
            //assetNames记录bundle中所有资源的相对路径
            ab.assetNames = new string[] { assetName };
            mult.Add(ab);

            Debug.Log($"{assetName} {bundleName}");
        }

        string targetPath = Application.streamingAssetsPath;
        if (Directory.Exists(targetPath))
            Directory.Delete(targetPath, true);
        Directory.CreateDirectory(targetPath);

        BuildPipeline.BuildAssetBundles(targetPath, mult.ToArray(),
            BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);

        AssetDatabase.Refresh();
    }

    [MenuItem("Tools/遍历文件夹下的资源,处理依赖并打包")]
    public static void BuildDirectoryDependence()
    {
        string path = Application.dataPath + "/Res";
        List<string> list = new List<string>();
        GetFilePath(path, ref list);

        //key 资源路径,value 引用计数
        Dictionary<string, int> abDict = new Dictionary<string, int>();
        for (int i = 0; i < list.Count; i++)
        {
            string assetName = list[i].Replace(Application.dataPath, "Assets").Replace("\\", "/");

            //获取依赖资源,返回相对路径
            string[] dependences = AssetDatabase.GetDependencies(assetName);
            for(int j = 0; j < dependences.Length; ++j)
            {
                if (dependences[j].EndsWith(".cs"))
                {
                    continue;
                }

                Debug.Log($"{assetName} 依赖 {j} => {dependences[j]}");
                if (abDict.ContainsKey(dependences[j]))
                {
                    abDict[dependences[j]]++;
                }
                else
                {
                    abDict.Add(dependences[j], 1);
                }
            }
        }

        var enumerator = abDict.GetEnumerator();
        List<AssetBundleBuild> mult = new List<AssetBundleBuild>();
        while (enumerator.MoveNext())
        {
            string fileName = enumerator.Current.Key;
            int refCount = enumerator.Current.Value;

            string bundleName = Path.GetFileNameWithoutExtension(fileName);
            if(refCount > 1)
            {
                //引用计数大于1的为公共资源,单独打包
                bundleName = "common/" + bundleName;
            }

            AssetBundleBuild ab = new AssetBundleBuild();
            ab.assetBundleName = bundleName;
            //assetNames记录bundle中所有资源的相对路径
            ab.assetNames = new string[] { fileName };
            mult.Add(ab);
        }

        string targetPath = Application.streamingAssetsPath;
        if (Directory.Exists(targetPath))
            Directory.Delete(targetPath, true);
        Directory.CreateDirectory(targetPath);

        BuildPipeline.BuildAssetBundles(targetPath, mult.ToArray(),
            BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);

        AssetDatabase.Refresh();
    }

    /// 
    /// 递归获取所有文件路径
    /// 
    public static void GetFilePath(string path, ref List<string> list)
    {
        string[] files = Directory.GetFiles(path);
        for (int i = 0; i < files.Length; i++)
        {
            if (files[i].EndsWith(".cs") || files[i].EndsWith(".meta"))
            {
                continue;
            }

            list.Add(files[i]);
        }

        string[] dirs = Directory.GetDirectories(path);
        for(int i = 0; i < dirs.Length; i++)
        {
            GetFilePath(dirs[i], ref list);
        }
    }
}

Unity 简单打包脚本_第1张图片
前面的选项不会处理依赖关系,公共资源会打进不同的bundle里
后面的选项会处理依赖资源,引用计数大于1的认为是公共资源,单独打包到common文件夹

加载脚本

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

public class LoadAB : MonoBehaviour
{
    private AssetBundleManifest _manifest;
    private List<string> _abList = new List<string>();
    private Dictionary<string, GameObject> _assetDict = new Dictionary<string, GameObject>();

    void Start()
    {
        LoadManifest();
        LoadGameObject("cube");
    }

    void LoadManifest()
    {
        AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StreamingAssets");
        _manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    }

    private void LoadGameObject(string abName)
    {
        if (string.IsNullOrEmpty(abName))
            return;

        abName = abName.ToLower();

		//先加载依赖资源
        string[] dependens = _manifest.GetAllDependencies(abName);
        for (int i = 0; i < dependens.Length; ++i)
        {
            if (!_abList.Contains(dependens[i]))
            {
                AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependens[i]);
                _abList.Add(dependens[i]);
            }
        }

        if (!_abList.Contains(abName))
        {
            AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + abName);
            _abList.Add(abName);
            _assetDict.Add(abName, ab.LoadAsset<GameObject>(abName));
        }

        if (_assetDict.ContainsKey(abName))
        {
            GameObject.Instantiate(_assetDict[abName]);
        }
    }
}

参考

untiy AssetBundle 依赖关系树

你可能感兴趣的:(资源管理,unity)