2023-10-19 15:00:19 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
2024-02-22 13:24:26 +08:00
|
|
|
|
using Cysharp.Threading.Tasks;
|
2024-02-21 16:24:29 +08:00
|
|
|
|
using PhxhSDK.AOT;
|
2024-02-22 12:41:18 +08:00
|
|
|
|
using PhxhSDK.AOT.SimpleLoader;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.AddressableAssets;
|
|
|
|
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
|
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
|
|
|
|
|
|
|
public class GameLauncher : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2024-01-30 19:42:52 +08:00
|
|
|
|
[Serializable]
|
|
|
|
|
|
private class DownloadContent
|
|
|
|
|
|
{
|
|
|
|
|
|
public List<string> catalogs = new();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
const string START_SCENE_NAME = "Assets/Scenes/StartScene.unity";
|
|
|
|
|
|
|
2024-01-30 19:42:52 +08:00
|
|
|
|
//记录在playerPres里的需要下载的catalogs的ID
|
|
|
|
|
|
const string DOWNLOAD_CATALOGS_ID = "DownloadCatalogs";
|
|
|
|
|
|
|
|
|
|
|
|
//最大能容忍的下载卡住时长,一旦超过则重新开始下载
|
2024-01-31 18:33:47 +08:00
|
|
|
|
// private const float DOWNLOAD_STUCK_TIME_MAX = 10;
|
2024-01-30 19:42:52 +08:00
|
|
|
|
|
2024-02-22 12:41:18 +08:00
|
|
|
|
private HybridCLRHelper _hybridCLRHelper;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
|
|
|
|
|
|
//version update
|
|
|
|
|
|
private AsyncOperationHandle _downloadOP;
|
2023-11-08 19:04:23 +08:00
|
|
|
|
private UI_VersionUpdate _versionUpdateUI;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
private Type _versionUpdaterType;
|
2024-01-31 18:33:47 +08:00
|
|
|
|
// private float _downloadProgress;
|
|
|
|
|
|
// private float _downloadStuckTime;
|
2024-01-30 19:42:52 +08:00
|
|
|
|
|
|
|
|
|
|
private List<object> _KeysNeedToDownload = new();
|
|
|
|
|
|
|
|
|
|
|
|
//此对象里保存了需要下载的catalog,每次获取新的catalog会将此对象保存到手机上,如果在下载的过程中关闭了游戏,下次打开还能拿到catalog继续下载
|
|
|
|
|
|
private DownloadContent _downloadContent = new();
|
|
|
|
|
|
|
|
|
|
|
|
private bool HasContentToDownload => _downloadContent != null && _downloadContent.catalogs != null &&
|
|
|
|
|
|
_downloadContent.catalogs.Count > 0;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
|
|
|
|
|
|
public bool enableHotUpdate = true;
|
|
|
|
|
|
|
|
|
|
|
|
private void Start()
|
|
|
|
|
|
{
|
2024-02-22 13:24:26 +08:00
|
|
|
|
Launch();
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-22 13:24:26 +08:00
|
|
|
|
private async UniTask Launch()
|
2023-10-19 15:00:19 +08:00
|
|
|
|
{
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
enableHotUpdate = false;
|
2024-02-21 16:24:29 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
#if USE_YOO
|
2024-02-22 13:24:26 +08:00
|
|
|
|
await YooAssetHelper.Init();
|
2023-10-19 15:00:19 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
Debug.Log($"Launch Game! enableHotUpdate:{enableHotUpdate}");
|
2024-02-22 13:24:26 +08:00
|
|
|
|
await VersionCheck();
|
2024-01-30 19:42:52 +08:00
|
|
|
|
if (HasContentToDownload)
|
2024-02-22 13:24:26 +08:00
|
|
|
|
await VersionUpdate();
|
2024-02-22 12:41:18 +08:00
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
if (enableHotUpdate)
|
2024-02-22 12:41:18 +08:00
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("需要热更新,开始加载程序集");
|
|
|
|
|
|
_hybridCLRHelper = new HybridCLRHelper();
|
|
|
|
|
|
_hybridCLRHelper.SetDllList(AOTGenericReferences.PatchedAOTAssemblyList);
|
|
|
|
|
|
|
|
|
|
|
|
#if USE_YOO
|
|
|
|
|
|
_hybridCLRHelper.RegistLoader(new SimpleLoader_YooAsset());
|
|
|
|
|
|
#else
|
|
|
|
|
|
_hybridCLRHelper.RegistLoader(new SimpleLoader_Addressables());
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2024-02-22 13:24:26 +08:00
|
|
|
|
await _hybridCLRHelper.LoadAssemblies();
|
2024-02-22 12:41:18 +08:00
|
|
|
|
Debug.Log("加载程序集结束!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-22 13:24:26 +08:00
|
|
|
|
await EnterGame();
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private IEnumerator VersionCheck()
|
|
|
|
|
|
{
|
|
|
|
|
|
//todo 如果包体版本不一致则提示用户去app store重新下载
|
|
|
|
|
|
var checkUpdateOP = Addressables.CheckForCatalogUpdates(false);
|
2024-02-07 14:59:43 +08:00
|
|
|
|
Debug.Log("start checkUpdateOP");
|
2023-10-19 15:00:19 +08:00
|
|
|
|
yield return checkUpdateOP;
|
|
|
|
|
|
if (checkUpdateOP.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
2024-01-30 19:42:52 +08:00
|
|
|
|
_downloadContent.catalogs = checkUpdateOP.Result;
|
|
|
|
|
|
if (HasContentToDownload)
|
2023-10-19 15:00:19 +08:00
|
|
|
|
{
|
2024-02-07 14:59:43 +08:00
|
|
|
|
Debug.Log("new version on server");
|
2024-01-30 19:42:52 +08:00
|
|
|
|
//如果服务器上的catalog和本地不一致,则覆盖上一次需要下载的被内容
|
2024-01-30 20:08:53 +08:00
|
|
|
|
var jsonStr = JsonUtility.ToJson(_downloadContent);
|
|
|
|
|
|
PlayerPrefs.SetString(DOWNLOAD_CATALOGS_ID, jsonStr);
|
|
|
|
|
|
PlayerPrefs.Save();
|
2024-01-30 19:42:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (PlayerPrefs.HasKey(DOWNLOAD_CATALOGS_ID))
|
|
|
|
|
|
{
|
2024-02-07 14:59:43 +08:00
|
|
|
|
Debug.Log("there are some contents remains from last downloading");
|
2024-01-30 20:08:53 +08:00
|
|
|
|
var jsonStr = PlayerPrefs.GetString(DOWNLOAD_CATALOGS_ID);
|
|
|
|
|
|
JsonUtility.FromJsonOverwrite(jsonStr, _downloadContent);
|
2024-01-30 19:42:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (HasContentToDownload)
|
|
|
|
|
|
{
|
|
|
|
|
|
var updateCatalogOP = Addressables.UpdateCatalogs(_downloadContent.catalogs, false);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
yield return updateCatalogOP;
|
|
|
|
|
|
if (updateCatalogOP.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
2024-01-30 19:42:52 +08:00
|
|
|
|
_KeysNeedToDownload.Clear();
|
2023-10-19 15:00:19 +08:00
|
|
|
|
foreach (var resourceLocator in updateCatalogOP.Result)
|
|
|
|
|
|
{
|
2024-01-30 19:42:52 +08:00
|
|
|
|
_KeysNeedToDownload.AddRange(resourceLocator.Keys);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"Update catalog failed!exception:{updateCatalogOP.OperationException.Message}");
|
|
|
|
|
|
}
|
2023-11-08 19:04:23 +08:00
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
Addressables.Release(updateCatalogOP);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"CheckUpdate failed!exception:{checkUpdateOP.OperationException.Message}");
|
|
|
|
|
|
}
|
2023-11-08 19:04:23 +08:00
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
Addressables.Release(checkUpdateOP);
|
2024-02-22 12:41:18 +08:00
|
|
|
|
yield return SimpleLoader_Addressables.ReloadAddressableCatalog();
|
2024-01-30 19:42:52 +08:00
|
|
|
|
Debug.Log($"版本检查结束,是否有需要下载的内容:{HasContentToDownload}");
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private IEnumerator VersionUpdate()
|
|
|
|
|
|
{
|
|
|
|
|
|
yield return OpenVersionUpdateUI();
|
|
|
|
|
|
yield return Download();
|
|
|
|
|
|
Debug.Log($"版本更新结束!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//通过加载场景打开版本更新界面
|
|
|
|
|
|
private IEnumerator OpenVersionUpdateUI()
|
|
|
|
|
|
{
|
2024-01-30 19:42:52 +08:00
|
|
|
|
_versionUpdateUI = FindObjectOfType<UI_VersionUpdate>(true);
|
2023-11-08 19:04:23 +08:00
|
|
|
|
if (_versionUpdateUI == null)
|
2023-10-19 15:00:19 +08:00
|
|
|
|
{
|
2023-11-08 19:04:23 +08:00
|
|
|
|
Debug.LogError("cant find UI_VersionUpdate");
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-30 19:42:52 +08:00
|
|
|
|
_versionUpdateUI.gameObject.SetActive(true);
|
2023-11-08 19:04:23 +08:00
|
|
|
|
return null;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//下载资源
|
|
|
|
|
|
private IEnumerator Download()
|
|
|
|
|
|
{
|
2024-01-30 19:42:52 +08:00
|
|
|
|
var downloadSizeOp = Addressables.GetDownloadSizeAsync((IEnumerable)_KeysNeedToDownload);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
yield return downloadSizeOp;
|
|
|
|
|
|
Debug.Log($"download size:{downloadSizeOp.Result / (1024f * 1024f)}MB");
|
|
|
|
|
|
|
|
|
|
|
|
if (downloadSizeOp.Result > 0)
|
|
|
|
|
|
{
|
2024-01-31 18:33:47 +08:00
|
|
|
|
//_downloadStuckTime = 0;
|
2024-01-30 19:42:52 +08:00
|
|
|
|
Addressables.Release(downloadSizeOp);
|
2024-01-31 18:33:47 +08:00
|
|
|
|
// //下载经常在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);
|
|
|
|
|
|
|
2023-11-08 19:04:23 +08:00
|
|
|
|
_downloadOP =
|
2024-01-31 18:33:47 +08:00
|
|
|
|
Addressables.DownloadDependenciesAsync((IEnumerable)_KeysNeedToDownload, Addressables.MergeMode.Union, false);
|
2023-11-08 19:04:23 +08:00
|
|
|
|
_versionUpdateUI.SetParams(_downloadOP);
|
|
|
|
|
|
|
2024-01-31 18:33:47 +08:00
|
|
|
|
// 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}");
|
|
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
Addressables.Release(_downloadOP);
|
|
|
|
|
|
}
|
2023-11-08 19:04:23 +08:00
|
|
|
|
|
2024-01-30 19:42:52 +08:00
|
|
|
|
//清除需要下载的内容
|
2024-01-30 20:08:53 +08:00
|
|
|
|
Debug.Log($"delete key:{DOWNLOAD_CATALOGS_ID}");
|
2024-01-30 19:42:52 +08:00
|
|
|
|
PlayerPrefs.DeleteKey(DOWNLOAD_CATALOGS_ID);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-31 18:33:47 +08:00
|
|
|
|
// 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;
|
2024-01-30 19:42:52 +08:00
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
|
|
|
|
|
|
private IEnumerator EnterGame()
|
|
|
|
|
|
{
|
|
|
|
|
|
var op = Addressables.LoadSceneAsync(START_SCENE_NAME, LoadSceneMode.Single);
|
|
|
|
|
|
yield return op;
|
|
|
|
|
|
if (op.Status != AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
2023-11-08 19:04:23 +08:00
|
|
|
|
Debug.LogError(
|
|
|
|
|
|
$"load scene failed,exception:{op.OperationException.Message} \r\n {op.OperationException.StackTrace}");
|
2023-10-19 15:00:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-22 12:41:18 +08:00
|
|
|
|
|
2023-11-08 19:04:23 +08:00
|
|
|
|
}
|