2025-07-16 19:16:46 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-07-16 13:36:21 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.AddressableAssets;
|
|
|
|
|
|
using UnityEngine.AddressableAssets.ResourceLocators;
|
|
|
|
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
|
|
|
|
using UnityEngine.ResourceManagement.ResourceLocations;
|
2025-07-24 12:50:20 +08:00
|
|
|
|
using UnityEngine.U2D;
|
2025-07-16 13:36:21 +08:00
|
|
|
|
|
|
|
|
|
|
namespace CreatGame.AssetBundle
|
2025-07-15 15:33:35 +08:00
|
|
|
|
{
|
|
|
|
|
|
public class AssetBundleManager : Singleton<AssetBundleManager>
|
|
|
|
|
|
{
|
2025-07-17 09:52:33 +08:00
|
|
|
|
private class AssetBundleData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string assetBundleName;
|
|
|
|
|
|
public GameObject assetBundle;
|
|
|
|
|
|
}
|
2025-07-24 12:50:20 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Dictionary<string, AssetBundleData> m_AssetBundles;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Dictionary<string, SpriteAtlas> m_SpriteAtlasCache;
|
2025-07-16 19:16:46 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 是否初始化完成
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool IsInitializeAsync;
|
2025-07-15 15:33:35 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 需要初始化Addressble系统
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public AssetBundleManager()
|
|
|
|
|
|
{
|
2025-07-16 19:16:46 +08:00
|
|
|
|
IsInitializeAsync = false;
|
2025-07-24 12:50:20 +08:00
|
|
|
|
m_AssetBundles = new Dictionary<string, AssetBundleData>();
|
|
|
|
|
|
m_SpriteAtlasCache = new Dictionary<string, SpriteAtlas>();
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-16 13:36:21 +08:00
|
|
|
|
Addressables.InitializeAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
Addressables.InitializeAsync().Completed += OnInitializeCompleted;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 初始化信息回调
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnInitializeCompleted(AsyncOperationHandle<IResourceLocator> operationHandle)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (operationHandle.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("Addressables initialization succeeded");
|
|
|
|
|
|
#region MyRegion
|
|
|
|
|
|
// IResourceLocator locator = operationHandle.Result;
|
|
|
|
|
|
// foreach (object locatorKey in locator.Keys)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// locator.Locate(locatorKey,typeof(UnityEngine.Object),out IList<IResourceLocation> locations);
|
|
|
|
|
|
// if (locations == null)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// continue;
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
|
|
|
|
|
// foreach (var location in locations)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// string key = location.PrimaryKey;
|
|
|
|
|
|
// Addressables.LoadAssetAsync<UnityEngine.Object>(key).Completed += (handle) =>
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// Debug.Log("Addressables load asset succeeded");
|
|
|
|
|
|
// var asset = handle.Result;
|
|
|
|
|
|
// GameObject.Instantiate(asset);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// };
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
#endregion
|
2025-07-16 19:16:46 +08:00
|
|
|
|
|
|
|
|
|
|
IsInitializeAsync = true;
|
2025-07-16 13:36:21 +08:00
|
|
|
|
}
|
2025-07-15 15:33:35 +08:00
|
|
|
|
}
|
2025-07-19 17:59:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步加载资源
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="assetBundleName"></param>
|
|
|
|
|
|
/// <param name="callback"></param>
|
|
|
|
|
|
public void LoadGameObjectAsync(string assetBundleName, Action<GameObject> callback)
|
2025-07-16 19:16:46 +08:00
|
|
|
|
{
|
2025-07-24 12:50:20 +08:00
|
|
|
|
if (m_AssetBundles.TryGetValue(assetBundleName, out var bundle))
|
2025-07-17 09:52:33 +08:00
|
|
|
|
{
|
|
|
|
|
|
callback.Invoke(GameObject.Instantiate(bundle.assetBundle));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-16 19:16:46 +08:00
|
|
|
|
Addressables.LoadAssetAsync<GameObject>(assetBundleName).Completed += (handle) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
2025-07-19 17:59:28 +08:00
|
|
|
|
var assetData = CacheAssetBundles(assetBundleName, handle.Result);
|
|
|
|
|
|
Addressables.Release(handle);
|
|
|
|
|
|
callback?.Invoke(GameObject.Instantiate(assetData.assetBundle));
|
2025-07-16 19:16:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"assetBundleName = {assetBundleName} 加载失败 Status = {handle.Status}");
|
|
|
|
|
|
callback?.Invoke(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2025-07-19 17:59:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 同步等待加载资源
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="assetBundleName"></param>
|
|
|
|
|
|
public GameObject LoadGameObject(string assetBundleName)
|
|
|
|
|
|
{
|
2025-07-24 12:50:20 +08:00
|
|
|
|
if (m_AssetBundles.TryGetValue(assetBundleName, out var bundle))
|
2025-07-19 17:59:28 +08:00
|
|
|
|
{
|
|
|
|
|
|
return GameObject.Instantiate(bundle.assetBundle);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var handle = Addressables.LoadAssetAsync<GameObject>(assetBundleName);
|
|
|
|
|
|
handle.WaitForCompletion();
|
|
|
|
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
|
|
|
|
|
bundle = CacheAssetBundles(assetBundleName, handle.Result);
|
|
|
|
|
|
Addressables.Release(handle);
|
|
|
|
|
|
|
|
|
|
|
|
return GameObject.Instantiate(bundle.assetBundle);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Debug.LogError("资源加载失败");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 缓存加载出来的资源
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="bundleName"></param>
|
|
|
|
|
|
/// <param name="bundle"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private AssetBundleData CacheAssetBundles(string bundleName, GameObject bundle = null)
|
|
|
|
|
|
{
|
2025-07-19 20:29:55 +08:00
|
|
|
|
var data = new AssetBundleData(){assetBundleName = bundleName, assetBundle = bundle};
|
2025-07-24 12:50:20 +08:00
|
|
|
|
m_AssetBundles.Add(bundleName, data);
|
2025-07-19 17:59:28 +08:00
|
|
|
|
return data;
|
|
|
|
|
|
}
|
2025-07-24 12:50:20 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 同步加载图集
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="atlasName"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public SpriteAtlas LoadSpriteAtlas(string atlasName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_SpriteAtlasCache.TryGetValue(atlasName, out var atlas))
|
|
|
|
|
|
{
|
|
|
|
|
|
return atlas;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var handle = Addressables.LoadAssetAsync<SpriteAtlas>(atlasName);
|
|
|
|
|
|
handle.WaitForCompletion();
|
|
|
|
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
|
|
|
|
|
atlas = handle.Result;
|
|
|
|
|
|
Addressables.Release(handle);
|
|
|
|
|
|
m_SpriteAtlasCache.Add(atlasName, atlas);
|
|
|
|
|
|
return atlas;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Debug.LogError($"图集加载失败 atlasName = {atlasName} Status = {handle.Status}");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步加载图集
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="assetBundleName"></param>
|
|
|
|
|
|
/// <param name="callback"></param>
|
|
|
|
|
|
public void LoadSpriteAsync(string atlasName, Action<SpriteAtlas> callback)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_SpriteAtlasCache.TryGetValue(atlasName, out var atlas))
|
|
|
|
|
|
{
|
|
|
|
|
|
callback.Invoke(atlas);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
Addressables.LoadAssetAsync<SpriteAtlas>(atlasName).Completed += (handle) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
|
|
|
|
{
|
|
|
|
|
|
atlas = handle.Result;
|
|
|
|
|
|
Addressables.Release(handle);
|
|
|
|
|
|
m_SpriteAtlasCache.Add(atlasName, atlas);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"图集加载失败 atlasName = {atlasName} Status = {handle.Status}");
|
|
|
|
|
|
callback?.Invoke(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 释放所有的资源
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void ReleaseAll()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var mAssetBundle in m_AssetBundles)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameObject.Destroy(mAssetBundle.Value.assetBundle);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_AssetBundles.Clear();
|
|
|
|
|
|
}
|
2025-07-15 15:33:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|