2024-08-23 15:49:34 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using AssetManagement;
|
|
|
|
|
using AssetUpdate;
|
|
|
|
|
using GCGame.Table;
|
|
|
|
|
using Module.Log;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using Object = UnityEngine.Object;
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public class LoadAssetBundle : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
#region Load Asset - 加载资源包的主体
|
|
|
|
|
|
|
|
|
|
public const string atlasPathConvertTable = "AtlasPathConvert";
|
|
|
|
|
|
|
|
|
|
public const string BUNDLE_MAIN_BASE_UI = "MainBase";
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public const string BUNDLE_PATH_MODEL = "model/";
|
|
|
|
|
public const string BUNDLE_PATH_PET = "model/";
|
|
|
|
|
public const string BUNDLE_PATH_EFFECT = "effect/";
|
|
|
|
|
public const string BUNDLE_PATH_UI = "ui/";
|
|
|
|
|
public const string BUNDLE_PATH_SOUND = "sounds/";
|
|
|
|
|
public const string BUNDLE_PATH_SPRITE = "ui/sprite/commonitem";
|
|
|
|
|
public const string BUNDLE_PATH_Other = "other/";
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public const string bundleFileExtension = AssetConst.bundleVariant;
|
|
|
|
|
|
|
|
|
|
public const string BUNDLE_PATH_GAMERES = "gameres";
|
|
|
|
|
|
|
|
|
|
// 无用的Bundle,仅仅用于打包时,让Unity可以正常收集Shader之类的资源引用
|
|
|
|
|
public const string BUNDLE_PATH_DUMMY = "dummy";
|
|
|
|
|
|
|
|
|
|
// CommonItem的Bundle名称 - 原位于Editor程序集ClassifyBundles
|
|
|
|
|
public const string uiCommonSpriteBundle = uiSpriteBundleHeader + "commonitem";
|
|
|
|
|
|
|
|
|
|
// Sprite类Bundle名称头 - 原位于Editor程序集ClassifyBundles
|
|
|
|
|
public const string uiSpriteBundleHeader = "ui/sprite/";
|
|
|
|
|
|
|
|
|
|
private readonly LoadAssetRequestList<GameObject> _gameObjectList = new LoadAssetRequestList<GameObject>();
|
2024-09-23 22:56:51 +08:00
|
|
|
|
private readonly LoadAssetRequestList<Object> _assetList = new LoadAssetRequestList<Object>();
|
|
|
|
|
private readonly LoadAssetRequestList<AudioClip> _audioList = new LoadAssetRequestList<AudioClip>();
|
|
|
|
|
private readonly LoadAssetRequestList<TextAsset> _textAssetList = new LoadAssetRequestList<TextAsset>();
|
2024-08-23 15:49:34 +08:00
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
private readonly LoadSpriteRequestList _spriteList = new LoadSpriteRequestList();
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private readonly LoadRawImageRequestList _rawImageList = new LoadRawImageRequestList();
|
|
|
|
|
|
|
|
|
|
public AssetPathHub pathHub { get; private set; }
|
|
|
|
|
|
|
|
|
|
// Use this for initialization
|
|
|
|
|
private void Awake()
|
|
|
|
|
{
|
|
|
|
|
Instance = this;
|
|
|
|
|
if (!AssetUpdateManager.useResources)
|
|
|
|
|
{
|
|
|
|
|
// 暂时不考虑动态切换资源路径的流程,需要再处理类型情况
|
|
|
|
|
pathHub = new AssetPathHub();
|
|
|
|
|
// 加载全部资源资料
|
|
|
|
|
string uri;
|
|
|
|
|
if (string.IsNullOrEmpty(AssetUpdateManager.assetUri))
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("Cannot find assetInfo. You should start the game from AssetUpdate instead of Login!");
|
|
|
|
|
// 这个问题无法正确恢复,仅仅测试版本可以继续使用本地资源
|
|
|
|
|
uri = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
uri = AssetUpdateManager.assetUri;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dependencyPath =
|
2024-09-23 22:56:51 +08:00
|
|
|
|
AssetConst.persistentDataPath.Open(AssetUtils.GetTextMd5(AssetConst.versionFile) +
|
|
|
|
|
AssetConst.bundleVariant);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
AssetDependencyInfo dependencyInfo = null;
|
|
|
|
|
if (!File.Exists(dependencyPath))
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError(
|
2024-09-23 22:56:51 +08:00
|
|
|
|
"Cannot find dependency file. You should start the game from AssetUpdate instead of Login!");
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
dependencyInfo = AssetDependencyInfo.Create(dependencyPath);
|
2024-09-23 22:56:51 +08:00
|
|
|
|
Debug.Log("LoaderAssetsBundle");
|
2024-08-23 15:49:34 +08:00
|
|
|
|
if (dependencyInfo == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError("Unable to load dependency file! This is not recoverable!");
|
|
|
|
|
LiteConfirmWin.Open("资源错误", "无法加载资源依赖!\n需要重启游戏修复!",
|
2024-09-23 22:56:51 +08:00
|
|
|
|
new LiteConfirmButtonData("确定", () => SdkControl.instance.CloseGame()));
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pathHub.Init(uri, dependencyInfo);
|
|
|
|
|
var loadHub = new BundleLoadHub();
|
|
|
|
|
// 暂时限制到同时5个并行加载
|
|
|
|
|
loadHub.Init(pathHub, new List<AsyncLoadRule>
|
|
|
|
|
{
|
|
|
|
|
new AsyncLoadRule(int.MaxValue, 5)
|
|
|
|
|
});
|
|
|
|
|
var downloadHub = new BundleDownloadHub();
|
|
|
|
|
// 后台下载限制到最大一个;主动加载限制到最大三个;
|
|
|
|
|
downloadHub.Init(pathHub, new List<AsyncLoadRule>
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
new AsyncLoadRule(0, 1),
|
2024-08-23 15:49:34 +08:00
|
|
|
|
new AsyncLoadRule(int.MaxValue, 3)
|
|
|
|
|
});
|
|
|
|
|
downloadHub.onComplete += pathHub.DownloadComplete;
|
|
|
|
|
// 注:BundleManager需要在PathHub绑定后执行初始化,否则无法正确更新PathData
|
|
|
|
|
var bundleManager = new BundleManager(pathHub, loadHub, downloadHub);
|
|
|
|
|
if (AssetManager.instance == null)
|
|
|
|
|
AssetManager.CreateInstance();
|
|
|
|
|
var assetManager = AssetManager.instance;
|
|
|
|
|
// ReSharper disable once PossibleNullReferenceException
|
|
|
|
|
assetManager.Init(bundleManager);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
DontDestroyOnLoad(gameObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void StartBackGround()
|
|
|
|
|
{
|
|
|
|
|
if (!AssetUpdateManager.useResources)
|
|
|
|
|
AssetManager.instance.bundleManager.downloadHub.StartBackGroundDownload();
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public static void CreateInstance()
|
|
|
|
|
{
|
|
|
|
|
var loadObject = new GameObject("LoadAssetBundle");
|
|
|
|
|
loadObject.AddComponent<LoadAssetBundle>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearCallbacks()
|
|
|
|
|
{
|
|
|
|
|
_gameObjectList.Clear();
|
|
|
|
|
_assetList.Clear();
|
|
|
|
|
_audioList.Clear();
|
|
|
|
|
_textAssetList.Clear();
|
|
|
|
|
_spriteList.Clear();
|
|
|
|
|
_rawImageList.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsBundleAndAssetValid(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
return !string.IsNullOrEmpty(bundleName) &&
|
2024-09-23 22:56:51 +08:00
|
|
|
|
!string.IsNullOrEmpty(assetName) &&
|
|
|
|
|
!bundleName.Equals("-1") &&
|
2024-08-23 15:49:34 +08:00
|
|
|
|
!assetName.Equals("-1");
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
private void LoadAssetFromList<T>(string bundleName, string assetName, LoadBundleAssetCallback<T> callback,
|
|
|
|
|
Hashtable hashtable, LoadAssetRequestList<T> list, bool archive) where T : Object
|
2024-08-23 15:49:34 +08:00
|
|
|
|
{
|
|
|
|
|
// 已知问题,即使已经加载的资源,仍然会产生一次列表推入和回调监听,造成少量性能浪费
|
|
|
|
|
// 暂时不修改这个结构,保持当前强健的逻辑流程
|
|
|
|
|
list.AddCallback(bundleName, assetName, callback, hashtable);
|
|
|
|
|
LoadAssetInternal<T>(bundleName, assetName);
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private void RemoveAllCallback(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
_gameObjectList.RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
_assetList.RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
_audioList.RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
_textAssetList.RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
_spriteList.RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
_rawImageList.RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public void LoadGameObject(string bundleName, string assetName, LoadBundleAssetCallback<GameObject> callback,
|
|
|
|
|
Hashtable hashParam, bool archive = false)
|
2024-08-23 15:49:34 +08:00
|
|
|
|
{
|
|
|
|
|
if (IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName += assetName;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
bundleName = FixBundleName(bundleName);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
LoadAssetFromList(bundleName, assetName, callback, hashParam, _gameObjectList, archive);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public void LoadAsset(string bundleName, string assetName, LoadBundleAssetCallback<Object> callback,
|
|
|
|
|
Hashtable hashParam, bool archive = false)
|
2024-08-23 15:49:34 +08:00
|
|
|
|
{
|
|
|
|
|
if (IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
LoadAssetFromList(bundleName, assetName, callback, hashParam, _assetList, archive);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveAssetCallback(string bundleName, string assetName, LoadBundleAssetCallback<Object> callback)
|
|
|
|
|
{
|
|
|
|
|
if (IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
_assetList.RemoveCallback(bundleName, assetName, callback);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// GameObject加载需求的析构接口,因为会修改AssetBundle名称,使用一个统一接口
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void UnloadAssetWithPathFix(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
if (!AssetUpdateManager.useResources && IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName = bundleName + assetName;
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
AssetManager.instance.RemoveAsset(bundleName, assetName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// GameObject加载需求的析构接口,不会修改bundleName,因此不要给会用资源名校正包名资源的使用
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void UnloadAsset(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
if (!AssetUpdateManager.useResources && IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
RemoveAllCallback(bundleName, assetName);
|
|
|
|
|
AssetManager.instance.RemoveAsset(bundleName, assetName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public void LoadUI(string bundleName, string assetName, LoadBundleAssetCallback<GameObject> callback,
|
|
|
|
|
Hashtable hashParam, bool archive = true)
|
2024-08-23 15:49:34 +08:00
|
|
|
|
{
|
|
|
|
|
if (IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
LoadAssetFromList(bundleName, assetName, callback, hashParam, _gameObjectList, archive);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public void LoadSoundAsync(string bundlePath, string assetName, LoadBundleAssetCallback<AudioClip> callback,
|
|
|
|
|
Hashtable hashParam)
|
2024-08-23 15:49:34 +08:00
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(assetName))
|
|
|
|
|
if (IsBundleAndAssetValid(bundlePath, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundlePath = FixBundleName(bundlePath);
|
|
|
|
|
LoadAssetFromList(bundlePath, assetName, callback, hashParam, _audioList, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetRawTexture(RawImage image, string assetName, string bundleName)
|
|
|
|
|
{
|
|
|
|
|
var valid = false;
|
|
|
|
|
if (image != null)
|
|
|
|
|
{
|
|
|
|
|
if (image.texture == null)
|
|
|
|
|
{
|
|
|
|
|
image.enabled = false;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
valid = true;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
valid = !image.texture.name.Equals(assetName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (valid && IsBundleAndAssetValid(bundleName, assetName))
|
|
|
|
|
{
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
_rawImageList.AddCallback(bundleName, assetName, image);
|
|
|
|
|
LoadAssetInternal<Texture>(bundleName, assetName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetImageSprite(Image image, string assetName, LoadSpritesCallback callback = null)
|
|
|
|
|
{
|
|
|
|
|
var valid = false;
|
|
|
|
|
if (image != null)
|
|
|
|
|
{
|
|
|
|
|
if (image.sprite == null)
|
|
|
|
|
{
|
|
|
|
|
image.enabled = false;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
valid = true;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
valid = !image.sprite.name.Equals(assetName);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
if (valid && IsBundleAndAssetValid(BUNDLE_PATH_SPRITE, assetName))
|
|
|
|
|
{
|
|
|
|
|
// 试图校正精灵包名
|
|
|
|
|
var bundleName = GetAtlasBundleName(BUNDLE_PATH_SPRITE, assetName);
|
|
|
|
|
_spriteList.AddCallback(bundleName, assetName, image, callback);
|
|
|
|
|
LoadAssetInternal<Sprite>(bundleName, assetName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 统一使用一个接口来处理修复Bundle名称之类的问题
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void LoadAssetInternal<T>(string bundleName, string assetName) where T : Object
|
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
if (AssetUpdateManager.useResources)
|
|
|
|
|
LoadForSimulateMode(bundleName, assetName, typeof(T));
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
AssetManager.instance.LoadAsset<T>(bundleName, assetName, this, OnAssetLoadedFinish);
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private void OnAssetLoadedFinish<T>(string bundleName, string assetName, T asset) where T : Object
|
|
|
|
|
{
|
|
|
|
|
_gameObjectList.FinishAsset(bundleName, assetName, asset);
|
|
|
|
|
_assetList.FinishAsset(bundleName, assetName, asset);
|
|
|
|
|
_audioList.FinishAsset(bundleName, assetName, asset);
|
|
|
|
|
_textAssetList.FinishAsset(bundleName, assetName, asset);
|
|
|
|
|
_spriteList.FinishAsset(bundleName, assetName, asset);
|
|
|
|
|
_rawImageList.FinishAsset(bundleName, assetName, asset);
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
[Serializable]
|
|
|
|
|
public class EditorBundleList
|
|
|
|
|
{
|
|
|
|
|
private readonly Dictionary<string, string> _assetDataList = new Dictionary<string, string>();
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public EditorBundleList(IEnumerable<string> assets)
|
|
|
|
|
{
|
|
|
|
|
foreach (var asset in assets)
|
|
|
|
|
{
|
|
|
|
|
_assetDataList[Path.GetFileName(asset).ToLower()] = asset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string GetAssetPath(string assetName)
|
|
|
|
|
{
|
|
|
|
|
string result;
|
|
|
|
|
if (!_assetDataList.TryGetValue(assetName, out result))
|
|
|
|
|
result = string.Empty;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class EditorResourceAsync
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public readonly string bundleName;
|
|
|
|
|
public readonly string assetName;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public readonly AsyncOperation operation;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public EditorResourceAsync(string bundleName, string assetName, AsyncOperation operation)
|
|
|
|
|
{
|
|
|
|
|
this.bundleName = bundleName;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
this.assetName = assetName;
|
|
|
|
|
this.operation = operation;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public const string assetPathHeader = "Assets/Project3D/Resources";
|
|
|
|
|
public const string uiSpriteAssetPath = "Assets/Project3D/Sprites";
|
|
|
|
|
public const string bundleToAssetPath = "Assets/Editor/Config/BundleToAsset" + AssetConst.bytesExtension;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
private Dictionary<string, string> _uiCommonPathDict;
|
|
|
|
|
private Dictionary<string, EditorBundleList> _resourcesDict;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
private const int _maxAsyncCount = 1;
|
|
|
|
|
private readonly List<EditorResourceAsync> _asyncList = new List<EditorResourceAsync>();
|
|
|
|
|
private readonly Queue<MyTuple<string, string>> _pendingList = new Queue<MyTuple<string, string>>();
|
2024-08-23 15:49:34 +08:00
|
|
|
|
|
|
|
|
|
private void OnResourcesLoad(AsyncOperation operation)
|
|
|
|
|
{
|
|
|
|
|
var resourceRequest = operation as ResourceRequest;
|
|
|
|
|
if (resourceRequest != null)
|
|
|
|
|
{
|
|
|
|
|
for (var i = _asyncList.Count - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
var async = _asyncList[i];
|
|
|
|
|
if (async.operation == operation)
|
|
|
|
|
{
|
|
|
|
|
_asyncList.RemoveAt(i);
|
|
|
|
|
OnAssetLoadedFinish(async.bundleName, async.assetName, resourceRequest.asset);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
while (_asyncList.Count < _maxAsyncCount && _pendingList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var task = _pendingList.Dequeue();
|
|
|
|
|
StartResourceLoad(task.first, task.second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StartResourceLoad(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
if (_resourcesDict == null)
|
|
|
|
|
{
|
|
|
|
|
var dataPath = Application.dataPath.MoveUp().Open(bundleToAssetPath);
|
|
|
|
|
if (File.Exists(dataPath))
|
|
|
|
|
{
|
|
|
|
|
var bitFormatter = new BinaryFormatter();
|
|
|
|
|
using (var fs = File.OpenRead(dataPath))
|
|
|
|
|
_resourcesDict = bitFormatter.Deserialize(fs) as Dictionary<string, EditorBundleList>;
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
if (_resourcesDict == null)
|
|
|
|
|
_resourcesDict = new Dictionary<string, EditorBundleList>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorBundleList list;
|
|
|
|
|
if (!_resourcesDict.TryGetValue(bundleName, out list))
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
var assets = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName + AssetConst.bundleVariant)
|
|
|
|
|
.Where(a => a.StartsWith(assetPathHeader))
|
|
|
|
|
.Select(a => a.RemoveExtension().Substring(assetPathHeader.Length + 1)).ToArray();
|
2024-08-23 15:49:34 +08:00
|
|
|
|
if (assets.Length > 0)
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
list = new EditorBundleList(assets);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
_resourcesDict[bundleName] = list;
|
|
|
|
|
var bitFormatter = new BinaryFormatter();
|
2024-09-23 22:56:51 +08:00
|
|
|
|
var dataPath = Application.dataPath.MoveUp().Open(bundleToAssetPath);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
using (var fs = File.OpenWrite(dataPath))
|
|
|
|
|
bitFormatter.Serialize(fs, _resourcesDict);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
var path = list != null
|
|
|
|
|
? list.GetAssetPath(assetName.ToLower())
|
|
|
|
|
: string.Empty;
|
|
|
|
|
if (string.IsNullOrEmpty(path))
|
|
|
|
|
{
|
|
|
|
|
Debug.LogError(string.Format("Unable to load asset {0} from bundle {1}!", assetName, bundleName));
|
|
|
|
|
// ReSharper disable once ExpressionIsAlwaysNull
|
|
|
|
|
OnAssetLoadedFinish(bundleName, assetName, default(Object));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var request = Resources.LoadAsync(path);
|
|
|
|
|
_asyncList.Add(new EditorResourceAsync(bundleName, assetName, request));
|
|
|
|
|
request.completed += OnResourcesLoad;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private void LoadForSimulateMode(string bundleName, string assetName, Type assetType)
|
|
|
|
|
{
|
|
|
|
|
Object asset = null;
|
|
|
|
|
// 2019.03.01 不再试图维护Simulate的流程;uiCommonSprite直接走内置流程。
|
|
|
|
|
if (bundleName.StartsWith("ui/sprite/"))
|
|
|
|
|
{
|
|
|
|
|
if (_uiCommonPathDict == null)
|
|
|
|
|
{
|
|
|
|
|
_uiCommonPathDict = new Dictionary<string, string>();
|
|
|
|
|
var uiCommonPaths = from assetPath in AssetDatabase.GetAllAssetPaths()
|
|
|
|
|
where assetPath.StartsWith(uiSpriteAssetPath)
|
|
|
|
|
where !string.IsNullOrEmpty(Path.GetExtension(assetPath))
|
|
|
|
|
select assetPath;
|
|
|
|
|
foreach (var uiPath in uiCommonPaths)
|
|
|
|
|
{
|
|
|
|
|
var key = Path.GetFileNameWithoutExtension(uiPath).ToLower();
|
|
|
|
|
if (_uiCommonPathDict.ContainsKey(key))
|
|
|
|
|
Debug.LogError("Duplicate Key Found for " + uiPath + " and " + _uiCommonPathDict[key]);
|
|
|
|
|
else
|
|
|
|
|
_uiCommonPathDict.Add(key, uiPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string path;
|
|
|
|
|
if (_uiCommonPathDict.TryGetValue(assetName.ToLower(), out path))
|
|
|
|
|
asset = AssetDatabase.LoadAssetAtPath(path, assetType);
|
|
|
|
|
else
|
|
|
|
|
Debug.LogError("No Path for item " + assetName.ToLower());
|
|
|
|
|
OnAssetLoadedFinish(bundleName, assetName, asset);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var callBack = _asyncList.Find(a => a.bundleName == bundleName && a.assetName == assetName);
|
|
|
|
|
if (callBack == null)
|
|
|
|
|
{
|
|
|
|
|
if (_asyncList.Count < _maxAsyncCount)
|
|
|
|
|
StartResourceLoad(bundleName, assetName);
|
|
|
|
|
else
|
|
|
|
|
_pendingList.Enqueue(new MyTuple<string, string>(bundleName, assetName));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region load init
|
|
|
|
|
|
|
|
|
|
public static LoadAssetBundle Instance { get; private set; }
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
// public void UnloadBundle(string bundleName)
|
|
|
|
|
// {
|
|
|
|
|
// Debug.Log("Unload Bundle: " + bundleName);
|
|
|
|
|
// if (!AssetUpdateManager.useResources)
|
|
|
|
|
// {
|
|
|
|
|
// bundleName = FixBundleName(bundleName);
|
|
|
|
|
// AssetManager.instance.RemovePreload(bundleName);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 统一处理一些AssetBundle后缀名称问题
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static string FixBundleName(string bundleName)
|
|
|
|
|
{
|
|
|
|
|
// var extension = Path.GetExtension();
|
|
|
|
|
// if (string.IsNullOrEmpty(extension))
|
|
|
|
|
// {
|
|
|
|
|
// bundleName += bundleFileExtension;
|
|
|
|
|
// }
|
|
|
|
|
// else if (!extension.Equals(bundleFileExtension, StringComparison.CurrentCultureIgnoreCase))
|
|
|
|
|
// {
|
|
|
|
|
// bundleName = bundleName.Remove(bundleName.Length - extension.Length);
|
|
|
|
|
// bundleName += bundleFileExtension;
|
|
|
|
|
// }
|
|
|
|
|
return bundleName.RemoveExtension().ToLower();
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
// /// <summary>
|
|
|
|
|
// /// 加载一个AssetBundle,如果Bundle已经加载就返回true
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// private void LoadOneAssetBundle(string bundleName)
|
|
|
|
|
// {
|
|
|
|
|
// bundleName = FixBundleName(bundleName);
|
|
|
|
|
// AssetManager.instance.Preload(bundleName, this, OnAssetBundleLoaded);
|
|
|
|
|
// }
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 预加载过场动画
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 预加载场景电影Bundle
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly List<int> _movieId = new List<int>();
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private string _preloadScene;
|
|
|
|
|
|
|
|
|
|
private static string GetMovieName(int movieId)
|
|
|
|
|
{
|
|
|
|
|
var movieName = string.Empty;
|
|
|
|
|
if (movieId >= 0)
|
|
|
|
|
{
|
|
|
|
|
var movieData = TableManager.GetSceneMovieByID(movieId);
|
|
|
|
|
if (movieData != null)
|
|
|
|
|
{
|
|
|
|
|
var profession = GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Profession;
|
|
|
|
|
movieName = movieData.GetResPathbyIndex(profession);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
return movieName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddMoviePreload(int movieId)
|
|
|
|
|
{
|
|
|
|
|
var movieName = GetMovieName(movieId);
|
|
|
|
|
if (!string.IsNullOrEmpty(movieName))
|
|
|
|
|
Instance.LoadGameObject(BUNDLE_PATH_MODEL, movieName, null, null);
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private void RemoveMoviePreload(int movieId)
|
|
|
|
|
{
|
|
|
|
|
var movieName = GetMovieName(movieId);
|
|
|
|
|
if (!string.IsNullOrEmpty(movieName))
|
|
|
|
|
{
|
|
|
|
|
var bundleName = BUNDLE_PATH_MODEL + movieName;
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
Instance.UnloadAsset(bundleName, movieName);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public void StartPreloadScene(string sceneName, int movieId)
|
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
if (AssetUpdateManager.useResources)
|
|
|
|
|
return;
|
|
|
|
|
#endif
|
|
|
|
|
sceneName = GetSceneBundleName(sceneName);
|
|
|
|
|
// 如果场景对不上,则卸载之前的场景预加载
|
|
|
|
|
var loadScene = _preloadScene != sceneName;
|
|
|
|
|
if (loadScene)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(_preloadScene))
|
|
|
|
|
CleanPreloadScene();
|
|
|
|
|
_preloadScene = sceneName;
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
if (!_movieId.Contains(movieId))
|
|
|
|
|
AddMoviePreload(movieId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CleanPreloadScene()
|
|
|
|
|
{
|
|
|
|
|
_preloadScene = string.Empty;
|
|
|
|
|
foreach (var id in _movieId)
|
|
|
|
|
RemoveMoviePreload(id);
|
|
|
|
|
_movieId.Clear();
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#endregion
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#region loadScene
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否允许加载场景
|
|
|
|
|
/// </summary>
|
|
|
|
|
// 注:如果当前有其他SceneLoadOperaction,则不允许继续加载场景
|
|
|
|
|
public bool AllowLoadScene()
|
|
|
|
|
{
|
|
|
|
|
return !AssetManager.instance.IsLoadingScene();
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public static string GetSceneBundleName(string sceneName)
|
|
|
|
|
{
|
|
|
|
|
var bundleName = "scene/" + sceneName;
|
|
|
|
|
bundleName = FixBundleName(bundleName);
|
|
|
|
|
return bundleName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UnloadMainScene()
|
|
|
|
|
{
|
|
|
|
|
if (!AssetUpdateManager.useResources)
|
|
|
|
|
AssetManager.instance.UnloadAllScene();
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 加载主要场景 - 主要场景加载时,会卸载之前的主要场景
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool LoadMainScene(string assetName, LoadSceneMode mode, out SceneHandle loadHandle)
|
|
|
|
|
{
|
|
|
|
|
bool load;
|
|
|
|
|
if (AssetUpdateManager.useResources)
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
load = true;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
loadHandle = null;
|
|
|
|
|
SceneManager.LoadScene(assetName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var bundleName = GetSceneBundleName(assetName);
|
2024-09-23 22:56:51 +08:00
|
|
|
|
var current = AssetManager.instance.GetCurrentSceneHandle();
|
2024-08-23 15:49:34 +08:00
|
|
|
|
load = current == null || current.sceneName == assetName;
|
|
|
|
|
if (!load)
|
|
|
|
|
load = AllowLoadScene();
|
|
|
|
|
loadHandle = load ? AssetManager.instance.LoadScene(bundleName, assetName, mode, allowReload: true) : null;
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
return load;
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region loadGameRes
|
|
|
|
|
|
|
|
|
|
public static string gameResBundleName
|
|
|
|
|
{
|
|
|
|
|
get { return FixBundleName(BUNDLE_PATH_GAMERES); }
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region LoadTable
|
|
|
|
|
|
|
|
|
|
private const string _tableBundleName = "tables";
|
|
|
|
|
|
|
|
|
|
public TextAsset LoadTableAsset(string tableName)
|
|
|
|
|
{
|
|
|
|
|
return LoadTextAsset(_tableBundleName, tableName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public const string tablePath = "Assets/Project3D/BundleData/Tables3D/";
|
|
|
|
|
private Dictionary<string, string> _luaFiles;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#endif
|
|
|
|
|
private TextAsset LoadTextAsset(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
TextAsset result = null;
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
if (AssetUpdateManager.useResources)
|
|
|
|
|
{
|
|
|
|
|
if (bundleName == _scriptBundleName)
|
|
|
|
|
{
|
|
|
|
|
if (_luaFiles == null)
|
|
|
|
|
{
|
|
|
|
|
_luaFiles = new Dictionary<string, string>();
|
|
|
|
|
var luaPath = "Assets".Open("Project").Open("Script").Open("LuaScripts") + '/';
|
|
|
|
|
var scripts = AssetDatabase.GetAllAssetPaths().Where(a => a.StartsWith(luaPath))
|
2024-09-23 22:56:51 +08:00
|
|
|
|
.Where(a => AssetConst.textExtension.Equals(Path.GetExtension(a)));
|
2024-08-23 15:49:34 +08:00
|
|
|
|
foreach (var script in scripts)
|
|
|
|
|
_luaFiles.Add(Path.GetFileNameWithoutExtension(script).ToLower(), script);
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
string path;
|
|
|
|
|
if (_luaFiles.TryGetValue(assetName.ToLower(), out path))
|
|
|
|
|
result = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
|
|
|
|
}
|
|
|
|
|
else if (bundleName == _tableBundleName)
|
|
|
|
|
{
|
|
|
|
|
var extension = string.Equals(assetName, atlasPathConvertTable, StringComparison.Ordinal)
|
|
|
|
|
? AssetConst.bytesExtension
|
|
|
|
|
: AssetConst.textExtension;
|
|
|
|
|
result = AssetDatabase.LoadAssetAtPath<TextAsset>(tablePath + assetName + extension);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Debug.LogError(string.Format("Unable to load TextAsset {1} from bundle {0}!", bundleName, assetName));
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2024-09-23 22:56:51 +08:00
|
|
|
|
if (AssetManager.instance == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("AssetManager is not initialized!");
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
result = AssetManager.instance.LoadAssetSync<TextAsset>(bundleName, assetName);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#region LoadScript
|
|
|
|
|
|
|
|
|
|
// 注:之前逻辑是和LoadTable在一起,但是没有监听过这个AssetBundle是否加载结束的
|
|
|
|
|
// 暂时保持接口和调用处不变
|
|
|
|
|
private const string _scriptBundleName = "script";
|
|
|
|
|
|
|
|
|
|
public TextAsset LoadScriptAsset(string script)
|
|
|
|
|
{
|
|
|
|
|
return LoadTextAsset(_scriptBundleName, script);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#region Atlas Path Convert
|
|
|
|
|
|
|
|
|
|
private Dictionary<string, string> _pathConvertDict;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
private void CreateAtlasConvert()
|
|
|
|
|
{
|
|
|
|
|
_pathConvertDict = new Dictionary<string, string>();
|
|
|
|
|
var lines = AssetUtils.TextToLines(LoadTableAsset(atlasPathConvertTable).text);
|
|
|
|
|
foreach (var line in lines)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(line))
|
|
|
|
|
{
|
|
|
|
|
var keyValue = line.Split('\t');
|
|
|
|
|
_pathConvertDict[keyValue[0]] = keyValue[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetAtlasBundleName(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
if (_pathConvertDict == null)
|
|
|
|
|
CreateAtlasConvert();
|
|
|
|
|
string newName;
|
|
|
|
|
if (_pathConvertDict.TryGetValue(assetName.ToLower(), out newName))
|
|
|
|
|
bundleName = newName;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogModule.ErrorLog(string.Format(
|
2024-09-23 22:56:51 +08:00
|
|
|
|
"Try to load asset {0} from {1}, while Asset Load Manager hasn't init path conversion yet!",
|
|
|
|
|
assetName, bundleName));
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
return bundleName;
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region Load Asset Data
|
|
|
|
|
|
|
|
|
|
public delegate void LoadSpritesCallback(bool isSucess, GameObject obj);
|
|
|
|
|
|
|
|
|
|
public delegate void LoadBundleAssetCallback<in T>(string assetName, T assetItem, Hashtable hashTable) where T : Object;
|
|
|
|
|
|
|
|
|
|
public delegate void LoadAssetBundleFinish(string bundleName);
|
|
|
|
|
|
|
|
|
|
public abstract class LoadAssetRequestBase
|
|
|
|
|
{
|
|
|
|
|
public readonly string assetName;
|
|
|
|
|
public readonly string bundleName;
|
|
|
|
|
|
|
|
|
|
protected LoadAssetRequestBase(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
this.bundleName = bundleName;
|
2024-09-23 22:56:51 +08:00
|
|
|
|
this.assetName = assetName;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class LoadAssetRequestMethods
|
|
|
|
|
{
|
|
|
|
|
public static int GetIndexFromList<T>(this List<T> requestList, string bundleName, string assetName)
|
|
|
|
|
where T : LoadAssetRequestBase
|
|
|
|
|
{
|
|
|
|
|
var result = -1;
|
|
|
|
|
for (var i = 0; i < requestList.Count; i++)
|
|
|
|
|
if (requestList[i].bundleName.Equals(bundleName, StringComparison.OrdinalIgnoreCase) &&
|
|
|
|
|
requestList[i].assetName.Equals(assetName, StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
result = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LoadRawImageRequest : LoadAssetRequestBase
|
|
|
|
|
{
|
|
|
|
|
public readonly List<RawImage> rawImageList = new List<RawImage>();
|
|
|
|
|
|
|
|
|
|
public LoadRawImageRequest(string bundleName, string assetName) : base(bundleName, assetName)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddCallback(RawImage rawImage)
|
|
|
|
|
{
|
|
|
|
|
if (!rawImageList.Contains(rawImage))
|
|
|
|
|
rawImageList.Add(rawImage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(RawImage rawImage)
|
|
|
|
|
{
|
|
|
|
|
rawImageList.Remove(rawImage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAsset(Object asset)
|
|
|
|
|
{
|
|
|
|
|
var texture = asset as Texture;
|
|
|
|
|
for (var i = 0; i < rawImageList.Count; i++)
|
|
|
|
|
if (rawImageList[i])
|
|
|
|
|
{
|
|
|
|
|
rawImageList[i].texture = texture;
|
|
|
|
|
rawImageList[i].enabled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LoadSpriteRequest : LoadAssetRequestBase
|
|
|
|
|
{
|
|
|
|
|
public readonly List<MyTuple<Image, LoadSpritesCallback>> callBackList =
|
|
|
|
|
new List<MyTuple<Image, LoadSpritesCallback>>();
|
|
|
|
|
|
|
|
|
|
public LoadSpriteRequest(string bundleName, string assetName) : base(bundleName, assetName)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddCallback(Image image, LoadSpritesCallback callback)
|
|
|
|
|
{
|
|
|
|
|
var index = GetCallBackIndex(image);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
callBackList[index].second = callback;
|
|
|
|
|
else
|
|
|
|
|
callBackList.Add(new MyTuple<Image, LoadSpritesCallback>(image, callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(Image image)
|
|
|
|
|
{
|
|
|
|
|
var index = GetCallBackIndex(image);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
callBackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetCallBackIndex(Image image)
|
|
|
|
|
{
|
|
|
|
|
var result = -1;
|
|
|
|
|
for (var i = 0; i < callBackList.Count; i++)
|
|
|
|
|
if (callBackList[i].first == image)
|
|
|
|
|
{
|
|
|
|
|
result = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAsset(Object asset)
|
|
|
|
|
{
|
|
|
|
|
var sprite = asset as Sprite;
|
|
|
|
|
for (var i = 0; i < callBackList.Count; i++)
|
|
|
|
|
if (callBackList[i].first)
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
callBackList[i].first.sprite = sprite;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
callBackList[i].first.enabled = true;
|
|
|
|
|
if (callBackList[i].second != null)
|
|
|
|
|
callBackList[i].second.Invoke(true, callBackList[i].first.gameObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LoadAssetRequest<T> : LoadAssetRequestBase where T : Object
|
|
|
|
|
{
|
|
|
|
|
public readonly List<MyTuple<LoadBundleAssetCallback<T>, Hashtable>> callBackList =
|
|
|
|
|
new List<MyTuple<LoadBundleAssetCallback<T>, Hashtable>>();
|
|
|
|
|
|
|
|
|
|
public LoadAssetRequest(string bundleName, string assetName) : base(bundleName, assetName)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddCallback(LoadBundleAssetCallback<T> callback, Hashtable hashTable)
|
|
|
|
|
{
|
|
|
|
|
var index = GetCallbackIndex(callback);
|
|
|
|
|
if (index < 0)
|
|
|
|
|
callBackList.Add(new MyTuple<LoadBundleAssetCallback<T>, Hashtable>(callback, hashTable));
|
|
|
|
|
else
|
|
|
|
|
callBackList[index].second = hashTable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(LoadBundleAssetCallback<T> callback)
|
|
|
|
|
{
|
|
|
|
|
var index = GetCallbackIndex(callback);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
callBackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetCallbackIndex(LoadBundleAssetCallback<T> callback)
|
|
|
|
|
{
|
|
|
|
|
var result = -1;
|
|
|
|
|
for (var i = 0; i < callBackList.Count; i++)
|
|
|
|
|
if (callBackList[i].first == callback)
|
|
|
|
|
{
|
|
|
|
|
result = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAsset(Object asset)
|
|
|
|
|
{
|
|
|
|
|
var item = asset as T;
|
|
|
|
|
for (var i = 0; i < callBackList.Count; i++)
|
|
|
|
|
if (callBackList[i].first != null)
|
|
|
|
|
callBackList[i].first.Invoke(assetName, item, callBackList[i].second);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LoadRawImageRequestList
|
|
|
|
|
{
|
|
|
|
|
private readonly List<LoadRawImageRequest> _callbackList = new List<LoadRawImageRequest>();
|
|
|
|
|
|
|
|
|
|
public void AddCallback(string bundleName, string assetName, RawImage rawImage)
|
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
LoadRawImageRequest request;
|
|
|
|
|
if (index < 0)
|
|
|
|
|
{
|
|
|
|
|
request = new LoadRawImageRequest(bundleName, assetName);
|
|
|
|
|
_callbackList.Add(request);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
request = _callbackList[index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
request.AddCallback(rawImage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(string bundleName, string assetName, RawImage rawImage)
|
|
|
|
|
{
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
_callbackList[index].RemoveCallback(rawImage);
|
|
|
|
|
if (_callbackList[index].rawImageList.Count <= 0)
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveAllCallback(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAsset(string bundleName, string assetName, Object asset)
|
|
|
|
|
{
|
|
|
|
|
// 这个接收底层回调的消息,不会出现名字错误的问题
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
var item = _callbackList[index];
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
item.FinishAsset(asset);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-23 22:56:51 +08:00
|
|
|
|
|
2024-08-23 15:49:34 +08:00
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
_callbackList.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LoadSpriteRequestList
|
|
|
|
|
{
|
|
|
|
|
private readonly List<LoadSpriteRequest> _callbackList = new List<LoadSpriteRequest>();
|
|
|
|
|
|
|
|
|
|
public void AddCallback(string bundleName, string assetName, Image image, LoadSpritesCallback callback)
|
|
|
|
|
{
|
|
|
|
|
bundleName = LoadAssetBundle.FixBundleName(bundleName);
|
2024-09-23 22:56:51 +08:00
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
LoadSpriteRequest request;
|
|
|
|
|
if (index < 0)
|
|
|
|
|
{
|
|
|
|
|
request = new LoadSpriteRequest(bundleName, assetName);
|
|
|
|
|
_callbackList.Add(request);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
request = _callbackList[index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
request.AddCallback(image, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(string bundleName, string assetName, Image image)
|
|
|
|
|
{
|
|
|
|
|
bundleName = LoadAssetBundle.FixBundleName(bundleName);
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
_callbackList[index].RemoveCallback(image);
|
|
|
|
|
if (_callbackList[index].callBackList.Count <= 0)
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveAllCallback(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
bundleName = LoadAssetBundle.FixBundleName(bundleName);
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAsset(string bundleName, string assetName, Object asset)
|
|
|
|
|
{
|
|
|
|
|
// 这个接收底层回调的消息,不会出现名字错误的问题
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
var item = _callbackList[index];
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
item.FinishAsset(asset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
_callbackList.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LoadAssetRequestList<T> where T : Object
|
|
|
|
|
{
|
|
|
|
|
private readonly List<LoadAssetRequest<T>> _callbackList = new List<LoadAssetRequest<T>>();
|
|
|
|
|
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public void AddCallback(string bundleName, string assetName, LoadBundleAssetCallback<T> callback,
|
|
|
|
|
Hashtable hashTable)
|
2024-08-23 15:49:34 +08:00
|
|
|
|
{
|
2024-09-23 22:56:51 +08:00
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
2024-08-23 15:49:34 +08:00
|
|
|
|
LoadAssetRequest<T> request;
|
|
|
|
|
if (index < 0)
|
|
|
|
|
{
|
|
|
|
|
request = new LoadAssetRequest<T>(bundleName, assetName);
|
|
|
|
|
_callbackList.Add(request);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
request = _callbackList[index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
request.AddCallback(callback, hashTable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(string bundleName, string assetName, LoadBundleAssetCallback<T> callback)
|
|
|
|
|
{
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
_callbackList[index].RemoveCallback(callback);
|
|
|
|
|
if (_callbackList[index].callBackList.Count <= 0)
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveAllCallback(string bundleName, string assetName)
|
|
|
|
|
{
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAsset(string bundleName, string assetName, Object asset)
|
|
|
|
|
{
|
|
|
|
|
// 这个接收底层回调的消息,不会出现名字错误的问题
|
|
|
|
|
var index = _callbackList.GetIndexFromList(bundleName, assetName);
|
|
|
|
|
if (index >= 0)
|
|
|
|
|
{
|
|
|
|
|
var item = _callbackList[index];
|
|
|
|
|
_callbackList.RemoveAt(index);
|
|
|
|
|
item.FinishAsset(asset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
_callbackList.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 部分系统会需要穿越Asset级别,直接操作AssetBundle,保留这么一个回调
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class LoadWholeBundleRequest
|
|
|
|
|
{
|
|
|
|
|
public readonly List<LoadAssetBundleFinish> callbackList = new List<LoadAssetBundleFinish>();
|
2024-09-23 22:56:51 +08:00
|
|
|
|
public readonly string name;
|
2024-08-23 15:49:34 +08:00
|
|
|
|
|
|
|
|
|
public LoadWholeBundleRequest(string bundleName)
|
|
|
|
|
{
|
|
|
|
|
name = bundleName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddCallback(LoadAssetBundleFinish callback)
|
|
|
|
|
{
|
|
|
|
|
if (!callbackList.Contains(callback))
|
|
|
|
|
callbackList.Add(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveCallback(LoadAssetBundleFinish callback)
|
|
|
|
|
{
|
|
|
|
|
callbackList.Remove(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FinishAssetBundleLoad()
|
|
|
|
|
{
|
|
|
|
|
for (var i = 0; i < callbackList.Count; i++)
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (callbackList[i] != null)
|
|
|
|
|
callbackList[i].Invoke(name);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
LogModule.ErrorLog(e.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// public class LoadWholeBundleList
|
|
|
|
|
// {
|
|
|
|
|
// private readonly List<LoadWholeBundleRequest> _callbackList = new List<LoadWholeBundleRequest>();
|
|
|
|
|
//
|
|
|
|
|
// public void AddCallback(string bundleName, LoadAssetBundleFinish callback)
|
|
|
|
|
// {
|
|
|
|
|
// var index = GetCallbackIndex(bundleName);
|
|
|
|
|
// LoadWholeBundleRequest request;
|
|
|
|
|
// if (index < 0)
|
|
|
|
|
// {
|
|
|
|
|
// request = new LoadWholeBundleRequest(bundleName);
|
|
|
|
|
// _callbackList.Add(request);
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// request = _callbackList[index];
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// request.AddCallback(callback);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// public void RemoveCallback(string bundleName, LoadAssetBundleFinish callback)
|
|
|
|
|
// {
|
|
|
|
|
// var index = GetCallbackIndex(bundleName);
|
|
|
|
|
// if (index >= 0)
|
|
|
|
|
// {
|
|
|
|
|
// _callbackList[index].RemoveCallback(callback);
|
|
|
|
|
// if (_callbackList[index].callbackList.Count <= 0)
|
|
|
|
|
// _callbackList.RemoveAt(index);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// public void FinishBundle(string bundleName)
|
|
|
|
|
// {
|
|
|
|
|
// var index = GetCallbackIndex(bundleName);
|
|
|
|
|
// if (index >= 0)
|
|
|
|
|
// {
|
|
|
|
|
// var item = _callbackList[index];
|
|
|
|
|
// _callbackList.RemoveAt(index);
|
|
|
|
|
// item.FinishAssetBundleLoad();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// private int GetCallbackIndex(string bundleName)
|
|
|
|
|
// {
|
|
|
|
|
// var index = -1;
|
|
|
|
|
// for (var i = 0; i < _callbackList.Count; i++)
|
|
|
|
|
// if (_callbackList[i].name.Equals(bundleName, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
// {
|
|
|
|
|
// index = i;
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return index;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// public void Clear()
|
|
|
|
|
// {
|
|
|
|
|
// _callbackList.Clear();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
#endregion
|