Files
2026-02-02 17:58:39 +08:00

431 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Fantasy.Async;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
namespace NBC.Asset
{
public static class Assets
{
private static GameObject _monoGameObject;
private static bool _isInitialize;
private static NTaskStatus _initializeTaskStatus = NTaskStatus.None;
private static string _initializeError = string.Empty;
public static InitializationTask Initialize()
{
if (_isInitialize)
throw new Exception($"Repeated initialization!");
return InitConfirm();
}
#region
/// <summary>
/// 清理所有缓存
/// </summary>
public static void ClearAllCache()
{
if (Directory.Exists(Const.SavePath))
{
Directory.Delete(Const.SavePath, true);
}
}
#endregion
#region
public static T Load<T>(string path) where T : Object
{
var assetProvider = LoadAsset(path, typeof(T));
if (assetProvider != null)
{
return assetProvider.Asset as T;
}
return default(T);
}
public static async FTask<T> LoadAsync<T>(string path) where T : Object
{
var assetProvider = LoadAssetAsync(path, typeof(T));
await assetProvider.Task;
if (assetProvider.Asset != null)
{
return assetProvider.Asset as T;
}
return null;
}
public static AssetProvider LoadAsset<T>(string path)
{
return LoadAsset(path, typeof(T));
}
public static AssetProvider LoadAsset(string path, Type type)
{
var req = LoadAssetAsync(path, type);
req?.WaitForAsyncComplete();
return req;
}
public static AssetProvider LoadAssetAsync<T>(string path)
{
return LoadAssetAsync(path, typeof(T));
}
public static AssetProvider LoadAssetAsync(string path, Type type)
{
var assetInfo = Addressable.GetAssetInfo(path, type);
return AssetProvider.GetAssetProvider(assetInfo);
}
public static AssetProvider LoadAssetAll<T>(string path)
{
return LoadAssetAll(path, typeof(T));
}
public static AssetProvider LoadAssetAll(string path, Type type)
{
var req = LoadAssetAllAsync(path, type);
req?.WaitForAsyncComplete();
return req;
}
public static AssetProvider LoadAssetAllAsync<T>(string path)
{
return LoadAssetAllAsync(path, typeof(T));
}
public static AssetProvider LoadAssetAllAsync(string path, Type type)
{
var assetInfo = Addressable.GetAssetInfo(path, type);
return AssetProvider.GetAssetProvider(assetInfo, true);
}
#endregion
#region
public static SceneProvider LoadScene(string path, bool additive = false)
{
var assetInfo = Addressable.GetAssetInfo(path, typeof(Scene));
if (assetInfo == null)
{
throw new Exception($"Scene is null,path={path}");
}
return SceneProvider.GetSceneProvider(assetInfo, additive);
}
#endregion
#region
/// <summary>
/// 释放所有资源
/// </summary>
/// <param name="force">强制释放</param>
public static void ReleaseAllAssets(bool force = true)
{
AssetProvider.ReleaseAllAssets(force);
SceneProvider.ReleaseAllAssets(force);
}
/// <summary>
/// 根据标签,释放所有资源
/// </summary>
/// <param name="tags">标签</param>
/// <param name="force">强制释放</param>
public static void ReleaseAllAssetsByTag(string[] tags, bool force = true)
{
AssetProvider.ReleaseAllAssetsByTag(tags, force);
SceneProvider.ReleaseAllAssetsByTag(tags, force);
}
#endregion
#region
/// <summary>
/// 可以解压的bundle包数量
/// </summary>
/// <returns></returns>
public static int CanUnpackBundleCount()
{
var arr = Addressable.GetCanUnpackBundles();
return arr != null ? arr.Length : 0;
}
/// <summary>
/// 解压资源包任务(解压本地存在的所有资源)
/// </summary>
/// <param name="run">自动运行</param>
/// <returns></returns>
public static UnpackPackagesTask CreateUnpackPackagesTask(bool run = true)
{
var task = new UnpackPackagesTask();
if (run) task.Run(TaskRunner.Def);
return task;
}
#endregion
#region
/// <summary>
/// 获取当前版本可以下载到本地的bundle包
/// </summary>
/// <returns></returns>
public static List<BundleInfo> GetCanDownloadBundles()
{
List<BundleInfo> ret = new List<BundleInfo>();
var bundles = Addressable.GetCanDownloadBundles();
foreach (var bundleInfo in bundles)
{
var bundleData = bundleInfo.Bundle;
//可优化。缓存所有packageName但该逻辑理论全局只会调用一次是否需要缓存值得考虑
if (bundleData != null && IsNeedfulPackage(bundleData.PackageName))
{
ret.Add(bundleInfo);
}
}
return ret;
}
/// <summary>
/// 主动下载需要的bundles包任务
/// </summary>
/// <param name="downloadBundles">需要下载的bundle</param>
/// <param name="run">自动运行</param>
/// <returns></returns>
public static DownloadBundlesTask CreateDownloadBundlesTask(List<BundleInfo> downloadBundles, bool run = true)
{
var task = new DownloadBundlesTask(downloadBundles);
if (run) task.Run();
return task;
}
/// <summary>
/// 创建检查更新任务
/// </summary>
/// <returns></returns>
public static CheckUpdateTask CreateCheckUpdateTask(bool run = true)
{
var task = new CheckUpdateTask();
if (run) task.Run(TaskRunner.Def);
return task;
}
/// <summary>
/// 创建版本更新任务
/// </summary>
public static UpdateVersionTask CreateUpdateVersionTask(UpdateContext context, bool run = true)
{
var task = new UpdateVersionTask(context);
if (run) task.Run();
return task;
}
#endregion
#region
private static readonly HashSet<string> _defaultPackage = new HashSet<string>();
/// <summary>
/// 添加一个包进入需要列表
/// </summary>
/// <param name="packageName"></param>
public static void AddNeedfulPackage(string packageName)
{
_defaultPackage.Add(packageName);
}
/// <summary>
/// 移除一个需要的资源包
/// </summary>
/// <param name="packageName"></param>
public static void RemoveNeedfulPackage(string packageName)
{
if (_defaultPackage.Contains(packageName)) _defaultPackage.Remove(packageName);
}
/// <summary>
/// 移除全部额外需要包
/// </summary>
public static void RemoveAllNeedful()
{
_defaultPackage.Clear();
}
/// <summary>
/// 是否需要这个资源包
/// </summary>
/// <param name="packageName"></param>
/// <returns></returns>
public static bool IsNeedfulPackage(string packageName)
{
var ret = _defaultPackage.Contains(packageName);
if (!ret)
{
var package = Addressable.GetPackageData(packageName);
if (package != null)
{
return package.Def == 1;
}
}
return ret;
}
#endregion
#region
#if DEBUG
private static DebugRemoteServer _debugRemoteServer;
public static void StartDebugRemoteServer()
{
_debugRemoteServer = _monoGameObject.AddComponent<DebugRemoteServer>();
}
public static void StopDebugRemoteServer()
{
if (_debugRemoteServer != null)
{
Object.DestroyImmediate(_debugRemoteServer);
}
}
public static DebugInfo GetDebugInfos()
{
DebugInfo info = new DebugInfo();
info.Frame = Time.frameCount;
var assetProviders = AssetProvider.GetAssetProviders();
foreach (var asset in assetProviders)
{
var i = CreateDebugAssetInfo(asset.AssetInfo, asset.IsAll);
SetDebugBaseInfo(asset, i);
info.AssetInfos.Add(i);
}
var sceneProviders = SceneProvider.GetSceneProviders();
foreach (var scene in sceneProviders)
{
var i = CreateDebugAssetInfo(scene.AssetInfo, false);
SetDebugBaseInfo(scene, i);
info.AssetInfos.Add(i);
}
var bundleProviders = BundledProvider.GetBundleProviders();
foreach (var bundle in bundleProviders)
{
var bundleInfo = new DebugBundleInfo
{
BundleName = bundle.BundleInfo.Bundle.Name
};
SetDebugBaseInfo(bundle, bundleInfo);
info.BundleInfos.Add(bundleInfo);
}
return info;
}
private static DebugAssetInfo CreateDebugAssetInfo(AssetInfo asset, bool isAll)
{
var assetInfo = new DebugAssetInfo
{
Path = asset.Path,
Type = asset.AssetType.Name,
IsAll = isAll,
};
var bundleInfos = Addressable.GetAllDependBundleInfos(asset);
foreach (var bundle in bundleInfos)
{
assetInfo.Dependency.Add(bundle.Bundle.Name);
}
return assetInfo;
}
private static void SetDebugBaseInfo(ProviderBase provider, DebugBaseInfo info)
{
info.LoadScene = provider.LoadScene;
info.Ref = provider.RefCount;
info.Status = provider.Status.ToString();
info.LoadTime = provider.LoadTime;
info.LoadTotalTime = provider.LoadTotalTime;
}
#endif
#endregion
#region Private
private static void Update()
{
TaskRunner.Update();
Recycler.Update();
}
private static InitializationTask InitConfirm()
{
_monoGameObject = new GameObject("Assets", typeof(Mono));
Mono.AddUpdate(Update);
InitializationTask task;
#if UNITY_STANDALONE_WIN
Const.NotCache = true;
#endif
if (Const.Simulate)
{
task = new EditorInitializationTask();
AssetProvider.CreateLoader = AssetLoadFromDatabase.CreateInstance;
SceneProvider.CreateLoader = SceneLoadFromDatabase.CreateInstance;
}
else if (Const.Offline)
{
task = new OfflineInitializationTask();
}
else
{
task = new OnlineInitializationTask();
}
if (Const.IsWebGLPlatform)
{
Const.RemoteUrl = $"{Application.streamingAssetsPath}/";
}
task.OnCompleted(InitDone);
task.Run(TaskRunner.Def);
_isInitialize = true;
return task;
}
/// <summary>
/// 初始化完成回调
/// </summary>
/// <param name="taskBase"></param>
private static void InitDone(ITask taskBase)
{
Debug.Log("初始化完成===");
_initializeTaskStatus = taskBase.Status;
_initializeError = taskBase.ErrorMsg;
}
#endregion
}
}