• Unity5 AssetBundle 打包以及加载


    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEditor;
    using System.IO;
    
    public class BuildAssetBundle : Editor {
    
        //需要打包的路径,根据项目具体需求自己定
        private static string assetPath = "AllAssets";
    
        //导出包路径
        private static string AssetBundleOutPsth = "Assets/StreamingAssets";
    
        //保存需要打包的资源路径
        private static List<string> assetPathList = new List<string>();
    
        //需要打包的资源后缀
        private static Dictionary<string, string> asExtensionDic = new Dictionary<string, string> ();
    
        [MenuItem("Assets/BuildAssetBundle")]
        private static void BuildAssetBundleSource()
        {
            assetPathList.Clear (); 
    
            //根据不同平台拼接不同平台导出路径
            string outPsth = Path.Combine (AssetBundleOutPsth, Plathform.GetPlatformFolder(EditorUserBuildSettings.activeBuildTarget));
    
            GetDirs(Application.dataPath + "/" + assetPath);
    
            BuildAsset (outPsth);
        }
    
        //添加需要打包资源的后缀
        private static void SetASExtensionDic ()
        {
            asExtensionDic.Clear ();
    
            asExtensionDic.Add (".prefab", ".unity3d");
            asExtensionDic.Add (".mat", ".unity3d");
            asExtensionDic.Add (".png", ".unity3d");
        }
    
        //遍历制定文件夹获取需要打包的资源路径
        private static void GetDirs(string dirPath)
        {
            foreach (string path in Directory.GetFiles(dirPath))
            {
                // 通过资源后缀判断资源是否为需要打包的资源
                if (asExtensionDic.ContainsKey(System.IO.Path.GetExtension(path)))
                {
                    //将需要打包的资源路径添加到打包路劲中
                    assetPathList.Add(path);
                }
            }
    
            if (Directory.GetDirectories(dirPath).Length > 0)  //遍历所有文件夹
            {
                foreach (string path in Directory.GetDirectories(dirPath))
                {
                    //使用递归方法遍历所有文件夹
                    GetDirs(path);
                }
            }
        }
    
        //清除已经打包的资源 AssetBundleNames
        private static void ClearAssetBundlesName()
        {
            int length = AssetDatabase.GetAllAssetBundleNames ().Length;
            Debug.Log (length);
            string[] oldAssetBundleNames = new string[length];
            for (int i = 0; i < length; i++) 
            {
                oldAssetBundleNames[i] = AssetDatabase.GetAllAssetBundleNames()[i];
            }
    
            for (int j = 0; j < oldAssetBundleNames.Length; j++) 
            {
                AssetDatabase.RemoveAssetBundleName(oldAssetBundleNames[j],true);
            }
        }
    
        //打AS包
        private static void BuildAsset(string outPath)
        {
            //遍历获取到的打包资源路径
            for (int i = 0; i < assetPathList.Count; i ++) 
            {
                string asPath = assetPathList[i];
    
                //通过资源路径来获取需要打包的资源
                AssetImporter assetImporter = AssetImporter.GetAtPath(asPath);
                if (assetImporter == null)
                {
                    continue;
                }
    
                // 从此处(assetPath = "AllAssets")截取路径  
                string assetName = asPath.Substring(asPath.IndexOf(assetPath));
                //替换后缀名
                assetName = assetName.Replace(Path.GetExtension(assetName), ".unity3d");
                //设置打包资源的名字包括后缀
                assetImporter.assetBundleName = assetName;
            }
    
            //如果不存在到处路径文件,创建一个
            if (!Directory.Exists (outPath)) {
                Directory.CreateDirectory(outPath);
            }
    
            //打包
            BuildPipeline.BuildAssetBundles (outPath, 0, EditorUserBuildSettings.activeBuildTarget);
    
            //刷新资源路径,避免生成的文件不显示
            AssetDatabase.Refresh ();
        }
    }
    
    
    //根据切换的平台返回相应的导出路径
    public class Plathform
    {
        public static string GetPlatformFolder(BuildTarget target)
        {
            switch (target)
            {
            case BuildTarget.Android:   //Android平台导出到 Android文件夹中
                return "Android";
            case BuildTarget.iOS:
                return "IOS";
            case BuildTarget.WebPlayer:
                return "WebPlayer";
            case BuildTarget.StandaloneWindows:
            case BuildTarget.StandaloneWindows64:
                return "Windows";
            case BuildTarget.StandaloneOSXIntel:
            case BuildTarget.StandaloneOSXIntel64:
            case BuildTarget.StandaloneOSXUniversal:
                return "OSX";
            default:
                return null;
            }
        }
    
    }

    操作如下,以项目为例 

    在 StreamingAssets文件夹下生成AB文件

    打比完毕,每个资源自动打包出两个文件 

    下面是加载,封装了一下加载代码如下

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System;
    using System.IO;
    
    // 回调方法
    public delegate void CallBack(UnityEngine.Object obj);
    
    // AS 文件只能加载一次,重复加载出错,两种方案,
    // 一、加载后卸载,下次需要使用时重新加载,
    // 二、加载后将AS保存起来,下载加载相同AS时直接取出来使用
    public class LoadAssetBundle{
        //单例
        public static readonly LoadAssetBundle Instance = new LoadAssetBundle();
    
        private string path = Application.streamingAssetsPath;
    
        //保存加载的AS
        private Dictionary<string, AssetBundle> assetBundleRefDic = new Dictionary<string, AssetBundle>();
    
        //PC本地资源需加上  "file://"
        private string GetThePathWithPlathform
        {
            get
            {
                if (Application.isEditor)
                {
                    return "file://" + path;
                }
                else
                {
                    return path;
                }
            }
        }
    
        // 加载后释放
        // assetPath      加载资源路径
        // assetName      资源名
        // type           加载资源类型
        // callBack       加载完成回调
        // isUnload       加载后是否卸载
        public IEnumerator Load(string assetPath, string assetName, Type type, CallBack callBack, bool isUnload)
        {
            string loadpath = GetThePathWithPlathform;
            string url = Path.Combine(loadpath, assetPath);
    
            AssetBundle ab = GetASFromUrl (url);
    
            if (ab != null) {
                GetObject (ab, assetName, type, callBack, isUnload);
    
                yield return null;
            } 
            else 
            {
                WWW www = WWW.LoadFromCacheOrDownload (url, 0);
    
                yield return www;
    
                if (!string.IsNullOrEmpty (www.error)) {
                    Debug.LogError (www.error);
                    yield return null;
                }
                else
                {
                    ab = www.assetBundle;
                    GetObject ( ab, assetName, type, callBack, isUnload);
    
                    if (!isUnload)
                    {
                        if (!assetBundleRefDic.ContainsKey(url))
                        {
                            Debug.Log("add");
                            assetBundleRefDic.Add(url, ab);
                        }
                    }
                }
            }
        }
    
        //从 AssetBundle 中将资源加载出来
        private void GetObject(AssetBundle ab, string assetName, Type type, CallBack callBack, bool isUnload)
        {
            UnityEngine.Object obj = ab.LoadAsset (assetName, type);
    
            if (callBack != null)
            {
                callBack(obj);  // 回调
            }
    
            if (isUnload) {
                // 加载资源后从内存中卸载
                ab.Unload (true);
            }
        }
    
        //根据地址从字典中获取 AssetBundle
        private AssetBundle GetASFromUrl(string url)
        {
            AssetBundle ab = null;
            if (assetBundleRefDic.TryGetValue (url, out ab)) {
                return ab;
            }
    
            return null;
        }
    }
    //调用如下
    
    using UnityEngine;
    using System.Collections;
    
    public class Test : MonoBehaviour {
    
        // Update is called once per frame
        void Update () {
            if (Input.GetKeyDown (KeyCode.A)) 
            {
                string loadPath = "Android/allassets/gameobject.unity3d";
                string asName = "gameobject";
                StartCoroutine(LoadAssetBundle.Instance.Load(loadPath, asName, typeof(GameObject), CallBack, true));
            }
    
            if (Input.GetKeyDown (KeyCode.D)) 
            {
                string loadPath = "Android/allassets/gameobject.unity3d";
                string asName = "gameobject";
                StartCoroutine(LoadAssetBundle.Instance.Load(loadPath, asName, typeof(GameObject), CallBack, false));
            }
        }
    
        private void CallBack(UnityEngine.Object obj)
        {
            Debug.Log (obj.name);
            GameObject.Instantiate ((GameObject)obj);
        }
    }
  • 相关阅读:
    Python安装
    php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法
    关闭sublime自动检测更新提示
    Linux系统基本命令操作汇总
    jQuery各版本CDN
    【分享】每个 Web 开发者在 2021 年必须拥有 15 个 VSCode 扩展
    React & Redux 实战 Reminder Pro 项目 免费视频教程(5 个视频)
    Redux 入门教程(React 进阶)(20 个视频)
    Nodejs + Express + MongoDB 基础篇(17 个视频)
    轻松学 nodejs
  • 原文地址:https://www.cnblogs.com/lihonglin2016/p/4997106.html
Copyright © 2020-2023  润新知