killapp/Assets/Scripts/Base/LoadRes.cs

232 lines
7.6 KiB
C#
Raw Normal View History

2025-11-18 09:18:48 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace Kill.Base
{
public class LoadRes : MonoBehaviour
{
[Serializable]
public enum ResPosition
{
= 1,
= 2
}
public ResPosition resPosition;
public static LoadRes Instance;
public Dictionary<string, AssetBundle> loadedBundles;
public List<string> commonList;
void Awake()
{
Instance = this;
}
public async Task Init()
{
#if !UNITY_EDITOR
resPosition=ResPosition.;
#endif
if (resPosition == ResPosition.)
{
loadedBundles = new Dictionary<string, AssetBundle>();
if (commonList != null)
{
foreach (string bundleName in commonList)
{
await LoadBundleAsync(bundleName);
}
}
}
await LanguageManager.Instance.Init();
UI.UIManager.Instance.Init();
}
/// <summary>
/// 异步加载AssetBundle
/// </summary>
/// <param name="bundleName">Bundle名称</param>
/// <returns>AssetBundle对象</returns>
public async Task<AssetBundle> LoadBundleAsync(string bundleName)
{
if (resPosition == ResPosition.)
{
return null;
}
// 检查是否已经加载过该bundle
if (loadedBundles.ContainsKey(bundleName))
{
return loadedBundles[bundleName];
}
string localPath = Application.persistentDataPath + "/" + bundleName + ".ab";
AssetBundle bundleToReturn = null;
try
{
if (System.IO.File.Exists(localPath))
{
// 优先加载热更新后的包
var loadRequest = AssetBundle.LoadFromFileAsync(localPath);
while (!loadRequest.isDone)
{
await Task.Yield();
}
bundleToReturn = loadRequest.assetBundle;
}
else
{
// fallback加载 StreamingAssets 中的原始包(首次安装时)
string streamingPath = Application.streamingAssetsPath + "/" + bundleName + ".ab";
var loadRequest = AssetBundle.LoadFromFileAsync(streamingPath);
while (!loadRequest.isDone)
{
await Task.Yield();
}
bundleToReturn = loadRequest.assetBundle;
}
// 如果加载成功,添加到字典中避免下次重复加载
if (bundleToReturn != null)
{
loadedBundles.Add(bundleName, bundleToReturn);
}
}
catch (Exception e)
{
Debug.LogError($"加载AssetBundle失败: {bundleName}, 错误: {e.Message}");
}
return bundleToReturn;
}
/// <summary>
/// 同步加载AssetBundle保留原有方法
/// </summary>
/// <param name="bundleName">Bundle名称</param>
/// <returns>AssetBundle对象</returns>
public AssetBundle LoadBundle(string bundleName)
{
if (resPosition == ResPosition.)
{
return null;
}
// 检查是否已经加载过该bundle
if (loadedBundles.ContainsKey(bundleName))
{
return loadedBundles[bundleName];
}
string localPath = Application.persistentDataPath + "/" + bundleName + ".ab";
AssetBundle bundleToReturn = null;
try
{
if (System.IO.File.Exists(localPath))
{
// 优先加载热更新后的包
bundleToReturn = AssetBundle.LoadFromFile(localPath);
}
else
{
// fallback加载 StreamingAssets 中的原始包(首次安装时)
string streamingPath = Application.streamingAssetsPath + "/" + bundleName + ".ab";
bundleToReturn = AssetBundle.LoadFromFile(streamingPath);
}
// 如果加载成功,添加到字典中避免下次重复加载
if (bundleToReturn != null)
{
loadedBundles.Add(bundleName, bundleToReturn);
}
}
catch (Exception e)
{
Debug.LogError($"加载AssetBundle失败: {bundleName}, 错误: {e.Message}");
}
return bundleToReturn;
}
string localPath = "Assets/Res/";
/// <summary>
/// 通用资源加载方法(同步)
/// </summary>
/// <typeparam name="T">资源类型</typeparam>
/// <param name="bundleName">Bundle名称</param>
/// <param name="assetName">资源名称</param>
/// <returns>指定类型的资源</returns>
public T LoadAsset<T>(string bundleName, string assetName) where T : UnityEngine.Object
{
#if UNITY_EDITOR
if (resPosition == ResPosition.)
{
string[] paths = bundleName.Split('_');
string realPath = localPath;
foreach (string path in paths)
{
realPath += path + "/";
}
return AssetDatabase.LoadAssetAtPath<T>(realPath + assetName);
}
#endif
AssetBundle ab = LoadBundle(bundleName);
if (ab != null)
{
return ab.LoadAsset<T>(assetName);
}
return null;
}
/// <summary>
/// 通用资源加载方法(异步)
/// </summary>
/// <typeparam name="T">资源类型</typeparam>
/// <param name="bundleName">Bundle名称</param>
/// <param name="assetName">资源名称</param>
/// <returns>指定类型的资源</returns>
public async Task<T> LoadAssetAsync<T>(string bundleName, string assetName) where T : UnityEngine.Object
{
#if UNITY_EDITOR
if (resPosition == ResPosition.)
{
string[] paths = bundleName.Split('_');
string realPath = localPath;
foreach (string path in paths)
{
realPath += path + "/";
}
return AssetDatabase.LoadAssetAtPath<T>(realPath + assetName);
}
#endif
AssetBundle ab = await LoadBundleAsync(bundleName);
if (ab != null)
{
var assetRequest = ab.LoadAssetAsync<T>(assetName);
while (!assetRequest.isDone)
{
await Task.Yield();
}
return assetRequest.asset as T;
}
return null;
}
public void UnloadBundle(string bundleName)
{
if (loadedBundles.ContainsKey(bundleName))
{
AssetBundle bundle = loadedBundles[bundleName];
bundle.Unload(false);
loadedBundles.Remove(bundleName);
}
}
}
}