Add hot-update boot pipeline, UI bundles/atlas assets, and design docs.
Ignore AIClient/Library and AIClient/HybridCLRData permanently; include HybridCLR/YooAsset project setup and UI tooling. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using YooAsset;
|
||||
|
||||
namespace AOT.Boot
|
||||
{
|
||||
/// <summary>
|
||||
/// 壳层传给热更入口的运行时上下文。
|
||||
/// </summary>
|
||||
public sealed class BootContext
|
||||
{
|
||||
public string AppVersion;
|
||||
public string ResVersion;
|
||||
public string CdnRoot;
|
||||
public string PackageName;
|
||||
public ResourcePackage Package;
|
||||
public string WsUrlTemplate;
|
||||
|
||||
public string BuildWsUrl(string pid, string token = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(WsUrlTemplate))
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return $"wss://game.xworld.ren/ws?pid={pid}";
|
||||
return $"wss://game.xworld.ren/ws?pid={pid}&token={UnityEngine.Networking.UnityWebRequest.EscapeURL(token)}";
|
||||
}
|
||||
|
||||
var url = WsUrlTemplate.Replace("{pid}", pid ?? string.Empty);
|
||||
if (url.Contains("{token}"))
|
||||
url = url.Replace("{token}", UnityEngine.Networking.UnityWebRequest.EscapeURL(token ?? string.Empty));
|
||||
else if (!string.IsNullOrEmpty(token))
|
||||
url += (url.Contains("?") ? "&" : "?") + "token=" + UnityEngine.Networking.UnityWebRequest.EscapeURL(token);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a57e0242ddf4ff48af5d8e8a763e105
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
using AOT.Boot;
|
||||
using AOT.HotUpdate;
|
||||
using AOT.Patch;
|
||||
using AOT.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AOT.Boot
|
||||
{
|
||||
/// <summary>
|
||||
/// 壳层启动入口:版本检查 → 资源补丁 → HybridCLR/热更入口。
|
||||
/// </summary>
|
||||
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} cdn={ctx.CdnRoot}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d11b543accc52448b82d773c022254c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace AOT.Boot
|
||||
{
|
||||
/// <summary>
|
||||
/// Boot 可序列化配置(挂在 BootDriver 上)。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class BootSettings
|
||||
{
|
||||
[Tooltip("壳版本,对应提审包 appVersion")]
|
||||
public string AppVersion = "1.0.0";
|
||||
|
||||
[Tooltip("CDN 总控 version.json")]
|
||||
public string VersionUrl = "https://www.xworld.ren/wechat/version.json";
|
||||
|
||||
[Tooltip("CDN 根(version.json 未下发 cdnRoot 时回退;含 Package 名)")]
|
||||
public string DefaultCdnRoot = "https://www.xworld.ren/wechat/1.0.0/DefaultPackage";
|
||||
|
||||
[Tooltip("YooAsset 默认包名")]
|
||||
public string PackageName = "DefaultPackage";
|
||||
|
||||
[Tooltip("热更 DLL 在包内的定位地址")]
|
||||
public string HotUpdateDllLocation = "HotUpdate.Runtime";
|
||||
|
||||
[Tooltip("WebSocket 模板,{pid}/{token} 会被替换")]
|
||||
public string WsUrlTemplate = "wss://game.xworld.ren/ws?pid={pid}&token={token}";
|
||||
|
||||
[Tooltip("运行模式;编辑器默认 EditorSimulateMode;M1 Offline/Host 验证时切换")]
|
||||
public EPlayMode PlayMode = EPlayMode.EditorSimulateMode;
|
||||
|
||||
[Tooltip("编辑器下跳过 YooAsset 补丁,直接反射加载已编译热更程序集(M0 默认开;M1 验证补丁时关掉)")]
|
||||
public bool EditorDirectHotUpdate = true;
|
||||
|
||||
[Tooltip("version.json 拉取失败时是否允许使用 StreamingAssets 本地回退")]
|
||||
public bool AllowStreamingVersionFallback = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2c6317a2a3e50f4ca2bed34aafc0291
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user