之前提到过通过AssetBundle.CreateFromFile读取本地AssetBundle,因为该方法只能读取未压缩的AssetBundle,所以打包AssetBundle时,需要选择BuildAssetBundleOptions.UncompressedAssetBundle未压缩模式,然后使用LZMA或GZIP压缩后上传服务器。本地下载后需要解压缩保存在Application.persistentDataPath目录下。
下面说明如何压缩AssetBundle。
【Unity3d热更新(四)(压缩文件)】首先需要下载7-zip的C#核心文件,下载地址http://www.7-zip.org/sdk.html。
文章图片
解压后将CS文件夹下的7zip文件夹导入Unity工程,下面是一个Demo,可以直接用。
using UnityEngine;
using System.Collections;
using UnityEditor;
using SevenZip.Compression.LZMA;
using System.IO;
using System;
// 压缩或解压文件
public class CompressAndDecompress : Editor {// 压缩Unity3D文件
[MenuItem("Compress/Compress Unity3D File")]
static void CompressUnity3DFile()
{
string path = EditorUtility.OpenFilePanel("Compress file", "", "unity3d");
CompressFile(path);
}// 压缩Lua文件
[MenuItem("Compress/Compress Lua File")]
static void CompressLuaFile()
{
string path = EditorUtility.OpenFilePanel("Compress file", "", "lua");
CompressFile(path);
}// 压缩文件
static void CompressFile(string path)
{
if (path.Length != 0)
{
int lastDotIndex = path.LastIndexOf(".");
string outputPath = path.Substring(0, lastDotIndex + 1) + "zip";
CompressFileLZMA(path, outputPath);
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("压缩文件", "文件已压缩完成", "确认");
}
}// 解压Unity3D文件
[MenuItem("Compress/Decompress Unity3D File")]
static void DecompressUnity3DFile()
{
DecompressFile("unity3d");
}// 解压Lua文件
[MenuItem("Compress/Decompress Lua File")]
static void DecompressLuaFile()
{
DecompressFile("lua");
}static void DecompressFile(string extension)
{
string path = EditorUtility.OpenFilePanel("Decompress file", "", "zip");
if (path.Length != 0)
{
int lastDotIndex = path.LastIndexOf(".");
string outputPath = path.Substring(0, lastDotIndex + 1) + extension;
DecompressFileLZMA(path, outputPath);
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("解压文件", "文件已解压完成", "确认");
}
}// 压缩文件夹中的文件
[MenuItem("Compress/Compress Files In Directory")]
static void CompressFilesInDirectory()
{
string path = EditorUtility.OpenFolderPanel("Compress Files In Directory", "", "");
if (path.Length != 0)
{
DirectoryInfo source = new DirectoryInfo(path);
DirectoryInfo target = new DirectoryInfo(path + "_compress");
if (target.Exists)
{
target.Delete(true);
}target.Create();
target.Refresh();
// 复制源文件夹到目标文件夹
CopyAll(source, target);
ListFiles((FileSystemInfo)target, true);
EditorUtility.DisplayDialog("压缩文件夹", "文件夹中所有的文件已压缩完成", "确认");
}
}// 解压文件夹中的文件
//[MenuItem("Compress/Decompress Files In Directory")]
static void DecompressFilesInDirectory()
{
string path = EditorUtility.OpenFolderPanel("Decompress Files In Directory", "", "");
if (path.Length != 0)
{
DirectoryInfo source = new DirectoryInfo(path);
DirectoryInfo target = new DirectoryInfo(path + "_decompress");
if (target.Exists)
{
target.Delete(true);
}target.Create();
target.Refresh();
// 复制源文件夹到目标文件夹
CopyAll(source, target);
ListFiles(target, false);
EditorUtility.DisplayDialog("解压文件夹", "文件夹中所有的文件已解压完成", "确认");
}
}// 使用LZMA算法压缩文件
private static void CompressFileLZMA(string inFile, string outFile)
{
Encoder coder = new Encoder();
FileStream input = new FileStream(inFile, FileMode.Open);
FileStream output = new FileStream(outFile, FileMode.Create);
coder.WriteCoderProperties(output);
byte[] data = https://www.it610.com/article/BitConverter.GetBytes(input.Length);
output.Write(data, 0, data.Length);
coder.Code(input, output, input.Length, -1, null);
output.Flush();
output.Close();
input.Close();
}// 使用LZMA算法解压文件
private static void DecompressFileLZMA(string inFile, string outFile)
{
Decoder coder = new Decoder();
FileStream input = new FileStream(inFile, FileMode.Open);
FileStream output = new FileStream(outFile, FileMode.Create);
byte[] properties = new byte[5];
input.Read(properties, 0, 5);
byte[] fileLengthBytes = new byte[8];
input.Read(fileLengthBytes, 0, 8);
long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);
coder.SetDecoderProperties(properties);
coder.Code(input, output, input.Length, fileLength, null);
output.Flush();
output.Close();
input.Close();
}// 复制源文件夹到目标文件夹
public static void CopyAll(DirectoryInfo source, DirectoryInfo target, ArrayList extensions = null)
{
if (source.FullName.ToLower() == target.FullName.ToLower())
{
return;
}// 检测目标文件是否存在,如果不存在,则创建
if (!Directory.Exists(target.FullName))
{
Directory.CreateDirectory(target.FullName);
target.Refresh();
}// 复制文件至目标文件夹
foreach (FileInfo fi in source.GetFiles())
{
if (extensions == null || extensions.Count == 0)
{
if (fi.Extension !=".meta")
{
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
}
else
{
if (extensions.Contains(fi.Extension))
{
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
}}// 使用递归复制子文件夹
foreach (DirectoryInfo sourceSubDir in source.GetDirectories())
{
DirectoryInfo targetSubDir = target.CreateSubdirectory(sourceSubDir.Name);
CopyAll(sourceSubDir, targetSubDir, extensions);
}
}// 遍历文件夹中的所有文件,压缩或解压缩
public static void ListFiles(FileSystemInfo info, bool isCompress)
{
if (!info.Exists)
{
return;
}DirectoryInfo dir = info as DirectoryInfo;
// 不是目录
if (dir == null)
{
return;
}FileSystemInfo[] files = dir.GetFileSystemInfos();
for (int i = 0;
i < files.Length;
i++)
{
FileInfo file = files[i] as FileInfo;
// 是文件
if (file != null)
{
string fullName = file.FullName;
// 如果是压缩文件
if (isCompress)
{
if (file.Extension == ".unity3d" || file.Extension == ".lua")
{
string outputPath = file.FullName.Replace(file.Extension, ".zip");
CompressFileLZMA(fullName, outputPath);
File.Delete(fullName);
}
}
// 如果是解压文件
else
{
if (file.Extension == ".zip")
{
string outputPath = file.FullName.Replace(file.Extension, ".unity3d");
DecompressFileLZMA(fullName, outputPath);
File.Delete(fullName);
}
}}
else
{
ListFiles(files[i], isCompress);
}
}
}
}
推荐阅读
- 游戏|元宇宙密室逃脱游戏攻略来啦!
- Unity|unity 一些控制物体移动 小技巧
- Unity|Unity 学习 SpaceShooter 第二次记录
- Unity|Unity 游戏开始UI设计
- Unity|用C#写题--如何读入一行按空格分开的整数
- Visual Studio Professional 2017 点击项目->属性 提示(尝试加载该页时出错)
- Unity|【Unity Shader】Blend混合
- unity|AR Shadow Shader 实时阴影+ DepthMask透明遮罩
- Unity|unity3d知识点之一
- Unity|绿幕背景抠图,去除掉物体周围一圈的绿边 OpenCVForUnity