赞
踩
目录
Unity 基础 之 使用 WWW / UnityWebRequest / UnityWebRequestAssetBundle 加载 AssetBundle (AB包)的方法简单使用
Unity中的一些基础知识点。
本节介绍,在Unity 应用的时候,加载 AB 包的方式,WWW (老方法),UnityWebRequest (新方法,建议使用该方法)加载 AB 包的方式使用,方便以后进行热更新资源包使用。
1、WWW _www = new WWW(uriPath);
AssetBundle ab = _www.assetBundle;
2、UnityWebRequest request = UnityWebRequest.Get(uriPath);
byte[] results = request.downloadHandler.data;
AssetBundle ab = AssetBundle.LoadFromMemory(results);
3、UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uriPath);
AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
1、新建一个空工程
2、把资源打包成 ab 包 (BuildAB 脚本代码,贴在后面)
3、编写加载AB资源脚本 WWWAndUnitywebRequestLoadAB
4、把脚本挂载到场景中,并把场景中的 New Sprite 赋值脚本,用户来测试 AB 包中的图片
5、根据需要测试代码,运行场景,效果如上
1、WWWAndUnitywebRequestLoadAB
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Networking;
-
- public class WWWAndUnitywebRequestLoadAB : MonoBehaviour
- {
-
- public SpriteRenderer sr;
-
- string dirPath = Application.streamingAssetsPath + "/AB/tests/tests.ab";
-
- private void Start()
- {
- //StartCoroutine(WWWLoadAB(dirPath, (ab) => {
- // //实例化
- // GameObject obj = ab.LoadAsset<GameObject>("Cube");
- // Instantiate(obj);
- // Sprite sp = ab.LoadAsset<Sprite>("bird");
- // sr.sprite = sp;
- //}));
-
- //StartCoroutine(UnityWebRequestLoadAB1(dirPath, (ab) =>
- //{
- // //实例化
- // GameObject obj = ab.LoadAsset<GameObject>("Cube");
- // Instantiate(obj);
- // Sprite sp = ab.LoadAsset<Sprite>("bird");
- // sr.sprite = sp;
- //}));
-
- StartCoroutine(UnityWebRequestLoadAB2(dirPath, (ab) =>
- {
- //实例化
- GameObject obj = ab.LoadAsset<GameObject>("Cube");
- Instantiate(obj);
- Sprite sp = ab.LoadAsset<Sprite>("bird");
- sr.sprite = sp;
- }));
-
-
- }
-
- IEnumerator WWWLoadAB(string uriPath, Action<AssetBundle> loadABFinishedAction) {
- WWW _www = new WWW(uriPath);
- yield return _www;
- //检查是否发生错误
- if (string.IsNullOrEmpty(_www.error))
- {
- //检查AssetBundle是否为空
- if (_www.assetBundle != null)
- {
- AssetBundle ab = _www.assetBundle;
- if (loadABFinishedAction != null)
- {
- loadABFinishedAction(ab);
- }
- }
- }
- else
- {
- Debug.Log("_www.error: " + _www.error);
- }
-
- }
-
-
- IEnumerator UnityWebRequestLoadAB1(string uriPath, Action<AssetBundle> loadABFinishedAction)
- {
- UnityWebRequest request = UnityWebRequest.Get(uriPath);
- yield return request.SendWebRequest();
- if (request.isHttpError)
- {
- Debug.LogError(GetType() + "/ERROR/" + request.error);
- }
- else {
- byte[] results = request.downloadHandler.data;
- AssetBundle ab = AssetBundle.LoadFromMemory(results);
-
- if (loadABFinishedAction != null)
- {
- loadABFinishedAction(ab);
- }
- }
-
- }
-
- IEnumerator UnityWebRequestLoadAB2(string uriPath, Action<AssetBundle> loadABFinishedAction)
- {
- UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uriPath);
- yield return request.SendWebRequest();
- if (request.isHttpError)
- {
- Debug.LogError(GetType() + "/ERROR/" + request.error);
- }
- else
- {
-
- AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
-
- if (loadABFinishedAction != null)
- {
- loadABFinishedAction(ab);
- }
- }
-
- }
- }
2、BuildAB(仅供参考资源 ab 打包使用)
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using UnityEditor;
- using UnityEngine;
-
- public class BuildAB : Editor
- {
- static string dirPath = Application.streamingAssetsPath + "/AB";
-
- [MenuItem("ABTools/BuildAB ---- 把资源打包AB包资源")]
- static void ABXmlZipToStreamingAssetsPath()
- {
- RemoveABLabel();
- SetABLabel();
- ABBuilder();
- RemoveABLabel();
- //Directory.Delete(dirPath, true);
- AssetDatabase.Refresh();
-
- }
-
- static void ABBuilder()
- {
-
- if (Directory.Exists(dirPath) == false)
- {
- Directory.CreateDirectory(dirPath);
- }
- // BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath + "/AB", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
- BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath + "/AB", BuildAssetBundleOptions.None, BuildTarget.Android);
- // AssetDatabase.Refresh();
- }
-
- #region RemoveABLabel
-
- public static void RemoveABLabel()
- {
- // 需要移除标记的根目录
- string strNeedRemoveLabelRoot = string.Empty;
- // 目录信息(场景目录信息数组,表示所有根目录下场景目录)
- DirectoryInfo[] directoryDIRArray = null;
-
-
- // 定义需要移除AB标签的资源的文件夹根目录
- //strNeedRemoveLabelRoot = PathTools.GetABResourcesPath();
- strNeedRemoveLabelRoot = Application.dataPath + "/Resources";
- //Debug.Log("strNeedSetLabelRoot = "+strNeedSetLabelRoot);
-
- DirectoryInfo dirTempInfo = new DirectoryInfo(strNeedRemoveLabelRoot);
- directoryDIRArray = dirTempInfo.GetDirectories();
-
- // 遍历本场景目录下所有的目录或者文件
- foreach (DirectoryInfo currentDir in directoryDIRArray)
- {
- // 递归调用方法,找到文件,则使用 AssetImporter 类,标记“包名”与 “后缀名”
- JudgeDirOrFileByRecursive(currentDir);
- }
-
- // 清空无用的 AB 标记
- AssetDatabase.RemoveUnusedAssetBundleNames();
- // 刷新
- AssetDatabase.Refresh();
-
- // 提示信息,标记包名完成
- Debug.Log("AssetBundle 本次操作移除标记完成");
-
- }
-
- /// <summary>
- /// 递归判断判断是否是目录或文件
- /// 是文件,修改 Asset Bundle 标记
- /// 是目录,则继续递归
- /// </summary>
- /// <param name="fileSystemInfo">当前文件信息(文件信息与目录信息可以相互转换)</param>
- private static void JudgeDirOrFileByRecursive(FileSystemInfo fileSystemInfo)
- {
- // 调试信息
- //Debug.Log("currentDir.Name = " + fileSystemInfo.Name);
- //Debug.Log("sceneName = " + sceneName);
-
- // 参数检查
- if (fileSystemInfo.Exists == false)
- {
- Debug.LogError("文件或者目录名称:" + fileSystemInfo + " 不存在,请检查");
- return;
- }
-
- // 得到当前目录下一级的文件信息集合
- DirectoryInfo directoryInfoObj = fileSystemInfo as DirectoryInfo; // 文件信息转为目录信息
- FileSystemInfo[] fileSystemInfoArray = directoryInfoObj.GetFileSystemInfos();
-
- foreach (FileSystemInfo fileInfo in fileSystemInfoArray)
- {
- FileInfo fileInfoObj = fileInfo as FileInfo;
-
- // 文件类型
- if (fileInfoObj != null)
- {
- // 修改此文件的 AssetBundle 标签
- RemoveFileABLabel(fileInfoObj);
- }
- // 目录类型
- else
- {
-
- // 如果是目录,则递归调用
- JudgeDirOrFileByRecursive(fileInfo);
- }
- }
- }
-
- /// <summary>
- /// 给文件移除 Asset Bundle 标记
- /// </summary>
- /// <param name="fileInfoObj">文件(文件信息)</param>
- static void RemoveFileABLabel(FileInfo fileInfoObj)
- {
- // 调试信息
- //Debug.Log("fileInfoObj.Name = " + fileInfoObj.Name);
- //Debug.Log("scenesName = " + scenesName);
-
- // 参数定义
- // AssetBundle 包名称
- string strABName = string.Empty;
- // 文件路径(相对路径)
- string strAssetFilePath = string.Empty;
-
- // 参数检查(*.meta 文件不做处理)
- if (fileInfoObj.Extension == ".meta")
- {
- return;
- }
-
- // 得到 AB 包名称
- strABName = string.Empty;
- // 获取资源文件的相对路径
- int tmpIndex = fileInfoObj.FullName.IndexOf("Assets");
- strAssetFilePath = fileInfoObj.FullName.Substring(tmpIndex); // 得到文件相对路径
-
-
- // 给资源文件移除 AB 名称
- AssetImporter tmpImportObj = AssetImporter.GetAtPath(strAssetFilePath);
- tmpImportObj.assetBundleName = strABName;
-
-
- }
-
- #endregion
-
- #region SetABLabel
-
- public static void SetABLabel()
- {
-
- // 需要做标记的根目录
- string strNeedSetLabelRoot = string.Empty;
- // 目录信息(场景目录信息数组,表示所有根目录下场景目录)
- DirectoryInfo[] directoryDIRArray = null;
-
- // 清空无用的 AB 标记
- AssetDatabase.RemoveUnusedAssetBundleNames();
-
-
- // 定义需要打包资源的文件夹根目录
- //strNeedSetLabelRoot = PathTools.GetABResourcesPath();
- strNeedSetLabelRoot = Application.dataPath + "/Resources/XAN/AB";
- //Debug.Log("strNeedSetLabelRoot = "+strNeedSetLabelRoot);
-
- DirectoryInfo dirTempInfo = new DirectoryInfo(strNeedSetLabelRoot);
- directoryDIRArray = dirTempInfo.GetDirectories();
-
- //2、 遍历本场景目录下所有的目录或者文件
- foreach (DirectoryInfo currentDir in directoryDIRArray)
- {
- //2.1:遍历本场景目录下所有的目录或者文件
- // 如果是目录,则继续“递归”访问里面的文件,直到定位到文件
- string tmpScenesDir = strNeedSetLabelRoot + "/" + currentDir.Name; // Unity /xx/xx 全路径
- //DirectoryInfo tmpScenesDirInfo = new DirectoryInfo(tmpScenesDir);
- int tmpIndex = tmpScenesDir.LastIndexOf("/");
- string tmpScenesName = tmpScenesDir.Substring(tmpIndex + 1); // 场景名称
- //Debug.Log("tmpScenesDir = "+ tmpScenesDir);
-
- //2、2 递归调用方法,找到文件,则使用 AssetImporter 类,标记“包名”与 “后缀名”
- JudgeDirOrFileByRecursive(currentDir, tmpScenesName);
- }
-
- // 刷新
- AssetDatabase.Refresh();
-
- // 提示信息,标记包名完成
- Debug.Log("AssetBundle 本次操作设置标记完成");
- }
-
- /// <summary>
- /// 递归判断判断是否是目录或文件
- /// 是文件,修改 Asset Bundle 标记
- /// 是目录,则继续递归
- /// </summary>
- /// <param name="fileSystemInfo">当前文件信息(文件信息与目录信息可以相互转换)</param>
- /// <param name="sceneName">当前场景名称</param>
- private static void JudgeDirOrFileByRecursive(FileSystemInfo fileSystemInfo, string sceneName)
- {
- // 调试信息
- //Debug.Log("currentDir.Name = " + fileSystemInfo.Name);
- //Debug.Log("sceneName = " + sceneName);
-
- // 参数检查
- if (fileSystemInfo.Exists == false)
- {
- Debug.LogError("文件或者目录名称:" + fileSystemInfo + " 不存在,请检查");
- return;
- }
-
- // 得到当前目录下一级的文件信息集合
- DirectoryInfo directoryInfoObj = fileSystemInfo as DirectoryInfo; // 文件信息转为目录信息
- FileSystemInfo[] fileSystemInfoArray = directoryInfoObj.GetFileSystemInfos();
-
- foreach (FileSystemInfo fileInfo in fileSystemInfoArray)
- {
- FileInfo fileInfoObj = fileInfo as FileInfo;
-
- // 文件类型
- if (fileInfoObj != null)
- {
- // 修改此文件的 AssetBundle 标签
- SetFileABLabel(fileInfoObj, sceneName);
- }
- // 目录类型
- else
- {
-
- // 如果是目录,则递归调用
- JudgeDirOrFileByRecursive(fileInfo, sceneName);
- }
- }
- }
-
- /// <summary>
- /// 给文件打 Asset Bundle 标记
- /// </summary>
- /// <param name="fileInfoObj">文件(文件信息)</param>
- /// <param name="scenesName">场景名称</param>
- static void SetFileABLabel(FileInfo fileInfoObj, string scenesName)
- {
- // 调试信息
- //Debug.Log("fileInfoObj.Name = " + fileInfoObj.Name);
- //Debug.Log("scenesName = " + scenesName);
-
- // 参数定义
- // AssetBundle 包名称
- string strABName = string.Empty;
- // 文件路径(相对路径)
- string strAssetFilePath = string.Empty;
-
- // 参数检查(*.meta 文件不做处理)
- if (fileInfoObj.Extension == ".meta")
- {
- return;
- }
-
- // 得到 AB 包名称
- strABName = GetABName(fileInfoObj, scenesName);
- // 获取资源文件的相对路径
- int tmpIndex = fileInfoObj.FullName.IndexOf("Assets");
- strAssetFilePath = fileInfoObj.FullName.Substring(tmpIndex); // 得到文件相对路径
-
-
- // 给资源文件设置AB名称以及后缀
- AssetImporter tmpImportObj = AssetImporter.GetAtPath(strAssetFilePath);
- tmpImportObj.assetBundleName = strABName;
-
- // 判断文件是否是场景文件
- if (fileInfoObj.Extension == ".unity")
- {
- // 定义AB包的场景扩展名
- tmpImportObj.assetBundleVariant = "u3d";
- }
- else
- {
- // 定义AB包的非场景扩展名
- tmpImportObj.assetBundleVariant = "ab";
- }
- }
-
- /// <summary>
- /// 获取 AB 包的名称
- /// </summary>
- /// <param name="fileInfoObj">文件信息</param>
- /// <param name="scenesName">场景名称</param>
- /// AB 包名形成规则:
- /// 文件AB包名称 = “所在二级目录名称”(场景名称)+“三级目录名称”(类型名称)
- /// <returns></returns>
- static string GetABName(FileInfo fileInfoObj, string scenesName)
- {
- // 返回AB包名称
- string strABName = string.Empty;
-
- // win 路径
- string tmpWinPath = fileInfoObj.FullName;
- // 转为 Unity 路径格式
- string tmpUnityPath = tmpWinPath.Replace("\\", "/");
-
- // 定位“场景名称”后面字符位置
- int tmpSceneNamePosition = tmpUnityPath.IndexOf(scenesName) + scenesName.Length;
- // AB 包中 “类型名称”所在区域
- string strABFileNameArea = tmpUnityPath.Substring(tmpSceneNamePosition + 1);
- //测试
- //Debug.Log(" strABFileNameArea = " + strABFileNameArea);
-
- // 非场景资源
- if (strABFileNameArea.Contains("/"))
- {
- string[] tmpStrArray = strABFileNameArea.Split('/');
-
- //测试
- //Debug.Log("tmpStrArray[0] = "+ tmpStrArray[0]);
-
- // AB 包名称正式形成
- strABName = scenesName + "/" + tmpStrArray[0];
- }
- // 场景资源
- else
- {
- // 定义*.unity 文件形成的特殊 AB 包名称
- strABName = scenesName + "/" + scenesName;
- }
-
-
- return strABName;
- }
-
- #endregion
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。