构建AB包

using System. Collections;
using System. Collections. Generic;
using UnityEngine;
using UnityEditor;
using System. IO;
using System. Security. Cryptography;
using System. Text;

/// < summary >
/// AssetBundle编辑
/// </ summary >
public class AssetBundleEditor
{
#region 自动做标记

//思路
//1.找到资源保存的文件夹
//2.遍历里面的每个场景文件夹
//3.遍历场景文件夹里的所有文件系统
//4.如果访问的是文件夹:再继续访问里面的所有文件系统,直到找到 文件 (递归)
//5.找到文件 就要修改他的 assetbundle labels
//6.用 AssetImporter 类 修改名称和后缀
//7.保存对应的 文件夹名 和 具体路径

[ MenuItem( "AssetBundle/Set AssetBundle Labels")]
public static void SetAssetBundleLabels()
{
//移除所有没有使用的标记
AssetDatabase. RemoveUnusedAssetBundleNames();

//1.找到资源保存的文件夹
string assetDirectory = Application. dataPath + "/Res";
//Debug.Log(assetDirectory);

DirectoryInfo directoryInfo = new DirectoryInfo( assetDirectory);
DirectoryInfo[] sceneDirectories = directoryInfo. GetDirectories();
//2.遍历里面的每个场景文件夹
foreach ( DirectoryInfo tmpDirectoryInfo in sceneDirectories)
{
string sceneDirectory = assetDirectory + "/" + tmpDirectoryInfo. Name;
DirectoryInfo sceneDirectoryInfo = new DirectoryInfo( sceneDirectory);
//错误检测
if ( sceneDirectoryInfo == null)
{
Debug. LogError( sceneDirectory + " 不存在!");
return;
}
else
{
Dictionary< string, string> namePahtDict = new Dictionary< string, string>();

//3.遍历场景文件夹里的所有文件系统
//sceneDirectory
//C:\Users\张晋枭\Documents\ABLesson\Assets\AssetBundles\Res\Scene1

//C:/Users/张晋枭/Documents/ABLesson/Assets/AssetBundles/Res/Scene1
int index = sceneDirectory. LastIndexOf( "/");
string sceneName = sceneDirectory. Substring( index + 1);
onSceneFileSystemInfo( sceneDirectoryInfo, sceneName, namePahtDict);

onWriteConfig( sceneName, namePahtDict);
}
}

AssetDatabase. Refresh();

Debug. Log( "设置成功");
}

/// < summary >
/// 记录配置文件
/// </ summary >
private static void onWriteConfig( string sceneName, Dictionary< string, string> namePathDict)
{
string path = PathUtil. GetAssetBundleOutPath() + "/" + sceneName + "Record.txt";
// Debug.Log(path);

using ( FileStream fs = new FileStream( path, FileMode. OpenOrCreate, FileAccess. Write))
{
//写二进制
using ( StreamWriter sw = new StreamWriter( fs))
{
sw. WriteLine( namePathDict. Count);

foreach ( KeyValuePair< string, string> kv in namePathDict)
sw. WriteLine( kv. Key + " " + kv. Value);
}
}

}

/// < summary >
/// 遍历场景文件夹里的所有文件系统
/// </ summary >
private static void onSceneFileSystemInfo( FileSystemInfo fileSystemInfo, string sceneName, Dictionary< string, string> namePahtDict)
{
if (! fileSystemInfo. Exists)
{
Debug. LogError( fileSystemInfo. FullName + " 不存在!");
return;
}

DirectoryInfo directoryInfo = fileSystemInfo as DirectoryInfo;
FileSystemInfo[] fileSystemInfos = directoryInfo. GetFileSystemInfos();
foreach ( var tmpFileSystemInfo in fileSystemInfos)
{
FileInfo fileInfo = tmpFileSystemInfo as FileInfo;
if ( fileInfo == null)
{
//代表强转失败,不是文件 就是文件夹
//如果访问的是文件夹:再继续访问里面的所有文件系统,直到找到 文件 (递归)
onSceneFileSystemInfo( tmpFileSystemInfo, sceneName, namePahtDict);
}
else
{
//就是文件
//5.找到文件 就要修改他的 assetbundle labels
setLabels( fileInfo, sceneName, namePahtDict);
}
}
}

/// < summary >
/// 修改资源文件的 assetbundle labels
/// </ summary >
private static void setLabels( FileInfo fileInfo, string sceneName, Dictionary< string, string> namePahtDict)
{
//对unity自身生成的meta文件 无视它
if ( fileInfo. Extension == ".meta")
return;

string bundleName = getBundleName( fileInfo, sceneName);
//C:\Users\张晋枭\Documents\ABLesson\Assets\Res\Scene1\Buildings\Folder\Building4.prefab
int index = fileInfo. FullName. IndexOf( "Assets");
//Assets\Res\Scene1\Buildings\Folder\Building4.prefab
string assetPath = fileInfo. FullName. Substring( index);

AssetImporter assetImporter = AssetImporter. GetAtPath( assetPath);
//用 AssetImporter 类 修改名称和后缀
assetImporter. assetBundleName = bundleName. ToLower();
if ( fileInfo. Extension == ".unity")
assetImporter. assetBundleVariant = "u3d";
else
assetImporter. assetBundleVariant = "assetbundle";

string folderName = "";
//添加到字典里
if ( bundleName. Contains( "/"))
folderName = bundleName. Split( '/')[ 1];
else
folderName = bundleName;

string bundlePath = assetImporter. assetBundleName + "." + assetImporter. assetBundleVariant;
if (! namePahtDict. ContainsKey( folderName))
namePahtDict. Add( folderName, bundlePath);
}


/// < summary >
/// 获取包名
/// </ summary >
private static string getBundleName( FileInfo fileInfo, string sceneName)
{
string windowsPath = fileInfo. FullName; //C:\Users\张晋枭\Documents\ABLesson\Assets\Res\Scene1\Buildings\Folder\Building4.prefab
//转换成unity可识别的路径
string unityPath = windowsPath. Replace( @"\", "/");

//C:/Users/张晋枭/Documents/ABLesson/Assets/Res/Scene1 /Buildings/Folder/Building4.prefab
//C: \Users\张晋枭\Documents\ABLesson\Assets\Res\Scene1\Scene1.unity
int index = unityPath. IndexOf( sceneName) + sceneName. Length;

string bundlePath = unityPath. Substring( index + 1);

if ( bundlePath. Contains( "/"))
{
//Buildings/Folder/Folder/Folder/Folder/Folder/Building4.prefab
string[] tmp = bundlePath. Split( '/');
return sceneName + "/" + tmp[ 0];
}
else
{
//Scene1.unity
return sceneName;
}
}

#endregion

#region 打包

[ MenuItem( "AssetBundle/Build AssetBundles")]
static void BuildAllAssetBundles()
{
string outPath = PathUtil. GetAssetBundleOutPath();

BuildPipeline. BuildAssetBundles( outPath, 0, BuildTarget. StandaloneWindows64);
}


#endregion

#region 一键删除

[ MenuItem( "AssetBundle/Delete All")]
static void DeleteAssetBundle()
{
string outPath = PathUtil. GetAssetBundleOutPath();

Directory. Delete( outPath, true);
File. Delete( outPath + ".meta");

AssetDatabase. Refresh();
}

#endregion




[ MenuItem( "Tools/Create Files")]
static void CreateFiles()
{
//C:/Users/Ahpily/Desktop/AB/Assets/StreamingAssets/Windows
string outPath = PathUtil. GetAssetBundleOutPath();
//校验文件的路径
string filePath = outPath + "/files.txt";
if ( File. Exists( filePath))
File. Delete( filePath);

//遍历这个文件夹下面的所有文件
List< string> fileList = new List< string>();
listFiles( new DirectoryInfo( outPath), ref fileList);

FileStream fs = new FileStream( filePath, FileMode. CreateNew);
StreamWriter sw = new StreamWriter( fs);

for ( int i = 0; i < fileList. Count; i++)
{
string file = fileList[ i];
string ext = Path. GetExtension( file);
if ( ext. EndsWith( ".meta"))
continue;

//生成这个文件对应的md5值
string md5 = getFileMd5( file);
//scene1.assetbundle
string value = file. Replace( outPath + "/", string. Empty);
//写入到文件
sw. WriteLine( value + "|" + md5);
}

sw. Close();
fs. Close();

AssetDatabase. Refresh();
}

/// < summary >
/// 遍历文件夹下的所有文件
/// </ summary >
/// < param name = "fileSystemInfo" > 文件夹的路径 </ param >
/// < param name = "fileList" ></ param >
static void listFiles( FileSystemInfo fileSystemInfo, ref List< string> fileList)
{
DirectoryInfo directoryInfo = fileSystemInfo as DirectoryInfo;
//获取所有的文件系统
FileSystemInfo[] infos = directoryInfo. GetFileSystemInfos();

foreach ( var info in infos)
{
FileInfo fileInfo = info as FileInfo;
//如果是文件 就成功了
if ( fileInfo != null)
{
fileList. Add( fileInfo. FullName. Replace( " \\ ", "/"));
}
//如果是文件夹就不成功 null
else
{
//递归
listFiles( info, ref fileList);
}
}

}

/// < summary >
/// 获取文件的md5值
/// </ summary >
/// < param name = "filePath" ></ param >
static string getFileMd5( string filePath)
{
FileStream fs = new FileStream( filePath, FileMode. Open);
MD5 md5 = new MD5CryptoServiceProvider();

byte[] result = md5. ComputeHash( fs);
fs. Close();

StringBuilder sb = new StringBuilder();
for ( int i = 0; i < result. Length; i++)
{
sb. Append( result[ i]. ToString( "x2"));
}
return sb. ToString();
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值