代码参考蛮牛教育CTO教你万能框架教程
利用Editor统一AssetBundle的命名规则。
文件结构如下所示
命名规则:
1.对Art/Scenes下文件进行命名,所有文件的AssetBundleName为Scenes下二级子文件夹名称,例如:Cube(1)的assetBundleName为sceneone/font
2.其中普通文件.ld,场景文件后缀.u3d
代码如下
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
public class AssetBundleEditor : Editor
{
[MenuItem("ITools/BuildeAssetBundle")]
public static void BuildAssetBundle()
{
BuildPipeline.BuildAssetBundles(Application.dataPath + "/AssetBundle", 0, EditorUserBuildSettings.activeBuildTarget);
//刷新
AssetDatabase.Refresh();
}
[MenuItem("ITools/MarkAssetBundle")]
public static void MarkAssetBundle()
{
AssetDatabase.RemoveUnusedAssetBundleNames();
string path = Application.dataPath + "/Art/Scenes";
DirectoryInfo dir = new DirectoryInfo(path);
FileSystemInfo[] fileInfo = dir.GetFileSystemInfos();
for (int i = 0; i < fileInfo.Length; i++)
{
FileSystemInfo tmpFile = fileInfo[i];
if (tmpFile is DirectoryInfo)
{
string tmpPath = Path.Combine(path, tmpFile.Name);
ScenesOverView(tmpPath);
}
}
//刷新
AssetDatabase.Refresh();
}
/// <summary>
/// 遍历文件并生成记录文件,文件名:文件夹名称+Record.txt
/// </summary>
/// <param name="path">文件路径</param>
private static void ScenesOverView(string path)
{
string textFileName = "Record.txt";
string tmpPath = path + textFileName;
FileStream fs = new FileStream(tmpPath, FileMode.OpenOrCreate);
StreamWriter bw = new StreamWriter(fs);
//存储对应关系
Dictionary<string, string> theWriter = new Dictionary<string, string>();
GetRelativePath(path, theWriter);
foreach (var item in theWriter)
{
bw.WriteLine(item.Key + " | " + item.Value);
}
bw.Close();
fs.Close();
}
// D:/XXXX/Assets/Art/Scenes\\XXX/XXX/...
// SceneOne/load
/// <summary>
/// 截取相对路径
/// </summary>
/// <param name="fullPath">完整路径</param>
/// <param name="theWriter">文本记录</param>
public static void GetRelativePath(string fullPath, Dictionary<string, string> theWriter)
{
// 得到 D:/XXXX/ 总长度
int tmpCount = fullPath.IndexOf("Assets");
int tmpLength = fullPath.Length;
//得到 Assets/Art/Scenes\\XXX/XXX/... 相对路径
string relativePath = fullPath.Substring(tmpCount, tmpLength - tmpCount);
DirectoryInfo dir = new DirectoryInfo(fullPath);
if (dir != null)
{
ListFiles(dir, relativePath, theWriter);
}
else
{
Debug.LogError("Path " + fullPath + " is not exit");
}
}
/// <summary>
/// 递归法遍历文件夹下每一个文件
/// </summary>
public static void ListFiles(FileSystemInfo info, string relativePath, Dictionary<string, string> theWriter)
{
if (!info.Exists)
{
Debug.LogError("info is not exit");
return;
}
DirectoryInfo dir = info as DirectoryInfo;
FileSystemInfo[] files = dir.GetFileSystemInfos();
for (int i = 0; i < files.Length; i++)
{
FileInfo file = files[i] as FileInfo;
//对文件的操作,如果是文件夹就继续递归循环,如果是文件就更变其Mark值
if (file != null)
{
ChangeMark(file, relativePath, theWriter);
}
//对目录的操作,递归
else
{
ListFiles(files[i], relativePath, theWriter);
}
}
}
/// <summary>
/// 改变文件标记
/// </summary>
public static void ChangeMark(FileInfo tmpFile, string relativePath, Dictionary<string, string> theWriter)
{
if (tmpFile.Extension == ".meta")
{
return;
}
Debug.Log("ChangeFile>>=======================================================");
string markStr = GetBundlePath(tmpFile, relativePath);
Debug.Log("markStr ==" + markStr);
ChangeAssetMark(tmpFile, markStr, theWriter);
}
/// <summary>
/// 计算mark 标记值
/// </summary>
public static string GetBundlePath(FileInfo file, string relativePath)
{
// D:\\XXX\\XXX此方法获得的路径斜杠方向不同
string tmpPath = file.FullName;
tmpPath = FixedWindowsPath(tmpPath);
relativePath = FixedWindowsPath(relativePath);
Debug.Log("fullPath ==" + tmpPath);
Debug.Log("relativePath ==" + relativePath);
//Assets/Art/Scenes/SceneOne/load
//Assets/Art/Scenes/SceneOne/
int assetCount = tmpPath.IndexOf(relativePath);
assetCount += relativePath.Length + 1;;
int nameCount = tmpPath.LastIndexOf(file.Name);
int tmpLength = nameCount - assetCount;
int tmpCount = relativePath.LastIndexOf("/");
string sceneHead = relativePath.Substring(tmpCount + 1, relativePath.Length - tmpCount - 1);
//sceneHead == SceneOne
//Load\TestThree\
if (tmpLength > 0)
{
//Load/TestThree/TestThree.prefab
string subString = tmpPath.Substring(assetCount, tmpPath.Length - assetCount);
string[] result = subString.Split("/".ToCharArray());
//SceneOne + Load
return sceneHead + "/" + result[0];
}
else
{
//场景文件 所标记
return sceneHead;
}
}
public static void ChangeAssetMark(FileInfo tmpFile, string markStr, Dictionary<string, string> theWriter)
{
string fullPath = tmpFile.FullName;
int assetCount = fullPath.IndexOf("Assets");
string assetPath = fullPath.Substring(assetCount, fullPath.Length - assetCount);
// assets/sceneone/load/test.prefab
AssetImporter importer = AssetImporter.GetAtPath(assetPath);
//改变标记
importer.assetBundleName = markStr;
if (tmpFile.Extension == ".unity")
{
importer.assetBundleVariant = "u3d";
}
else
{
importer.assetBundleVariant = "ld";
}
//Load -- SceneOne/load
string modleName = "";
string[] subMark = markStr.Split("/".ToCharArray());
if (subMark.Length > 1)
{
modleName = subMark[1];
}
else
{
//Load -- SceneOne
modleName = markStr;
}
//sceneone/load.ld
string modlePath = markStr.ToLower() + "." + importer.assetBundleVariant;
if (!theWriter.ContainsKey(modleName))
theWriter.Add(modleName, modlePath);
}
public static string FixedWindowsPath(string path)
{
path = path.Replace("\\", "/");
return path;
}
}
ITools/MarkAssetBundle运行结果
ITools/BuildeAssetBundle 运行结果
Record.txt内容