using System.Collections; using System.Collections.Generic; using System.Linq; using Ichni.StartMenu; using SLSUtilities.General; using TMPro; using UniRx; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Serialization; namespace Ichni { public class ThemeBundleManager : Singleton { /// 小写别名,兼容现有调用点 public new static ThemeBundleManager instance => Instance; public List themeBundleAbstractList; public List selectedThemeBundleList; public List loadedThemeBundleList; public IntReactiveProperty waitingBundleAmount; public TMP_Text LogWindow; protected override void Awake() { Initialize(true); // DontDestroyOnLoad 持久化单例 loadedThemeBundleList = new List(); AssetBundle.UnloadAllAssetBundles(true); LoadAllThemeBundlesAbstract(); } public bool TryGetThemeBundle(string themeBundleName, out ThemeBundle themeBundle) { themeBundle = loadedThemeBundleList.Find(bundle => bundle.themeBundleName == themeBundleName); return themeBundle != null; } public T GetObject(string themeBundleName, string objectName) where T : class { return loadedThemeBundleList.Find(bundle => bundle.themeBundleName == themeBundleName)?.GetObject(objectName); } public void LoadThemeBundles(List list) { AssetBundle.UnloadAllAssetBundles(true); loadedThemeBundleList.Clear(); LogWindow = StartMenuManager.instance.startPage.logText; if (InformationTransistor.instance.isRecovery) { LogWindow.text += "Recovery Mode.\n"; LogWindow.color = Color.red; } LogWindow.text += "Loading ThemeBundles, Please wait...\n"; waitingBundleAmount = new IntReactiveProperty(list.Count); Debug.Log("Waiting for " + list.Count + " AssetBundles to load."); LogWindow.text += "Waiting for " + list.Count + " AssetBundles to load.\n"; foreach (var bundle in list) { LoadThemeBundle(bundle); } selectedThemeBundleList = list; } public void LoadAllThemeBundlesAbstract() { string uri = Application.streamingAssetsPath + "/ThemeBundles/"; if (ES3.DirectoryExists(uri)) { List allFileList = ES3.GetFiles(uri).ToList(); List absList = new List(); foreach (var abs in allFileList) { if (abs.EndsWith(".abs")) { absList.Add(abs); } } foreach (var abs in absList) { themeBundleAbstractList.Add(ES3.Load("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; } UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri, 0); yield return request.SendWebRequest(); AssetBundle bundle = AssetBundle.LoadFromFile(uri); Object[] ob = bundle.LoadAllAssets(); 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]); } } yield return new WaitForEndOfFrame(); print(themeBundleName + " Done!"); LogWindow.text += themeBundleName + " Done!\n"; waitingBundleAmount.Value--; } } [System.Serializable] public class ThemeBundleAbstract { public string fileName; public string displayName; public string description; public List tags; public string iconPath; public ThemeBundleAbstract() { } public ThemeBundleAbstract(string fileName) { this.fileName = fileName; this.displayName = fileName; this.description = "Default Description"; this.tags = new List(); 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 assetList_GameObject; public List assetList_Material; public List assetList_Texture; public List assetList_Other; public ThemeBundle(string name) { themeBundleName = name; assetList_GameObject = new List(); assetList_Material = new List(); assetList_Texture = new List(); assetList_Other = new List(); } public T GetObject(string name) { if (name == "None") { return default(T); } 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) { 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) { 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) { 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) { return assetList[i]; } } } return default(T); } } }