1221 lines
41 KiB
C#
Raw 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;
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";
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/";
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>();
private readonly LoadAssetRequestList<Object> _assetList = new LoadAssetRequestList<Object>();
private readonly LoadAssetRequestList<AudioClip> _audioList = new LoadAssetRequestList<AudioClip>();
private readonly LoadAssetRequestList<TextAsset> _textAssetList = new LoadAssetRequestList<TextAsset>();
private readonly LoadSpriteRequestList _spriteList = new LoadSpriteRequestList();
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 =
AssetConst.persistentDataPath.Open(AssetUtils.GetTextMd5(AssetConst.versionFile) +
AssetConst.bundleVariant);
AssetDependencyInfo dependencyInfo = null;
if (!File.Exists(dependencyPath))
{
Debug.LogError(
"Cannot find dependency file. You should start the game from AssetUpdate instead of Login!");
}
else
dependencyInfo = AssetDependencyInfo.Create(dependencyPath);
Debug.Log("LoaderAssetsBundle");
if (dependencyInfo == null)
{
Debug.LogError("Unable to load dependency file! This is not recoverable!");
LiteConfirmWin.Open("资源错误", "无法加载资源依赖!\n需要重启游戏修复",
new LiteConfirmButtonData("确定", () => SdkControl.instance.CloseGame()));
}
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>
{
new AsyncLoadRule(0, 1),
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);
}
}
DontDestroyOnLoad(gameObject);
}
public void StartBackGround()
{
if (!AssetUpdateManager.useResources)
AssetManager.instance.bundleManager.downloadHub.StartBackGroundDownload();
}
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) &&
!string.IsNullOrEmpty(assetName) &&
!bundleName.Equals("-1") &&
!assetName.Equals("-1");
}
private void LoadAssetFromList<T>(string bundleName, string assetName, LoadBundleAssetCallback<T> callback,
Hashtable hashtable, LoadAssetRequestList<T> list, bool archive) where T : Object
{
// 已知问题,即使已经加载的资源,仍然会产生一次列表推入和回调监听,造成少量性能浪费
// 暂时不修改这个结构,保持当前强健的逻辑流程
list.AddCallback(bundleName, assetName, callback, hashtable);
LoadAssetInternal<T>(bundleName, assetName);
}
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);
}
public void LoadGameObject(string bundleName, string assetName, LoadBundleAssetCallback<GameObject> callback,
Hashtable hashParam, bool archive = false)
{
if (IsBundleAndAssetValid(bundleName, assetName))
{
bundleName += assetName;
bundleName = FixBundleName(bundleName);
LoadAssetFromList(bundleName, assetName, callback, hashParam, _gameObjectList, archive);
}
}
public void LoadAsset(string bundleName, string assetName, LoadBundleAssetCallback<Object> callback,
Hashtable hashParam, bool archive = false)
{
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);
}
}
public void LoadUI(string bundleName, string assetName, LoadBundleAssetCallback<GameObject> callback,
Hashtable hashParam, bool archive = true)
{
if (IsBundleAndAssetValid(bundleName, assetName))
{
bundleName = FixBundleName(bundleName);
LoadAssetFromList(bundleName, assetName, callback, hashParam, _gameObjectList, archive);
}
}
public void LoadSoundAsync(string bundlePath, string assetName, LoadBundleAssetCallback<AudioClip> callback,
Hashtable hashParam)
{
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;
valid = true;
}
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;
valid = true;
}
else
{
valid = !image.sprite.name.Equals(assetName);
}
}
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);
}
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);
}
#if UNITY_EDITOR
[Serializable]
public class EditorBundleList
{
private readonly Dictionary<string, string> _assetDataList = new Dictionary<string, string>();
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
{
public readonly string bundleName;
public readonly string assetName;
public readonly AsyncOperation operation;
public EditorResourceAsync(string bundleName, string assetName, AsyncOperation operation)
{
this.bundleName = bundleName;
this.assetName = assetName;
this.operation = operation;
}
}
public const string assetPathHeader = "Assets/Project3D/Resources";
public const string uiSpriteAssetPath = "Assets/Project3D/Sprites";
public const string bundleToAssetPath = "Assets/Editor/Config/BundleToAsset" + AssetConst.bytesExtension;
private Dictionary<string, string> _uiCommonPathDict;
private Dictionary<string, EditorBundleList> _resourcesDict;
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>>();
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);
}
}
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>;
}
if (_resourcesDict == null)
_resourcesDict = new Dictionary<string, EditorBundleList>();
}
EditorBundleList list;
if (!_resourcesDict.TryGetValue(bundleName, out list))
{
var assets = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName + AssetConst.bundleVariant)
.Where(a => a.StartsWith(assetPathHeader))
.Select(a => a.RemoveExtension().Substring(assetPathHeader.Length + 1)).ToArray();
if (assets.Length > 0)
{
list = new EditorBundleList(assets);
_resourcesDict[bundleName] = list;
var bitFormatter = new BinaryFormatter();
var dataPath = Application.dataPath.MoveUp().Open(bundleToAssetPath);
using (var fs = File.OpenWrite(dataPath))
bitFormatter.Serialize(fs, _resourcesDict);
}
}
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;
}
}
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; }
// 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();
}
// /// <summary>
// /// 加载一个AssetBundle如果Bundle已经加载就返回true
// /// </summary>
// private void LoadOneAssetBundle(string bundleName)
// {
// bundleName = FixBundleName(bundleName);
// AssetManager.instance.Preload(bundleName, this, OnAssetBundleLoaded);
// }
#endregion
#region
/// <summary>
/// 预加载场景电影Bundle
/// </summary>
private readonly List<int> _movieId = new List<int>();
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);
}
}
return movieName;
}
private void AddMoviePreload(int movieId)
{
var movieName = GetMovieName(movieId);
if (!string.IsNullOrEmpty(movieName))
Instance.LoadGameObject(BUNDLE_PATH_MODEL, movieName, null, null);
}
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);
}
}
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;
}
if (!_movieId.Contains(movieId))
AddMoviePreload(movieId);
}
public void CleanPreloadScene()
{
_preloadScene = string.Empty;
foreach (var id in _movieId)
RemoveMoviePreload(id);
_movieId.Clear();
}
#endregion
#region loadScene
/// <summary>
/// 是否允许加载场景
/// </summary>
// 注如果当前有其他SceneLoadOperaction则不允许继续加载场景
public bool AllowLoadScene()
{
return !AssetManager.instance.IsLoadingScene();
}
public static string GetSceneBundleName(string sceneName)
{
var bundleName = "scene/" + sceneName;
bundleName = FixBundleName(bundleName);
return bundleName;
}
public void UnloadMainScene()
{
if (!AssetUpdateManager.useResources)
AssetManager.instance.UnloadAllScene();
}
/// <summary>
/// 加载主要场景 - 主要场景加载时,会卸载之前的主要场景
/// </summary>
public bool LoadMainScene(string assetName, LoadSceneMode mode, out SceneHandle loadHandle)
{
bool load;
if (AssetUpdateManager.useResources)
{
load = true;
loadHandle = null;
SceneManager.LoadScene(assetName);
}
else
{
var bundleName = GetSceneBundleName(assetName);
var current = AssetManager.instance.GetCurrentSceneHandle();
load = current == null || current.sceneName == assetName;
if (!load)
load = AllowLoadScene();
loadHandle = load ? AssetManager.instance.LoadScene(bundleName, assetName, mode, allowReload: true) : null;
}
return load;
}
#endregion
#region loadGameRes
public static string gameResBundleName
{
get { return FixBundleName(BUNDLE_PATH_GAMERES); }
}
#endregion
#region LoadTable
private const string _tableBundleName = "tables";
public TextAsset LoadTableAsset(string tableName)
{
return LoadTextAsset(_tableBundleName, tableName);
}
#if UNITY_EDITOR
public const string tablePath = "Assets/Project3D/BundleData/Tables3D/";
private Dictionary<string, string> _luaFiles;
#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))
.Where(a => AssetConst.textExtension.Equals(Path.GetExtension(a)));
foreach (var script in scripts)
_luaFiles.Add(Path.GetFileNameWithoutExtension(script).ToLower(), script);
}
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));
return result;
}
#endif
if (AssetManager.instance == null)
{
throw new Exception("AssetManager is not initialized!");
}
result = AssetManager.instance.LoadAssetSync<TextAsset>(bundleName, assetName);
return result;
}
#endregion
#region LoadScript
// 注之前逻辑是和LoadTable在一起但是没有监听过这个AssetBundle是否加载结束的
// 暂时保持接口和调用处不变
private const string _scriptBundleName = "script";
public TextAsset LoadScriptAsset(string script)
{
return LoadTextAsset(_scriptBundleName, script);
}
#endregion
#region Atlas Path Convert
private Dictionary<string, string> _pathConvertDict;
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(
"Try to load asset {0} from {1}, while Asset Load Manager hasn't init path conversion yet!",
assetName, bundleName));
}
return bundleName;
}
#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;
this.assetName = assetName;
}
}
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)
{
callBackList[i].first.sprite = sprite;
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)
{
var index = _callbackList.GetIndexFromList(bundleName, assetName);
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);
}
}
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);
var index = _callbackList.GetIndexFromList(bundleName, assetName);
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>>();
public void AddCallback(string bundleName, string assetName, LoadBundleAssetCallback<T> callback,
Hashtable hashTable)
{
var index = _callbackList.GetIndexFromList(bundleName, assetName);
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>();
public readonly string name;
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