先删除所有的AssetBundle标记
public static void clearAssetBundlesName()
{
//获取所有的AssetBundle名称
string[] abNames = AssetDatabase.GetAllAssetBundleNames();
//强制删除所有AssetBundle名称
for (int i = 0; i < abNames.Length; i++)
{
AssetDatabase.RemoveAssetBundleName(abNames[i], true);
}
}
递归遍历需要打包的目录,找出所有资源文件
[MenuItem("AssetBundleTools/Set AssetBundle Label")]
public static void setAssetBundleLabel()
{
//打包资源根目录
string abRootPath = string.Empty;
//根目录下的目录信息
DirectoryInfo[] abDirector;
//AssetDatabase.RemoveUnusedAssetBundleNames();
clearAssetBundlesName();
//获取打包资源根目录
abRootPath = PathTools.getABResourcesPath();
DirectoryInfo abRootDirector = new DirectoryInfo(abRootPath);
abDirector = abRootDirector.GetDirectories();
//遍历每一个场景目录
foreach (DirectoryInfo scenesDir in abDirector)
{
string assetName = scenesDir.Name;
findFile(scenesDir, assetName);
}
AssetDatabase.Refresh();
Debug.LogWarning("设置成功");
}
private static void findFile(DirectoryInfo scenesDir, string assetName)
{
//所有文件信息
FileInfo[] fileArr = scenesDir.GetFiles();
foreach (FileInfo fileInfo in fileArr)
{
setFileABLabel(fileInfo, assetName);
}
//所有文件夹信息
DirectoryInfo[] dirArr = scenesDir.GetDirectories();
foreach (DirectoryInfo dir in dirArr)
{
findFile(dir, assetName);
}
}
以场景和资源类型划分包体,包体名称为场景目录+场景目录下一级目录(资源类型)
Texture目录里的资源的包名为“Scenes_1/Texture”,如果有子目录,里面的资源也为“Scenes_1/Texture”
给资源文件设置标记,过滤掉unity自动生成的.meta文件
private static void setFileABLabel(FileInfo fileInfo, string assetName)
{
//忽视unity自身生成的meta文件
if (fileInfo.Extension == ".meta")
return;
int index = fileInfo.FullName.IndexOf("Assets");
//截取Assets之后的路径
//AssetImporter.GetAtPath必须是unity工程的相对路径
//所以要Assets开头
string filePath = fileInfo.FullName.Substring(index);
//通过AssetImporter指定要标记的文件
AssetImporter importer = AssetImporter.GetAtPath(filePath);
//区分场景文件和资源文件后缀名
if (fileInfo.Extension == ".unity")
importer.assetBundleVariant = "u3d";
else
importer.assetBundleVariant = "ab";
//包名称
string bundleName = string.Empty;
//需要拿到场景目录下面一级目录名称
//包名=场景目录名+下一级目录名
int indexScenes = fileInfo.FullName.IndexOf(assetName) + assetName.Length + 1;
string bundlePath = fileInfo.FullName.Substring(indexScenes);
//替换win路径里的反斜杠
bundlePath = bundlePath.Replace(@"\", "/");
Debug.Log(bundlePath);
if (bundlePath.Contains("/"))
{
string[] strArr = bundlePath.Split('/');
bundleName = assetName + "/" + strArr[0];
}
else
{
bundleName = assetName + "/" + assetName;
}
importer.assetBundleName = bundleName;
}
打包之前删除掉之前的旧资源
private static void DeleteAllAssetBundles(RuntimePlatform platform)
{
string outPath = string.Empty;
outPath = PathTools.getABOutPath(platform);
Debug.Log("删除资源:"+outPath);
if(!string.IsNullOrEmpty(outPath))
{
if (Directory.Exists(outPath))
{
Directory.Delete(outPath, true);
File.Delete(outPath + ".meta");
}
}
AssetDatabase.Refresh();
}
最后打包
[MenuItem("AssetBundleTools/BuildWindowsAssetBundles")]
public static void buildWindowsAssetBundle()
{
DeleteAllAssetBundles(RuntimePlatform.WindowsPlayer);
string outPath = string.Empty;
outPath = PathTools.getABOutPath(RuntimePlatform.WindowsPlayer);
if (!Directory.Exists(outPath))
{
Directory.CreateDirectory(outPath);
}
BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
AssetDatabase.Refresh();
}
通过PathTools来管理打包路径
public class PathTools
{
//AssetBundle资源路径
public const string AB_Resources = "/AB_Resources";
public static string getABResourcesPath()
{
return Application.dataPath + AB_Resources;
}
///
/// AssetBundle输出路径
///
///
public static string getABOutPath(RuntimePlatform platform)
{
return getPlatformPath(platform);
}
private static string getPlatformPath(RuntimePlatform platform)
{
string platformPath = string.Empty;
switch (platform)
{
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
platformPath = Application.streamingAssetsPath;
break;
case RuntimePlatform.IPhonePlayer:
case RuntimePlatform.Android:
platformPath = Application.persistentDataPath;
break;
default:
break;
}
return platformPath;
}
}
项目源码https://github.com/GhostRain/AssetBundleFramework.git