247 lines
9.1 KiB
C#
247 lines
9.1 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using Cysharp.Threading.Tasks;
|
||
using PhxhSDK.AOT;
|
||
using PhxhSDK.AOT.SimpleLoader;
|
||
using UnityEngine;
|
||
using UnityEngine.AddressableAssets;
|
||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||
using UnityEngine.SceneManagement;
|
||
|
||
public class GameLauncher : MonoBehaviour
|
||
{
|
||
|
||
[Serializable]
|
||
private class DownloadContent
|
||
{
|
||
public List<string> catalogs = new();
|
||
}
|
||
|
||
const string START_SCENE_NAME = "Assets/Scenes/StartScene.unity";
|
||
|
||
//记录在playerPres里的需要下载的catalogs的ID
|
||
const string DOWNLOAD_CATALOGS_ID = "DownloadCatalogs";
|
||
|
||
//最大能容忍的下载卡住时长,一旦超过则重新开始下载
|
||
// private const float DOWNLOAD_STUCK_TIME_MAX = 10;
|
||
|
||
private HybridCLRHelper _hybridCLRHelper;
|
||
|
||
//version update
|
||
private AsyncOperationHandle _downloadOP;
|
||
private UI_VersionUpdate _versionUpdateUI;
|
||
private Type _versionUpdaterType;
|
||
// private float _downloadProgress;
|
||
// private float _downloadStuckTime;
|
||
|
||
private List<object> _KeysNeedToDownload = new();
|
||
|
||
//此对象里保存了需要下载的catalog,每次获取新的catalog会将此对象保存到手机上,如果在下载的过程中关闭了游戏,下次打开还能拿到catalog继续下载
|
||
private DownloadContent _downloadContent = new();
|
||
|
||
private bool HasContentToDownload => _downloadContent != null && _downloadContent.catalogs != null &&
|
||
_downloadContent.catalogs.Count > 0;
|
||
|
||
public bool enableHotUpdate = true;
|
||
|
||
private void Start()
|
||
{
|
||
Launch();
|
||
}
|
||
|
||
private async UniTask Launch()
|
||
{
|
||
#if UNITY_EDITOR
|
||
enableHotUpdate = false;
|
||
#endif
|
||
#if USE_YOO
|
||
await YooAssetHelper.Init();
|
||
#endif
|
||
Debug.Log($"Launch Game! enableHotUpdate:{enableHotUpdate}");
|
||
await VersionCheck();
|
||
if (HasContentToDownload)
|
||
await VersionUpdate();
|
||
|
||
if (enableHotUpdate)
|
||
{
|
||
Debug.Log("需要热更新,开始加载程序集");
|
||
_hybridCLRHelper = new HybridCLRHelper();
|
||
_hybridCLRHelper.SetDllList(AOTGenericReferences.PatchedAOTAssemblyList);
|
||
|
||
#if USE_YOO
|
||
_hybridCLRHelper.RegistLoader(new SimpleLoader_YooAsset());
|
||
#else
|
||
_hybridCLRHelper.RegistLoader(new SimpleLoader_Addressables());
|
||
#endif
|
||
|
||
await _hybridCLRHelper.LoadAssemblies();
|
||
Debug.Log("加载程序集结束!");
|
||
}
|
||
|
||
await EnterGame();
|
||
}
|
||
|
||
private IEnumerator VersionCheck()
|
||
{
|
||
//todo 如果包体版本不一致则提示用户去app store重新下载
|
||
var checkUpdateOP = Addressables.CheckForCatalogUpdates(false);
|
||
Debug.Log("start checkUpdateOP");
|
||
yield return checkUpdateOP;
|
||
if (checkUpdateOP.Status == AsyncOperationStatus.Succeeded)
|
||
{
|
||
_downloadContent.catalogs = checkUpdateOP.Result;
|
||
if (HasContentToDownload)
|
||
{
|
||
Debug.Log("new version on server");
|
||
//如果服务器上的catalog和本地不一致,则覆盖上一次需要下载的被内容
|
||
var jsonStr = JsonUtility.ToJson(_downloadContent);
|
||
PlayerPrefs.SetString(DOWNLOAD_CATALOGS_ID, jsonStr);
|
||
PlayerPrefs.Save();
|
||
}
|
||
else
|
||
{
|
||
if (PlayerPrefs.HasKey(DOWNLOAD_CATALOGS_ID))
|
||
{
|
||
Debug.Log("there are some contents remains from last downloading");
|
||
var jsonStr = PlayerPrefs.GetString(DOWNLOAD_CATALOGS_ID);
|
||
JsonUtility.FromJsonOverwrite(jsonStr, _downloadContent);
|
||
}
|
||
}
|
||
|
||
if (HasContentToDownload)
|
||
{
|
||
var updateCatalogOP = Addressables.UpdateCatalogs(_downloadContent.catalogs, false);
|
||
yield return updateCatalogOP;
|
||
if (updateCatalogOP.Status == AsyncOperationStatus.Succeeded)
|
||
{
|
||
_KeysNeedToDownload.Clear();
|
||
foreach (var resourceLocator in updateCatalogOP.Result)
|
||
{
|
||
_KeysNeedToDownload.AddRange(resourceLocator.Keys);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"Update catalog failed!exception:{updateCatalogOP.OperationException.Message}");
|
||
}
|
||
|
||
Addressables.Release(updateCatalogOP);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"CheckUpdate failed!exception:{checkUpdateOP.OperationException.Message}");
|
||
}
|
||
|
||
Addressables.Release(checkUpdateOP);
|
||
yield return SimpleLoader_Addressables.ReloadAddressableCatalog();
|
||
Debug.Log($"版本检查结束,是否有需要下载的内容:{HasContentToDownload}");
|
||
}
|
||
|
||
private IEnumerator VersionUpdate()
|
||
{
|
||
yield return OpenVersionUpdateUI();
|
||
yield return Download();
|
||
Debug.Log($"版本更新结束!");
|
||
}
|
||
|
||
//通过加载场景打开版本更新界面
|
||
private IEnumerator OpenVersionUpdateUI()
|
||
{
|
||
_versionUpdateUI = FindObjectOfType<UI_VersionUpdate>(true);
|
||
if (_versionUpdateUI == null)
|
||
{
|
||
Debug.LogError("cant find UI_VersionUpdate");
|
||
}
|
||
|
||
_versionUpdateUI.gameObject.SetActive(true);
|
||
return null;
|
||
}
|
||
|
||
//下载资源
|
||
private IEnumerator Download()
|
||
{
|
||
var downloadSizeOp = Addressables.GetDownloadSizeAsync((IEnumerable)_KeysNeedToDownload);
|
||
yield return downloadSizeOp;
|
||
Debug.Log($"download size:{downloadSizeOp.Result / (1024f * 1024f)}MB");
|
||
|
||
if (downloadSizeOp.Result > 0)
|
||
{
|
||
//_downloadStuckTime = 0;
|
||
Addressables.Release(downloadSizeOp);
|
||
// //下载经常在100%的时候卡住,参考:https://forum.unity.com/threads/addressables-1-14-2-downloaddependenciesasync-does-not-complete-randomly.966671/
|
||
// //倒数第二个回答
|
||
// var asyncLoadResources = Addressables.LoadResourceLocationsAsync((IEnumerable)_KeysNeedToDownload,
|
||
// Addressables.MergeMode.Union, null);
|
||
// IList<IResourceLocation> dependencyLoadList = new List<IResourceLocation>();
|
||
// yield return asyncLoadResources;
|
||
// foreach (var item in asyncLoadResources.Result)
|
||
// {
|
||
// dependencyLoadList.Add(item);
|
||
// }
|
||
//
|
||
// Addressables.Release(asyncLoadResources);
|
||
//
|
||
// _downloadOP =
|
||
// Addressables.DownloadDependenciesAsync(dependencyLoadList);
|
||
|
||
_downloadOP =
|
||
Addressables.DownloadDependenciesAsync((IEnumerable)_KeysNeedToDownload, Addressables.MergeMode.Union, false);
|
||
_versionUpdateUI.SetParams(_downloadOP);
|
||
|
||
// while (!_downloadOP.IsDone)
|
||
// {
|
||
// RefreshDownLoadStatus();
|
||
// if (!CheckIfNeedReDownload())
|
||
// yield return 0;
|
||
// else
|
||
// {
|
||
// //下载会经常卡在99%,此时还剩下很少的资源要下载,可以直接放弃下载,进入游戏
|
||
// //经过尝试,上述方法行不通,_downloadOp不能被终止,如果直接release的话会导致后续逻辑报错
|
||
// Debug.LogError($"下载卡住超过时间上限,放弃下载!");
|
||
// yield return _downloadOP;
|
||
// }
|
||
// }
|
||
yield return _downloadOP;
|
||
|
||
if (_downloadOP.Status == AsyncOperationStatus.Succeeded)
|
||
Debug.Log($"下载完毕!");
|
||
else
|
||
Debug.LogError($"Download Update Content Failed! exception:{_downloadOP.OperationException.Message} \r\n {_downloadOP.OperationException.StackTrace}");
|
||
|
||
Addressables.Release(_downloadOP);
|
||
}
|
||
|
||
//清除需要下载的内容
|
||
Debug.Log($"delete key:{DOWNLOAD_CATALOGS_ID}");
|
||
PlayerPrefs.DeleteKey(DOWNLOAD_CATALOGS_ID);
|
||
}
|
||
|
||
// private void RefreshDownLoadStatus()
|
||
// {
|
||
// var currDownloadProgress = _downloadOP.GetDownloadStatus().Percent;
|
||
// if (Math.Abs(currDownloadProgress - _downloadProgress) < float.Epsilon)
|
||
// _downloadStuckTime += Time.deltaTime;
|
||
// else
|
||
// _downloadStuckTime = 0;
|
||
// _downloadProgress = currDownloadProgress;
|
||
// //Debug.Log($"下载进度:{_downloadProgress} 下载卡顿时间:{_downloadStuckTime}");
|
||
// }
|
||
//
|
||
// private bool CheckIfNeedReDownload() => _downloadStuckTime >= DOWNLOAD_STUCK_TIME_MAX;
|
||
|
||
|
||
private IEnumerator EnterGame()
|
||
{
|
||
var op = Addressables.LoadSceneAsync(START_SCENE_NAME, LoadSceneMode.Single);
|
||
yield return op;
|
||
if (op.Status != AsyncOperationStatus.Succeeded)
|
||
{
|
||
Debug.LogError(
|
||
$"load scene failed,exception:{op.OperationException.Message} \r\n {op.OperationException.StackTrace}");
|
||
}
|
||
}
|
||
|
||
|
||
} |