using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Cysharp.Threading.Tasks; using Main; using Stary.Evo.InformationSave; using UnityEngine; using UnityEngine.SceneManagement; using YooAsset; namespace Stary.Evo { public class DomainAssetSystem : IDisposable { private static OpenDomainType _openDomainType { get; set; } private static TransformCtor _transformCtor { get; set; } public static ProgressBarPanel ProgressBarPanel { get; set; } private static readonly List _domainStaticNameEntities = new List(); private static List _domainNameEntities = new List(); public static void LoadDoaminAsset() { } public static void AddDomainNameEntity(DomainConfig domainName) { _domainNameEntities.Add(domainName); } public static void AddDomainStaticNameEntity(DomainConfig domainName) { _domainStaticNameEntities.Add(domainName); } public static void DeleteDomainNameEntity(DomainConfig domainName) { _domainNameEntities.Remove(domainName); } public static void DeleteDomainStaticNameEntity(DomainConfig domainName) { _domainStaticNameEntities.Remove(domainName); } public static async UniTask LoadDomainPrefab(DomainConfig domainConfig) { var package = YooAssets.GetPackage(domainConfig.domain); // 加载热更资源 var loadOperation = package.LoadAssetAsync(domainConfig.mainPrefab); await loadOperation; if (loadOperation.Status == EOperationStatus.Succeed) { var gameObject = loadOperation.InstantiateSync(); gameObject.name = domainConfig.domain; return gameObject; } else { Debug.LogErrorFormat("加载热更资源失败,资源路径为--【{0}】--", loadOperation.LastError); throw new System.Exception(loadOperation.LastError); } } public static async UniTask SetTransformInfo(GameObject gameObject) { LocalTransformInfo info = gameObject.GetOrAddComponent(); if (info._list.Count >= 2) { if (_openDomainType == OpenDomainType.PointCloud) { info.Switch(1); } else if (_openDomainType == OpenDomainType.VIOICE) { info.Switch(0); } else if (_openDomainType == OpenDomainType.ImageTracked) { info.transform.position = _transformCtor.position; info.transform.rotation = Quaternion.Euler(_transformCtor.rotation); info.transform.localScale = _transformCtor.scale; } else { info.Switch(0); } } else { Debug.LogError($"UnityEvo:{gameObject.name}的TransformInfo长度小于2,无法继续运行,请排查"); } } public static async UniTask BindableProperty(DomainConfig domainConfig, GameObject gameObject, Type type) { DomainBase hotfixInstance = gameObject.GetComponent(type) as DomainBase; if (hotfixInstance == null) { hotfixInstance = gameObject.AddComponent(type) as DomainBase; } if (hotfixInstance == null) { Debug.LogError($"热更类{type.Name}实例创建失败!必须继承MonoBehaviour"); return; } hotfixInstance.DomainName = domainConfig.domain; hotfixInstance.DomainNameRaw = $"{domainConfig.domain}_RawFile"; // 原有调用逻辑修改为使用实例 hotfixInstance.OnEnter(""); hotfixInstance.OnEnterAsync(""); } public static async UniTask RemoveDomain(DomainConfig domainConfig) { bool isQuit = (domainConfig.loadResType == DomainConfig.LoadResType.Prefab && domainConfig.domainLoadType == DomainConfig.DomainLoadType.Single) || (domainConfig.loadResType == DomainConfig.LoadResType.Scene && domainConfig.loadSceneMode == LoadSceneMode.Single); if (!isQuit) return; foreach (var entity in _domainNameEntities) { if (entity.loadResType == DomainConfig.LoadResType.Prefab) { await DomainAssetSystem.UnloadDomainAsset(entity); } else if (entity.loadResType == DomainConfig.LoadResType.Scene) { await DomainAssetSystem.UnloadSceneAsset(entity); } } } public static async UniTask UnloadDomainAsset(DomainConfig config) { if (HybridClREntrance.Global.stage == StageType.Developer) { var mainPrefab = GameObject.Find(config.domain); if (mainPrefab == null) { Debug.LogError($"UnityEvo:{config.domain}不存在,无法卸载"); return; } DomainBase domainBase = mainPrefab.GetOrAddComponent(); if (domainBase == null) { Debug.LogError($"UnityEvo:{mainPrefab.name}的DomainBase为空,无法退出,请排查"); } else { domainBase.OnExit(); await domainBase.OnExitAsync(); GameObject.Destroy(domainBase.gameObject); await ForceUnloadAllAssets(domainBase.DomainName); await ForceUnloadAllAssets(domainBase.DomainNameRaw); } Debug.Log($"UnityEvo:{config.domain} 退出成功..."); } else if (HybridClREntrance.Global.stage == StageType.Originality) { await ForceUnloadAllAssets(config.domain); AppConfig.PackageDomainName = ""; Debug.Log("UnityEvo:Domain退出..."); } } public static async UniTask UnloadSceneAsset(DomainConfig config) { if (config.loadResType == DomainConfig.LoadResType.Scene) { string sceneName = config.sceneIdentifier; if (sceneName == "") { Debug.LogError($"UnityEvo:{config.domain} 未配置场景名称,无法卸载"); return; } // 匹配开头到下划线的所有内容,替换为空 sceneName = Regex.Replace(sceneName, @"^[^_]*_", ""); await SceneManager.UnloadSceneAsync(sceneName); await ForceUnloadAllAssets(config.domain); AppConfig.PackageDomainName = ""; Debug.Log("UnityEvo:Domain退出..."); } } // 强制卸载所有资源包,该方法请在合适的时机调用。 // 注意:Package在销毁的时候也会自动调用该方法。 private static async UniTask ForceUnloadAllAssets(string packageName) { var package = YooAssets.TryGetPackage(packageName); if (package != null && package.InitializeStatus == EOperationStatus.Succeed) { var operation = package.UnloadAllAssetsAsync(); await operation; await package.DestroyAsync(); YooAssets.RemovePackage(packageName); Resources.UnloadUnusedAssets(); GC.Collect(); GC.WaitForPendingFinalizers(); Debug.Log($"UnityEvo:{packageName} 资源包已卸载..."); } else { Debug.LogWarning($"UnityEvo:{packageName} 资源包不存在,请检查是否已经卸载还是卸载异常..."); } } public void Dispose() { foreach (var entity in _domainStaticNameEntities) { DeleteDomainStaticNameEntity(entity); } _domainStaticNameEntities.Clear(); foreach (var entity in _domainNameEntities) { DeleteDomainNameEntity(entity); } _domainNameEntities.Clear(); if (ProgressBarPanel != null) { GameObject.Destroy(ProgressBarPanel); } } public static void SetOpenDomainType(OpenDomainType type) { _openDomainType = type; } public static void SetTransformCtor(Transform transform) { _transformCtor = transform.GetTransformCtor(); } public static void SetTransformCtor(TransformCtor transformCtor) { transformCtor = transformCtor; } } }