using Code.Scripts.HotUpdate.UI; using Cysharp.Threading.Tasks; using PhxhSDK.AOT; using PhxhSDK.AOT.SimpleLoader; using PhxhSDK.AOT.VersionUpdate; using System; using PhxhSDK.AOT.PreConfig; using UnityEngine; using UnityEngine.SceneManagement; using Assets.PhxhSDK.AOT.BI; #if PLATFORM_ANDROID using UnityEngine.Android; #endif #if SDK_BILIBILI using PhxhSDK.AOT.Bilibili; #endif public class GameLauncher : MonoBehaviour { const string START_SCENE_NAME = "Assets/Scenes/StartScene.unity"; //最大能容忍的下载卡住时长,一旦超过则重新开始下载 // private const float DOWNLOAD_STUCK_TIME_MAX = 10; #if USE_HCLR private HybridCLRHelper _hybridCLRHelper; #endif private VersionUpdateHandle _versionUpdateHandle; private ISimpleLoader _simpleLoader; private IVersionUpdateUI versionUpdateUI; public bool enableHotUpdate = true; private void Awake() { #if SDK_BILIBILI GameObject goBiliBiliSDK = new() { name = "BiliBiliSDK" }; if (!goBiliBiliSDK.TryGetComponent(out _)) goBiliBiliSDK.AddComponent(); if (!goBiliBiliSDK.TryGetComponent(out _)) goBiliBiliSDK.AddComponent(); DontDestroyOnLoad(goBiliBiliSDK); #endif } private void Start() { #if SDK_BILIBILI GSCSdkInterface.init(); #endif versionUpdateUI = new TempUIHandle(); bool agreement = PlayerPrefs.GetInt("PrivacyAgreement", 0) == 1; #if SDK_BILIBILI // B站不弹自己的隐私弹窗 agreement = true; #endif if (!agreement) // 弹隐私弹窗 { TempUpdateUI.Instance.PrivacyAgreeCallback = () => { TempUpdateUI.Instance.m_ProgressObj.SetActive(true); Launch(); }; TempUpdateUI.Instance.m_PrivacyDialogObj.SetActive(true); } else { TempUpdateUI.Instance.m_ProgressObj.SetActive(true); Launch(); } } private async void Launch() { #if UNITY_EDITOR enableHotUpdate = false; #endif #if PLATFORM_ANDROID if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite)) { Permission.RequestUserPermission(Permission.ExternalStorageWrite); } #endif versionUpdateUI.UpdateProgress(0f); versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("NetworkConnection")); // 尝试网络连接中... _versionUpdateHandle = new VersionUpdateHandle(versionUpdateUI); VersionUpdateInfo versionUpdateInfo = _versionUpdateHandle.GetVersionInfo(); PackDataInst.CreateInst(); UpdateLocalInfo localInfo = PackDataInst.inst.localInfo; string acquiring = LocalizeMono.Instance.GetLocalizeText("Acquiring"); // 获取中... versionUpdateUI.ShowVersion(Application.version, localInfo.workSpace, localInfo.localFullVersion, acquiring, acquiring); #if SDK_TALKINGDATA BIToolinAOT.Instance.Init(TalkingDataInitTool.appID, TalkingDataInitTool.channel);//TalkingData初始化 BIToolinAOT.Instance.TalkingDataStart(); BIToolinAOT.Instance.TrackEventInAOT("app_open", null); #endif PlayerPrefs.SetString("BI_Platform", TalkingDataInitTool.channel); #region 更新AppConfig bool downloadResult; do { try { versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("RequestConfiguration")); // 开始请求APPConfig BIToolinAOT.Instance.TrackEventInAOT("app_config_request", null); downloadResult = await PreConfig.instance.DownloadConfig(); versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("RequestConfigurationComplete")); // 请求APPConfig结束 versionUpdateUI.ShowVersion(Application.version, localInfo.workSpace, localInfo.localFullVersion, acquiring, PreConfig.instance.ServerName); BIToolinAOT.Instance.TrackEventInAOT("app_config_response", new System.Collections.Generic.Dictionary(){ {"result", downloadResult? 0 : 1 } }); } catch (Exception) { downloadResult = false; } } while (!downloadResult && await versionUpdateUI.ShowDialog(LocalizeMono.Instance.GetLocalizeText("Tip"), LocalizeMono.Instance.GetLocalizeText("DownloadConfigErrorRetry"))); // 下载配置文件失败,是否重试? if (!downloadResult) TempUpdateUI.Instance.OnClickCancel(); #endregion if (!PreConfig.instance.isConfigValid) { // 配置错误,没有读取到ResUrl // TODO: 这种情况也应该有个弹出框,提示用户配置文件错误 Debug.LogError("配置文件错误"); await versionUpdateUI.ShowDialog(LocalizeMono.Instance.GetLocalizeText("Tip"), LocalizeMono.Instance.GetLocalizeText("ConfigError")); // 配置文件错误 TempUpdateUI.Instance.OnClickCancel(); return; } #if USE_YOO await YooAssetHelper.Init(); _simpleLoader = new SimpleLoader_YooAsset(); #else _simpleLoader = new SimpleLoader_Addressables(); #endif Debug.Log($"Launch Game! enableHotUpdate:{enableHotUpdate}"); bool result = await _versionUpdateHandle.CheckUpdate();//这里会打点资源检测更新事件 if (!result) { Debug.LogError("更新失败!,无法进入游戏"); return; } if (enableHotUpdate) { #if USE_HCLR Debug.Log("需要热更新,开始加载程序集"); _hybridCLRHelper = new HybridCLRHelper(); _hybridCLRHelper.SetDllList(AOTGenericReferences.PatchedAOTAssemblyList); _hybridCLRHelper.RegistLoader(_simpleLoader); await _hybridCLRHelper.LoadAssemblies(); Debug.Log("加载程序集结束!"); #endif } await _simpleLoader.WarmUpShader(); await EnterGame(); } private async UniTask EnterGame() { Debug.Log("开始加载游戏场景"); SimulationProgress(versionUpdateUI.GetCurProgress()); try { Scene scene = await _simpleLoader.LoadSceneAsync(START_SCENE_NAME, LoadSceneMode.Additive); foreach (GameObject go in scene.GetRootGameObjects()) { if ("EventSystem".Equals(go.name)) { Destroy(go); break; } } } catch (Exception e) { Debug.LogError(e); } finally { await LoadOver(); Debug.Log("加载游戏场景结束"); } } private async void SimulationProgress(float startProgress) { versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("InitGaming")); // 初始化游戏... versionUpdateUI.UpdateProgress(startProgress); float step = (1f - startProgress) * 0.02f; while (startProgress + step <= 0.99f) { await UniTask.Delay(20); startProgress += step; versionUpdateUI.UpdateProgress(startProgress); } } private async UniTask LoadOver() { while (true) { await UniTask.Yield(); // Debug.Log($"校验是否加载完:{IVersionUpdateUI.IsLoadOver}"); if (IVersionUpdateUI.IsLoadOver) { versionUpdateUI.UpdateProgress(1f); versionUpdateUI.UpdateProgressText(LocalizeMono.Instance.GetLocalizeText("Complete")); // 完成 await UniTask.Delay(200); versionUpdateUI.CloseAll(); return; } } } }