Unity划时代热更方案 YooAsset+HybridCLR(wolong)(原huatuo)(六)完结篇_育婴房扛把子的博客-CSDN博客
详细的内容直接看上述系列文章.讲的比我好多了
相比于他的做法我这里做了一些更改,我图方便直接将热更新程序集设置成了整个Assembly-CSharp设置成了热更新对象
然后把loaddll的位置选择当AOT程序集
另外我还有一个加载热更新完成之后跳转场景的功能
所以loaddll代码中有如下修改:
//将他的代码中的hotUpdateAss修改成了assemblyCSharp
private static Assembly _assemblyCSharp;
void StartGame()
{
LoadMetadataForAOTAssemblies();
#if !UNITY_EDITOR
_assemblyCSharp = Assembly.Load(ReadBytesFromStreamingAssets("Assembly-CSharp.dll"));
#else
_assemblyCSharp = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "Assembly-CSharp");
#endif
StartCoroutine(StartScence());
}
IEnumerator StartScence()
{
var package = YooAssets.GetPackage("DefaultPackage");
string location = "Scence_MainScene";
var sceneMode = UnityEngine.SceneManagement.LoadSceneMode.Single;
bool suspendLoad = false;
// 异步加载下一个场景,并等待加载结束
SceneOperationHandle handle = package.LoadSceneAsync(location, sceneMode, suspendLoad);
while (!handle.IsDone)
{
// 在整个加载过程中更新进度条显示
slider.value = handle.Progress;
if (handle.Progress >= 0.9f)
{
// 如果已经加载到了90%以上,则直接跳转下一个场景
slider.value = 1;
}
// 添加此行代码,让Unity跳出循环继续执行其他任务
yield return null;
}
yield return handle;
Debug.Log($"Scene name is {handle.SceneObject.name}");
}
另外我还做了如果没有网络的情况下直接用之前下载好的包的判定
//2.获取资源版本
var operation = package.UpdatePackageVersionAsync();
yield return operation;
Debug.Log($"operation ={operation.Status} ");
if (operation.Status == EOperationStatus.Succeed)
{
string packageVersion = operation.PackageVersion;
Debug.Log($"Updated package Version : {packageVersion}");
//3.更新补丁清单
// 更新成功后自动保存版本号,作为下次初始化的版本。
// 也可以通过operation.SavePackageVersion()方法保存。
bool savePackageVersion = true;
var operation2 = package.UpdatePackageManifestAsync(packageVersion, savePackageVersion);
yield return operation2;
if (operation2.Status != EOperationStatus.Succeed)
{
//更新失败
Debug.LogError(operation2.Error);
}
//4.下载补丁包
yield return Download();
//判断是否下载成功
var assets = new List<string>
{
"Assembly-CSharp.dll",
}.Concat(AOTMetaAssemblyFiles);
foreach (var asset in assets)
{
//加载原生文件
RawFileOperationHandle handle = package.LoadRawFileAsync(asset);
yield return handle;
byte[] fileData = handle.GetRawFileData();
s_assetDatas[asset] = fileData;
Debug.Log($"dll:{asset} size:{fileData.Length}");
}
onDownloadComplete();
}
else
{
// 如果获取远端资源版本失败,说明当前网络无连接。
// 在正常开始游戏之前,需要验证本地清单内容的完整性。
string packageVersion = package.GetPackageVersion();
var operation2 = package.PreDownloadContentAsync(packageVersion);
yield return operation2;
if (operation2.Status != EOperationStatus.Succeed)
{
Debug.LogError("更新失败,请检查本地网络,有新的游戏内容需要更新!");
yield break;
}
int downloadingMaxNum = 10;
int failedTryAgain = 3;
int timeout = 60;
var downloader = operation2.CreateResourceDownloader(downloadingMaxNum, failedTryAgain, timeout);
if (downloader.TotalDownloadCount > 0)
{
// 资源内容本地并不完整,需要提示玩家联网更新。
Debug.LogError("资源包不全,请检查本地网络,有新的游戏内容需要更新!");
yield break;
}
//判断是否下载成功
var assets = new List<string>
{
"Assembly-CSharp.dll",
}.Concat(AOTMetaAssemblyFiles);
foreach (var asset in assets)
{
//加载原生文件
RawFileOperationHandle handle = package.LoadRawFileAsync(asset);
yield return handle;
byte[] fileData = handle.GetRawFileData();
s_assetDatas[asset] = fileData;
Debug.Log($"dll:{asset} size:{fileData.Length}");
}
StartGame();
}
这里再记录一下完成之后的打包逻辑
打包发布
然后返回unity界面,点击Build Settings先生成exe或者apk包程序。
之后返回unity界面。
第一步
第二步
然后会在StreamingAssets文件夹下生成一大堆之前LoadDll代码里的AOT相关的桥接文件。
将这一大堆.dll文件移动到Assets/AssetPackage/Codes文件夹中。
之后的操作大家都很熟悉了。
第一步
首次构建选择Force Rebuild,之后有小更新就选择Incremental Build就行点击构建后,又生成了一大堆更多的东西。
将着一大堆东西,移动到之前的安装的资源服务器www文件夹下。打开刚才生成好的exe或apk程序。
完事!