思路:
1.先把资源构建成AssetBundle包
2.将构建出来的AB包数据读取出来进行加密,然后重新写入AB包
3.先解密,然后加载AB包
加密与解密
1.这里我们首先设定一个加密码,然后将读取出来的文件流的每一位与加密码进行异或操作得到一个新的加密过的数据,解密也是一样的操作
public class FileTools
{
public const byte Key = 150; //加密码,自定义
/// <summary>
/// 加密/解密
/// </summary>
/// <param name="data"></param>
public static void Encrypt(ref byte[] data)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = (byte)(data[i] ^ Key); //每一位与加密码进行异或操作
}
}
}
构建AB包
1.先把资源AB包名和后缀名设定好
2.然后在Editor目录下新建个脚本,进行编辑器扩展
3.输出路径使用AB包需要放置的路径
[MenuItem("Component/构建AB包")]
public static void BuildBundle()
{
BuildPipeline.BuildAssetBundles(AssetData.AssetBundleOutPutPath, BuildAssetBundleOptions.None,BuildTarget.Android);
}
4.构建完成后,加密
[MenuItem("Component/加密AB包")]
public static void EncryptAssetBundle()
{
string[] abs = GetAllFiles(AssetData.AssetBundleOutPutPath, ".unity3d");
foreach (var item in abs)
{
byte[] data= File.ReadAllBytes(item); //把ab包数据读取出来
FileTools.Encrypt(ref data); //加密
File.WriteAllBytes(item, data); //加密后的数据重新写入包体
}
}
// 获取路径下所有后缀名为 endName 的文件名
public static string[] GetAllFiles(string path,string endName)
{
return Directory.GetFiles(path,"*"+endName,SearchOption.AllDirectories);
}
注意:不了解编辑器扩展的同学可以先去了解下编辑器扩展
加载
1.加载先把ab包数据读出来,然后使用AssetBundle.LoadFromMemoryAsync或者AssetBundle.LoadFromMemory去读取
//这里传入的abs是所有ab包的路径
IEnumerator StartLoad(string[] abs)
{
foreach (string path in abs)
{
byte[] data=File.ReadAllBytes(path);
FileTools.Encrypt(ref data); //解密
AssetBundleCreateRequest asset=AssetBundle.LoadFromMemoryAsync(data);
yield return asset;
while (!asset.isDone)
{
Debug.Log(path + "进度" + asset.progress);
yield return 0;
}
AssetBundleRequest bundleRequest= asset.assetBundle.LoadAllAssetsAsync();
yield return bundleRequest;
while (!bundleRequest.isDone)
{
yield return 0;
}
UnityEngine.Object[] res = bundleRequest.allAssets;
for (int i = 0; i < res.Length; i++)
{
string key = res[i].name;
Debug.Log("加载资源" + key + "完成");
if (!mResDic.ContainsKey(key))
{
mResDic.Add(key, res[i]); //缓存
}
}
}
}