using AOT.Boot; using AOT.HotUpdate; using AOT.Patch; using AOT.UI; using UnityEngine; namespace AOT.Boot { /// /// 壳层启动入口:版本检查 → 资源补丁 → HybridCLR/热更入口。 /// public sealed class BootDriver : MonoBehaviour { [SerializeField] BootSettings settings = new BootSettings(); BootPatchView _view; void Awake() { Application.targetFrameRate = 60; Screen.sleepTimeout = SleepTimeout.NeverSleep; DontDestroyOnLoad(gameObject); if (Screen.orientation != ScreenOrientation.Portrait) Screen.orientation = ScreenOrientation.Portrait; } void Start() { _view = BootPatchView.Create(); StartCoroutine(Bootstrap()); } System.Collections.IEnumerator Bootstrap() { BootContext ctx = null; string error = null; var runner = new PatchRunner(this, settings, _view); yield return runner.Run((c, e) => { ctx = c; error = e; }); if (!string.IsNullOrEmpty(error) || ctx == null) { _view?.SetError(error ?? "启动失败"); Debug.LogError($"[Boot] {error}"); yield break; } _view?.SetStatus("加载热更代码…"); _view?.SetProgress(0.97f); string loadError = null; yield return HotUpdateLoader.LoadAndStart(ctx, settings, e => loadError = e); if (!string.IsNullOrEmpty(loadError)) { _view?.SetError(loadError); Debug.LogError($"[Boot] {loadError}"); yield break; } _view?.SetProgress(1f); _view?.SetStatus("热更已启动"); Debug.Log($"[Boot] OK app={ctx.AppVersion} res={ctx.ResVersion} pack={ctx.PackVersion} cdn={ctx.CdnRoot}"); // Prefabs/atlases load asynchronously; two frames are not a readiness guarantee. _view?.SetStatus("加载主界面…"); float uiDeadline = Time.realtimeSinceStartup + 120f; while (!ctx.MainUiReady && string.IsNullOrEmpty(ctx.MainUiError) && Time.realtimeSinceStartup < uiDeadline) yield return null; if (!ctx.MainUiReady) { string uiError = ctx.MainUiError ?? "主界面加载超时,请检查 Art 资源包后重试"; _view?.SetError(uiError); Debug.LogError("[Boot] " + uiError); yield break; } yield return null; _view?.Hide(); } } }