using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using ET; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.U2D; using UnityObject = UnityEngine.Object; namespace YooAsset { public static class YooAssetWrapper { private static readonly Dictionary _Obj2Handle = new(); private static readonly Dictionary _GO2Obj = new(); private static readonly Dictionary> _ObjsInTag = new(); // 加载图集中的图片规则为:图集名[图片名],跟addressable中相同 // 例如:BuildingAtlas[Build_1001] private static readonly Regex _SA_MATCH = new("[*.\\w/]+"); private static PatchDownloaderOperation _DOWNLOADER; public static Action OnDownloadProgress; public static ETTask InitializeAsync(YooAssets.EPlayMode play_mode) { YooAssets.InitializeParameters parameters = play_mode switch { YooAssets.EPlayMode.EditorSimulateMode => new YooAssets.EditorSimulateModeParameters(), YooAssets.EPlayMode.OfflinePlayMode => new YooAssets.OfflinePlayModeParameters(), YooAssets.EPlayMode.HostPlayMode => new YooAssets.HostPlayModeParameters { DecryptionServices = null, ClearCacheWhenDirty = false, DefaultHostServer = GetHostServerURL(), FallbackHostServer = GetHostServerURL() }, _ => throw new ArgumentOutOfRangeException(nameof(play_mode), play_mode, null) }; parameters.LocationServices = new AddressLocationServices(); return YooAssets.InitializeAsync(parameters).ToETTask(); } public static string GetHostServerURL() { string hostServerIP = "http://127.0.0.1:8080"; string gameVersion = "100"; return $"{hostServerIP}/StandaloneWindows64/{gameVersion}"; } public static IEnumerator Initialize(YooAssets.EPlayMode play_mode) { YooAssets.InitializeParameters parameters = play_mode switch { YooAssets.EPlayMode.EditorSimulateMode => new YooAssets.EditorSimulateModeParameters(), YooAssets.EPlayMode.OfflinePlayMode => new YooAssets.OfflinePlayModeParameters(), YooAssets.EPlayMode.HostPlayMode => new YooAssets.HostPlayModeParameters { DecryptionServices = null, ClearCacheWhenDirty = false, DefaultHostServer = GetHostServerURL(), FallbackHostServer = GetHostServerURL() }, _ => throw new ArgumentOutOfRangeException(nameof(play_mode), play_mode, null) }; parameters.LocationServices = new AddressLocationServices(); return YooAssets.InitializeAsync(parameters); } public static async ETTask UpdateStaticVersion(int time_out = 30) { var operation = YooAssets.UpdateStaticVersionAsync(time_out); await operation.ToETTask(); if(operation.Status != EOperationStatus.Succeed) { return -1; } return operation.ResourceVersion; } public static async ETTask UpdateManifest(int resource_version, int time_out = 30) { var operation = YooAssets.UpdateManifestAsync(resource_version, time_out); await operation.ToETTask(); return operation.Status == EOperationStatus.Succeed; } public static long GetDownloadSize(int downloading_max_num = 10, int retry = 3) { _DOWNLOADER = YooAssets.CreatePatchDownloader(downloading_max_num, retry); return _DOWNLOADER.TotalDownloadCount == 0 ? 0 : _DOWNLOADER.TotalDownloadBytes; } public static async ETTask Download(IProgress progress = null) { if(_DOWNLOADER is null) { return false; } _DOWNLOADER.OnDownloadProgressCallback = (count, downloadCount, bytes, downloadBytes) => { OnDownloadProgress?.Invoke(count, downloadCount, bytes, downloadBytes); }; _DOWNLOADER.BeginDownload(); await _DOWNLOADER.ToETTask(); return _DOWNLOADER.Status == EOperationStatus.Succeed; } public static int GetResourceVersion() { return YooAssets.GetResourceVersion(); } public static async ETTask InstantiateAsync(string location, Transform parent_transform = null, bool stay_world_space = false, IProgress progress = null) { var handle = YooAssets.LoadAssetAsync(location); await handle.ToETTask(); if(!handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load asset: {location}"); } _Obj2Handle.TryAdd(handle.AssetObject, handle); if(UnityObject.Instantiate(handle.AssetObject, parent_transform, stay_world_space) is not GameObject go) { Release(handle.AssetObject); throw new Exception($"[YooAssetsWrapper] Failed to instantiate asset: {location}"); } _GO2Obj.Add(go, handle.AssetObject); return go; } public static GameObject InstantiateSync(string location, Transform parent_transform = null, bool stay_world_space = false) { var handle = YooAssets.LoadAssetSync(location); if(!handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load asset: {location}"); } _Obj2Handle.TryAdd(handle.AssetObject, handle); if(UnityObject.Instantiate(handle.AssetObject, parent_transform, stay_world_space) is not GameObject go) { Release(handle.AssetObject); throw new Exception($"[YooAssetsWrapper] Failed to instantiate asset: {location}"); } _GO2Obj.Add(go, handle.AssetObject); return go; } public static async ETTask LoadAssetAsync(string location, IProgress progress = null) where T : UnityObject { return await LoadAssetAsync(location, typeof (T)) as T; } public static async ETTask LoadAssetAsync(string location, Type type) { string path = ""; if(type == typeof(Sprite)) { var matches = _SA_MATCH.Matches(location); if(matches.Count == 2) { var atlasLocation = matches[0].Value; path = YooAssets.GetAssetPath(atlasLocation); if (string.IsNullOrEmpty(path)) { return null; } var sa_handle = YooAssets.LoadAssetAsync(matches[0].Value); await sa_handle.ToETTask(); if(!sa_handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load sprite atlas: {matches[0].Value}"); } if(sa_handle.AssetObject is not SpriteAtlas sa) { sa_handle.Release(); throw new Exception($"[YooAssetsWrapper] Failed to load sprite atlas: {matches[0].Value}"); } var sprite = sa.GetSprite(matches[1].Value); if(sprite is null) { sa_handle.Release(); throw new Exception($"[YooAssetsWrapper] Failed to load sprite: {location}"); } _Obj2Handle.TryAdd(sprite, sa_handle); return sprite; } } path = YooAssets.GetAssetPath(location); if (string.IsNullOrEmpty(path)) { return null; } var handle = YooAssets.LoadAssetAsync(location, type); await handle.ToETTask(); if(!handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load asset: {location}"); } _Obj2Handle.TryAdd(handle.AssetObject, handle); return handle.AssetObject; } public static T LoadAssetSync(string location) where T : UnityObject { return LoadAssetSync(location, typeof (T)) as T; } public static UnityObject LoadAssetSync(string location, Type type) { string path = ""; if(type == typeof(Sprite)) { var matches = _SA_MATCH.Matches(location); if(matches.Count == 2) { var atlasLocation = matches[0].Value; path = YooAssets.GetAssetPath(atlasLocation); if (string.IsNullOrEmpty(path)) { return null; } var sa_handle = YooAssets.LoadAssetSync(matches[0].Value); if(!sa_handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load sprite atlas: {matches[0].Value}"); } if(sa_handle.AssetObject is not SpriteAtlas sa) { sa_handle.Release(); throw new Exception($"[YooAssetsWrapper] Failed to load sprite atlas: {matches[0].Value}"); } var sprite = sa.GetSprite(matches[1].Value); if(sprite is null) { sa_handle.Release(); throw new Exception($"[YooAssetsWrapper] Failed to load sprite: {location}"); } _Obj2Handle.TryAdd(sprite, sa_handle); return sprite; } } path = YooAssets.GetAssetPath(location); if (string.IsNullOrEmpty(path)) { return null; } var handle = YooAssets.LoadAssetSync(location, type); if(!handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load asset: {location}"); } _Obj2Handle.TryAdd(handle.AssetObject, handle); return handle.AssetObject; } public static async ETTask LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true) { SceneOperationHandle handle = YooAssets.LoadSceneAsync(location, sceneMode, activateOnLoad); await handle.ToETTask(); if(!handle.IsValid) { throw new Exception($"[YooAssetsWrapper] Failed to load scene: {location}"); } } public static ETTask GetRawFileAsync(string path) { ETTask result = ETTask.Create(); RawFileOperation rawFileOperation = YooAssets.GetRawFileAsync(path); rawFileOperation.Completed += handle => { result.SetResult(rawFileOperation); }; return result; } public static async ETTask> GetAssetsByTagAsync(string tag) { if (!_ObjsInTag.TryGetValue(tag, out List objs)) { objs = new List(); AssetInfo[] assetInfos = YooAssets.GetAssetInfos(tag); for (int i = 0; i < assetInfos.Length; i++) { var assetInfo = assetInfos[i]; Debug.Log(assetInfo.Address); var obj = await LoadAssetAsync(assetInfo.Address); objs.Add(obj); } // foreach (var assetInfo in assetInfos) // { // Debug.Log(assetInfo.Address); // Debug.Log(assetInfo.AssetPath); // // var obj = await LoadAssetAsync(assetInfo.Address); // objs.Add(obj); // } } Dictionary objectDict = new Dictionary(); foreach (UnityObject o in objs) { objectDict.Add(o.name, o); } return objectDict; } public static Dictionary GetAssetsByTagSync(string tag) { if (!_ObjsInTag.TryGetValue(tag, out List objs)) { objs = new List(); AssetInfo[] assetInfos = YooAssets.GetAssetInfos(tag); for (int i = 0; i < assetInfos.Length; i++) { var assetInfo = assetInfos[i]; var obj = LoadAssetSync(assetInfo.Address); objs.Add(obj); } // foreach (var assetInfo in assetInfos) // { // Debug.Log(assetInfo.Address); // Debug.Log(assetInfo.AssetPath); // // var obj = await LoadAssetAsync(assetInfo.Address); // objs.Add(obj); // } } Dictionary objectDict = new Dictionary(); foreach (UnityObject o in objs) { objectDict.Add(o.name, o); } return objectDict; } public static void ReleaseByTag(string tag) { if (_ObjsInTag.TryGetValue(tag, out List objs)) { foreach (UnityObject o in objs) { Release(o); } _ObjsInTag.Remove(tag); } } public static void ReleaseInstance(GameObject go) { if(go is null) { return; } UnityObject.Destroy(go); _GO2Obj.Remove(go, out UnityObject obj); Release(obj); } public static void Release(UnityObject obj) { if(obj is null) { return; } _Obj2Handle.Remove(obj, out OperationHandleBase handle); handle?.Release(); } } }