目錄
打包與資源加載框架目錄
正文
熱更流程都不是固定的,每個人寫的狀態(tài)機也有所差別,但是一些必要步驟肯定不可能少,例如下載清單,對比版本,下載AB包,標記下載完成。我接下來的每一篇文章都是下載AB包的重要步驟,大概率是不能省略的。
檢查沙盒路徑是否存在
public static string MakePersistentLoadPath(string path)
{
#if UNITY_EDITOR
// 注意:為了方便調(diào)試查看,編輯器下把存儲目錄放到項目里
string projectPath = Path.GetDirectoryName(Application.dataPath).Replace("\\","/");
projectPath = GetRegularPath(projectPath);
return StringFormat.Format("{0}/Sandbox/{1}", projectPath, path);
#else
return StringFormat.Format("{0}/Sandbox/{1}", Application.persistentDataPath, path);
#endif
}
檢查下載臨時目錄是否存在
請注意,熱更時下載AB包先下載到臨時目錄,之后再拷貝到沙盒目錄
public static string MakeDownloadTempPath(string path)
{
#if UNITY_EDITOR
string projectPath = Path.GetDirectoryName(Application.dataPath).Replace("\\", "/");
projectPath = GetRegularPath(projectPath);
return StringFormat.Format("{0}/Sandbox_Temp/{1}", projectPath, path);
#else
return StringFormat.Format("{0}/Sandbox_Temp/{1}", Application.persistentDataPath, path);
#endif
}
路徑都確認存在后,開始下載
前文有介紹過,生成的AB包清單長這個樣子,把這個文件生成二進制bytes文件扔到服務(wù)器上去下載。
![[游戲開發(fā)][Unity]Assetbundle下載篇(1)熱更前準備與下載AB包清單,項目管理,unity,游戲開發(fā),Powered by 金山文檔](https://imgs.yssmx.com/Uploads/2023/07/557554-1.png)
第一行是SVN版本號
第二行是AB包數(shù)量
從第三行開始是資源包信息,以=號分割開有效數(shù)據(jù),分別是
MD5.unity3d = 資源路徑 = 資源路徑的HashId = 包體KB大小 = SVN版本號 = 啟動熱更模式
每一行數(shù)據(jù)封裝了一個PatchElement類,代碼在下文中
我們項目封裝了一下UnityWebRequest,叫WebDataRequest,你不想封裝直接用UnityWebRequest即可,WebDataRequest代碼在后面有。
private IEnumerator DownLoad()
{
// 解析APP里的補丁清單
string filePath = AssetPathHelper.MakeStreamingLoadPath(PatchDefine.InitManifestFileName);
string url = AssetPathHelper.ConvertToWWWPath(filePath);
using (WebDataRequest downloader = new WebDataRequest(url))
{
yield return downloader.DownLoad();
if (downloader.States == EWebRequestStates.Success)
{
PatchHelper.Log(ELogLevel.Log, "Parse app patch manifest.");
ParseAppPatchManifest(downloader.GetData());
}
else
{
throw new System.Exception($"Fatal error : Failed download file : {url}");
}
}
}
// 解析補丁清單文件相關(guān)接口
public void ParseAppPatchManifest(byte[] data)
{
if (AppPatchManifest != null)
throw new Exception("Should never get here.");
AppPatchManifest = new PatchManifest(true);
AppPatchManifest.Parse(data);
}
PatchManifest類是一個專門解析AB包清單的類,看代碼也能知道,Parse方法的最終目的,就是把清單的每一行數(shù)據(jù)解析成PatchElement然后加入到字典中存起來等著下載時調(diào)用
/// <summary>
/// 補丁清單文件
/// </summary>
public class PatchManifest
{
private bool _isParse = false;
/// <summary>
/// 資源版本號
/// </summary>
public int DllVersion { private set; get; }
public int ResVersion { private set; get; }
private bool IsInit = false;
/// <summary>
/// 所有打包文件列表
/// </summary>
public readonly Dictionary<string, PatchElement> Elements = new Dictionary<string, PatchElement>();
public PatchManifest(bool isInit = false)
{
IsInit = isInit;
}
/// <summary>
/// 解析數(shù)據(jù)
/// </summary>
public void Parse(byte[] data)
{
using (var ms = new MemoryStream(data))
{
using(var br = new BinaryReader(ms))
{
Parse(br);
}
}
}
public void ParseFile(string filePath)
{
using (var fs = File.OpenRead(filePath))
{
using (var br = new BinaryReader(fs))
{
Parse(br);
}
}
}
/// <summary>
/// 解析數(shù)據(jù)
/// </summary>
public void Parse(BinaryReader br)
{
if (br == null)
throw new Exception("Fatal error : Param is null.");
if (_isParse)
throw new Exception("Fatal error : Package is already parse.");
_isParse = true;
// 讀取版本號
DllVersion = br.ReadInt32();
ResVersion = br.ReadInt32();
GameVersion.PatchResDesc = ResVersion + " dllVer:" + DllVersion;
int fileCount = br.ReadInt32();
// 讀取所有Bundle的數(shù)據(jù)
for(var i = 0; i < fileCount; i++)
{
var ele = PatchElement.Deserialize(br, IsInit);
if (Elements.ContainsKey(ele.Name))
throw new Exception($"Fatal error : has same pack file : {ele.Name}");
Elements.Add(ele.Name, ele);
}
}
}
PatchElement是AB包清單每一行數(shù)據(jù)的封裝,PatchManifest的Parse里會循環(huán)創(chuàng)建一個Elements字典保存這些數(shù)據(jù)。文章來源:http://www.zghlxwxcb.cn/news/detail-557554.html
public class PatchElement
{
/// <summary>
/// 文件名稱
/// </summary>
public string Name { private set; get; }
/// <summary>
/// 文件MD5
/// </summary>
public string MD5 { private set; get; }
/// <summary>
/// 文件版本
/// </summary>
public int Version { private set; get; }
/// <summary>
/// 文件大小
/// </summary>
public long SizeKB { private set; get; }
/// <summary>
/// 構(gòu)建類型
/// buildin 在安裝包中
/// ingame 游戲中下載
/// </summary>
public string Tag { private set; get; }
/// <summary>
/// 是否是安裝包內(nèi)的Patch
/// </summary>
public bool IsInit { private set; get; }
/// <summary>
/// 下載文件的保存路徑
/// </summary>
public string SavePath;
/// <summary>
/// 每次更新都會先下載到Sandbox_Temp目錄,防止下到一半重啟導(dǎo)致邏輯不一致報錯
/// temp目錄下的文件在重新進入更新流程時先校驗md5看是否要跳過下載
/// </summary>
public bool SkipDownload { get; set; }
public PatchElement(string name, string md5, int version, long sizeKB, string tag, bool isInit = false)
{
Name = name;
MD5 = md5;
Version = version;
SizeKB = sizeKB;
Tag = tag;
IsInit = isInit;
SkipDownload = false;
}
public void Serialize(BinaryWriter bw)
{
bw.Write(Name);
bw.Write(MD5);
bw.Write(SizeKB);
bw.Write(Version);
if (IsInit)
bw.Write(Tag);
}
public static PatchElement Deserialize(BinaryReader br, bool isInit = false)
{
var name = br.ReadString();
var md5 = br.ReadString();
var sizeKb = br.ReadInt64();
var version = br.ReadInt32();
var tag = EBundlePos.buildin.ToString();
if (isInit)
tag = br.ReadString();
return new PatchElement(name, md5, version, sizeKb, tag, isInit);
}
}
下面是下載數(shù)據(jù)封裝,本質(zhì)還是 UnityWebRequest文章來源地址http://www.zghlxwxcb.cn/news/detail-557554.html
public class WebDataRequest : WebRequestBase, IDisposable
{
public WebDataRequest(string url) : base(url)
{
}
public override IEnumerator DownLoad()
{
// Check fatal
if (States != EWebRequestStates.None)
throw new Exception($"{nameof(WebDataRequest)} is downloading yet : {URL}");
States = EWebRequestStates.Loading;
// 下載文件
CacheRequest = new UnityWebRequest(URL, UnityWebRequest.kHttpVerbGET);
DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
CacheRequest.downloadHandler = handler;
CacheRequest.disposeDownloadHandlerOnDispose = true;
CacheRequest.timeout = Timeout;
yield return CacheRequest.SendWebRequest();
// Check error
if (CacheRequest.isNetworkError || CacheRequest.isHttpError)
{
MotionLog.LogWarning($"Failed to download web data : {URL} Error : {CacheRequest.error}");
States = EWebRequestStates.Fail;
}
else
{
States = EWebRequestStates.Success;
}
}
public byte[] GetData()
{
if (States == EWebRequestStates.Success)
return CacheRequest.downloadHandler.data;
else
return null;
}
public string GetText()
{
if (States == EWebRequestStates.Success)
return CacheRequest.downloadHandler.text;
else
return null;
}
}
到了這里,關(guān)于[游戲開發(fā)][Unity]Assetbundle下載篇(1)熱更前準備與下載AB包清單的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!