Unity AssetBundle 之 (进阶)简单的自动给资源打上 AssetBundle 标签(分平台),方便 AssetBundle 打包的方法
目录
Unity AssetBundle 之 (进阶)简单的自动给资源打上 AssetBundle 标签(分平台),方便 AssetBundle 打包的方法
一、简单介绍
Unity中的一些基础知识点。
本节介绍,Asset Bundle 在 Unity中的使用,进阶第一篇,如何给需要打包 Asset Bundle 的资源自动打上标签,而不是手动一个一个标签的方法,有不对的地方欢迎指正。
二、实现原理
1、使用 Editor 脚本,指定资源文件夹,AssetImporter 进行资源 AssetBundle 标记标签
2、标签原理,场景名称/功能文件夹名 的方式标记标签
3、使用递归,标记非文件夹,且不是.meta 的文件
4、文件类型为.unity 标签后缀为u3d,其他文件类型均标记为.ab
三、注意事项
1、文件夹和文件,建议同一个场景功能文件夹下尽量别有重名的文件或者文件夹(与Unity自身标签机制有些关系)
四、效果预览
五、实现步骤
1、打开Unity,新建一个空工程
2、把资源导进来,这里 AssetBundle 标记标签的文件夹为 AB_Resources,文件结构如下,需要标记的资源如图功能文件夹放置
3、新建脚本 AutoSetAssetBundleLabel ,用于给指定的文件夹资源打上AB标签,PathTools 一些 AB 路径的管理脚本
4、菜单栏就会有 AssetBundleTools -- Set AB Label 工具
5、点击Set AB Label ,就会自动给指定的文件夹资源打上AB 标签(头一次打标签可能会较慢,根据资源情况),打完之后会有一个提示
6、对应资源就自动打上了对应的标签
六、关键脚本
1、AutoSetAssetBundleLabel
/****************************************************
文件:AutoSetAssetBundleLabel.cs
作者:仙魁XAN
邮箱:https://blog.csdn.net/u014361280
日期:2020/08/12 09:17:14
功能:Asset Bundle 簡單框架
开发思路:
1、 定义需要打包资源的文件夹根目录
2、遍历每个“场景”文件夹(目录)
2.1:遍历本场景目录下所有的目录或者文件
如果是目录,则继续“递归”访问里面的文件,直到定位到文件
2.2:递归调用方法,找到文件,则使用 AssetImporter 类,标记“包名”与 “后缀名”
*****************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
namespace ABFw
{
public class AutoSetAssetBundleLabel
{
/// <summary>
/// 设置AB包名
/// </summary>
[MenuItem("AssetBundleTools/Set AB Label")]
public static void SetABLabel() {
// 需要做标记的根目录
string strNeedSetLabelRoot = string.Empty;
// 目录信息(场景目录信息数组,表示所有根目录下场景目录)
DirectoryInfo[] directoryDIRArray = null;
// 清空无用的 AB 标记
AssetDatabase.RemoveUnusedAssetBundleNames();
// 定义需要打包资源的文件夹根目录
strNeedSetLabelRoot = PathTools.GetABResourcesPath();
//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;
}
}//class_End
}
2、PathTools
/****************************************************
文件:PathTools.cs
作者:仙魁XAN
邮箱:https://blog.csdn.net/u014361280
日期:2020/08/14 17:11:52
功能:AB框架的 路径工具类
1、路径常量
2、路径方法
*****************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ABFw
{
public class PathTools
{
/* 路径常量 */
public const string AB_RESOURCES = "AB_Resources"; // 打包AB包根路径
/* 路径方法 */
/// <summary>
/// 得到 AB 资源的输入目录
/// </summary>
/// <returns></returns>
public static string GetABResourcesPath() {
return Application.dataPath + "/" + AB_RESOURCES;
}
/// <summary>
/// 获得 AB 包输出路径
/// 1\ 平台(PC/移动端等)路径
/// 2\ 平台名称
/// </summary>
/// <returns></returns>
public static string GetABOutPath() {
return GetPlatformPath() + "/" + GetPlatformName();
}
/// <summary>
/// 获得平台路径
/// </summary>
/// <returns></returns>
private static string GetPlatformPath() {
string strReturenPlatformPath = string.Empty;
switch (Application.platform)
{
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
strReturenPlatformPath = Application.streamingAssetsPath;
break;
case RuntimePlatform.IPhonePlayer:
case RuntimePlatform.Android:
strReturenPlatformPath = Application.persistentDataPath;
break;
default:
break;
}
return strReturenPlatformPath;
}
/// <summary>
/// 获得平台名称
/// </summary>
/// <returns></returns>
public static string GetPlatformName()
{
string strReturenPlatformName = string.Empty;
switch (Application.platform)
{
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
strReturenPlatformName = "Windows";
break;
case RuntimePlatform.IPhonePlayer:
strReturenPlatformName = "IPhone";
break;
case RuntimePlatform.Android:
strReturenPlatformName = "Android";
break;
default:
break;
}
return strReturenPlatformName;
}
/// <summary>
/// 返回 WWW 下载 AB 包加载路径
/// </summary>
/// <returns></returns>
public static string GetWWWAssetBundlePath() {
string strReturnWWWPath = string.Empty;
switch (Application.platform)
{
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
strReturnWWWPath = "file://"+GetABOutPath();
break;
case RuntimePlatform.IPhonePlayer:
strReturnWWWPath = GetABOutPath()+"/Raw/";
break;
case RuntimePlatform.Android:
strReturnWWWPath = "jar:file://"+GetABOutPath();
break;
default:
break;
}
return strReturnWWWPath;
}
}//Class_End
}