Files
ichni_Official/Assets/Scripts/Manager/ThemeBundleManager.cs
SoulliesOfficial fe00ecfcc7 微调
2026-07-24 03:43:11 -04:00

301 lines
9.8 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.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Serialization;
namespace Ichni
{
public class ThemeBundleManager : MonoBehaviour
{
public static ThemeBundleManager instance;
public List<ThemeBundleAbstract> themeBundleAbstractList;
public List<string> selectedThemeBundleList;
public List<ThemeBundle> loadedThemeBundleList;
public IntReactiveProperty waitingBundleAmount;
// 只记录本 Manager 通过 AssetBundle.LoadFromFileAsync 加载的 Theme Bundle。
// Addressables包括 Unity Localization拥有自己的 Bundle 引用计数,绝不能通过
// AssetBundle.UnloadAllAssetBundles 代替各系统分别释放资源。
private readonly List<AssetBundle> loadedAssetBundles = new List<AssetBundle>();
private void Awake()
{
instance = this;
loadedThemeBundleList = new List<ThemeBundle>();
LoadAllThemeBundlesAbstract();
//LoadThemeBundle("basic");
//LoadThemeBundle("departure_to_multiverse");
}
private void OnDestroy()
{
// 仅卸载本实例拥有的 Theme Bundle不影响 Addressables 管理的 Locale、String Table
// 或其它系统加载的 AssetBundle。
foreach (AssetBundle bundle in loadedAssetBundles)
{
if (bundle != null)
{
bundle.Unload(true);
}
}
loadedAssetBundles.Clear();
loadedThemeBundleList?.Clear();
if (instance == this)
{
instance = null;
}
}
public bool TryGetThemeBundle(string themeBundleName, out ThemeBundle themeBundle)
{
themeBundle = loadedThemeBundleList.Find(bundle => bundle.themeBundleName == themeBundleName);
return themeBundle != null;
}
public T GetObject<T>(string themeBundleName, string objectName) where T : class
{
return loadedThemeBundleList.Find(bundle => bundle.themeBundleName == themeBundleName)?.GetObject<T>(objectName);
}
public void LoadThemeBundles(List<string> list)
{
waitingBundleAmount = new IntReactiveProperty(list.Count);
Debug.Log("Waiting for " + list.Count + " AssetBundles to load.");
foreach (var bundle in list)
{
LoadThemeBundle(bundle);
}
selectedThemeBundleList = list;
}
public void LoadAllThemeBundlesAbstract()
{
string uri = Application.streamingAssetsPath + "/ThemeBundles/";
if (ES3.DirectoryExists(uri))
{
List<string> allFileList = ES3.GetFiles(uri).ToList();
List<string> absList = new List<string>();
foreach (var abs in allFileList)
{
if (abs.EndsWith(".abs"))
{
absList.Add(abs);
}
}
foreach (var abs in absList)
{
themeBundleAbstractList.Add(ES3.Load<ThemeBundleAbstract>("ThemeBundleAbstract", uri + abs));
}
}
}
public void LoadThemeBundle(string themeBundleName)
{
StartCoroutine(LoadThemeBundleCoroutine(themeBundleName));
}
IEnumerator LoadThemeBundleCoroutine(string themeBundleName)
{
string uri = "";
if (Application.platform == RuntimePlatform.WindowsEditor ||
Application.platform == RuntimePlatform.WindowsPlayer)
{
uri = Application.streamingAssetsPath + "/ThemeBundles/Windows64/" + themeBundleName;
}
else if (Application.platform == RuntimePlatform.OSXEditor ||
Application.platform == RuntimePlatform.OSXPlayer)
{
uri = Application.streamingAssetsPath + "/ThemeBundles/OSX/" + themeBundleName;
}
else if (Application.platform == RuntimePlatform.Android)
{
uri = Application.streamingAssetsPath + "/ThemeBundles/Android/" + themeBundleName;
}
else if (Application.platform == RuntimePlatform.IPhonePlayer)
{
uri = Application.streamingAssetsPath + "/ThemeBundles/IOS/" + themeBundleName;
}
else
{
Debug.LogError("Unsupported platform for loading theme bundles.");
yield break;
}
AssetBundleCreateRequest createRequest = AssetBundle.LoadFromFileAsync(uri);
yield return createRequest;
AssetBundle bundle = createRequest.assetBundle;
if (bundle == null)
{
Debug.LogError($"Theme Bundle 加载失败:{uri}");
waitingBundleAmount.Value--;
yield break;
}
loadedAssetBundles.Add(bundle);
try
{
Object[] ob = bundle.LoadAllAssets<Object>();
loadedThemeBundleList.Add(new ThemeBundle(themeBundleName));
for (int i = 0; i < ob.Length; i++)
{
if (ob[i].GetType() == typeof(GameObject))
{
loadedThemeBundleList[^1].assetList_GameObject.Add(ob[i] as GameObject);
}
else if (ob[i].GetType() == typeof(Material))
{
loadedThemeBundleList[^1].assetList_Material.Add(ob[i] as Material);
}
else if (ob[i].GetType() == typeof(Texture2D))
{
loadedThemeBundleList[^1].assetList_Texture.Add(ob[i] as Texture2D);
}
else
{
loadedThemeBundleList[^1].assetList_Other.Add(ob[i]);
}
}
}
catch (System.Exception exception)
{
Debug.LogException(exception, this);
}
finally
{
waitingBundleAmount.Value--;
}
yield return new WaitForEndOfFrame();
print(themeBundleName + " Done!");
}
}
[System.Serializable]
public class ThemeBundleAbstract
{
public string fileName;
public string displayName;
public string description;
public List<string> tags;
public string iconPath;
public ThemeBundleAbstract()
{
}
public ThemeBundleAbstract(string fileName)
{
this.fileName = fileName;
this.displayName = fileName;
this.description = "Default Description";
this.tags = new List<string>();
this.iconPath = "Icons/Default.png";
}
public Texture2D GetIcon()
{
string uri = Application.streamingAssetsPath + "/" + iconPath;
if (ES3.FileExists(uri))
{
Texture2D sp = ES3.LoadImage(uri);
return sp;
}
return null;
}
}
[System.Serializable]
public class ThemeBundle
{
public string themeBundleName;
public List<GameObject> assetList_GameObject;
public List<Material> assetList_Material;
public List<Texture2D> assetList_Texture;
public List<Object> assetList_Other;
public ThemeBundle(string name)
{
themeBundleName = name;
assetList_GameObject = new List<GameObject>();
assetList_Material = new List<Material>();
assetList_Texture = new List<Texture2D>();
assetList_Other = new List<Object>();
}
public T GetObject<T>(string name) where T : class
{
if (name == "None")
{
return null;
}
T[] assetList;
if (typeof(T) == typeof(GameObject))
{
assetList = assetList_GameObject.ToArray() as T[];
for (int i = 0; i < assetList_GameObject.Count; i++)
{
if (name == assetList_GameObject[i].name)
{
if (assetList != null) return assetList[i];
}
}
}
else if (typeof(T) == typeof(Material))
{
assetList = assetList_Material.ToArray() as T[];
for (int i = 0; i < assetList_Material.Count; i++)
{
if (name == assetList_Material[i].name)
{
if (assetList != null) return assetList[i];
}
}
}
else if (typeof(T) == typeof(Texture2D))
{
assetList = assetList_Texture.ToArray() as T[];
for (int i = 0; i < assetList_Texture.Count; i++)
{
if (name == assetList_Texture[i].name)
{
if (assetList != null) return assetList[i];
}
}
}
else
{
assetList = assetList_Other.ToArray() as T[];
for (int i = 0; i < assetList_Other.Count; i++)
{
if (name == assetList_Other[i].name)
{
if (assetList != null) return assetList[i];
}
}
}
return null;
}
}
}