You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

446 lines
15 KiB

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<UnityObject, OperationHandleBase> _Obj2Handle = new();
private static readonly Dictionary<GameObject, UnityObject> _GO2Obj = new();
private static readonly Dictionary<string, List<UnityObject>> _ObjsInTag = new();
// 加载图集中的图片规则为:图集名[图片名],跟addressable中相同
// 例如:BuildingAtlas[Build_1001]
private static readonly Regex _SA_MATCH = new("[*.\\w/]+");
private static PatchDownloaderOperation _DOWNLOADER;
public static Action<int, int, long, long> OnDownloadProgress;
public static ETTask<AsyncOperationBase> 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<int> 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<bool> 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<bool> Download(IProgress<float> 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<GameObject> InstantiateAsync(string location,
Transform parent_transform = null,
bool stay_world_space = false,
IProgress<float> progress = null)
{
var handle = YooAssets.LoadAssetAsync<GameObject>(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<GameObject>(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<T> LoadAssetAsync<T>(string location, IProgress<float> progress = null)
where T : UnityObject
{
return await LoadAssetAsync(location, typeof (T)) as T;
}
public static async ETTask<UnityObject> 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<SpriteAtlas>(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<T>(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<SpriteAtlas>(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<RawFileOperation> GetRawFileAsync(string path)
{
ETTask<RawFileOperation> result = ETTask<RawFileOperation>.Create();
RawFileOperation rawFileOperation = YooAssets.GetRawFileAsync(path);
rawFileOperation.Completed += handle => { result.SetResult(rawFileOperation); };
return result;
}
public static async ETTask<Dictionary<string, UnityObject>> GetAssetsByTagAsync(string tag)
{
if (!_ObjsInTag.TryGetValue(tag, out List<UnityObject> objs))
{
objs = new List<UnityObject>();
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<UnityObject>(assetInfo.Address);
objs.Add(obj);
}
// foreach (var assetInfo in assetInfos)
// {
// Debug.Log(assetInfo.Address);
// Debug.Log(assetInfo.AssetPath);
//
// var obj = await LoadAssetAsync<UnityObject>(assetInfo.Address);
// objs.Add(obj);
// }
}
Dictionary<string, UnityObject> objectDict = new Dictionary<string, UnityObject>();
foreach (UnityObject o in objs)
{
objectDict.Add(o.name, o);
}
return objectDict;
}
public static Dictionary<string, UnityObject> GetAssetsByTagSync(string tag)
{
if (!_ObjsInTag.TryGetValue(tag, out List<UnityObject> objs))
{
objs = new List<UnityObject>();
AssetInfo[] assetInfos = YooAssets.GetAssetInfos(tag);
for (int i = 0; i < assetInfos.Length; i++)
{
var assetInfo = assetInfos[i];
var obj = LoadAssetSync<UnityObject>(assetInfo.Address);
objs.Add(obj);
}
// foreach (var assetInfo in assetInfos)
// {
// Debug.Log(assetInfo.Address);
// Debug.Log(assetInfo.AssetPath);
//
// var obj = await LoadAssetAsync<UnityObject>(assetInfo.Address);
// objs.Add(obj);
// }
}
Dictionary<string, UnityObject> objectDict = new Dictionary<string, UnityObject>();
foreach (UnityObject o in objs)
{
objectDict.Add(o.name, o);
}
return objectDict;
}
public static void ReleaseByTag(string tag)
{
if (_ObjsInTag.TryGetValue(tag, out List<UnityObject> 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();
}
}
}