using System.Linq; using UnityEngine; using System.Collections; using Newtonsoft.Json.Linq; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using System.Collections.Generic; using UnityEngine.ResourceManagement.ResourceLocations; using System.IO; using UnityEngine.UI; public class AssetLibrary : MonoBehaviour { protected static AssetLibrary _mainInstance; public ResourceLocationMap AddressableResourceMap; public List Shaders; public string LocalFilesPath => ModelViewerSettings.Get("AssetsPath"); private List _addressableKeys; public Dictionary LoadedAssets = new Dictionary(); protected virtual void Awake() { _mainInstance = this; } public static T GetInstance() where T : AssetLibrary { return _mainInstance as T; } public List GetAddressableKeys() { if (_addressableKeys == null) { _addressableKeys = AddressableResourceMap.Keys.Select(k=>k.ToString()).ToList(); } return _addressableKeys.ToList(); } /// /// Load catalog.json from games that use addressables /// /// /// public IEnumerator LoadAddressableCatalog(string catalogPath) { var opHandle = Addressables.LoadContentCatalogAsync(catalogPath); yield return opHandle; if (opHandle.Status == AsyncOperationStatus.Succeeded) { Debug.Log(opHandle.Result.GetType()); AddressableResourceMap = opHandle.Result as ResourceLocationMap; } else { throw opHandle.OperationException; } } public string GetResourcePath(string resourceName, out List dependencies) { dependencies = new List(); var locator = AddressableResourceMap.Locations[resourceName][0]; // AddressableResourceMap.Locations[resourceName][0].Dependencies[0].Data as AssetBundleRequestOptions; if (locator.HasDependencies) { GatherDependencies(locator, dependencies); var data = locator.Dependencies[0].Data as AssetBundleRequestOptions; var filePath = data.BundleName + "/" + data.Hash + "/" + "__data"; dependencies.Remove(filePath); return filePath; } else { var data = locator.Data as AssetBundleRequestOptions; var filePath = data.BundleName + "/" + data.Hash + "/" + "__data"; return filePath; } } private void GatherDependencies(IResourceLocation resource, List dependencies) { if (!resource.HasDependencies) { var data = resource.Data as AssetBundleRequestOptions; var filePath = data.BundleName + "/" + data.Hash + "/" + "__data"; if (!dependencies.Contains(filePath)) { dependencies.Add(filePath); } } else { foreach (var dep in resource.Dependencies) { GatherDependencies(dep, dependencies); } } } public IEnumerator LoadAssets(List paths) { var progressBar = ModelViewerInterface.GetInstance().ProgressBar; for (int i = paths.Count - 1; i >= 0; i--) { if (!File.Exists(paths[i])) { paths.RemoveAt(i); } } List routines = new List(); foreach(var path in paths) { routines.Add(AssetBundle.LoadFromFileAsync(path)); } while (routines.Any(r => !r.isDone)) { int finished = routines.Count(r => r.isDone); progressBar?.SetProgress($"Reading files ({finished}/{routines.Count})", (float)finished / routines.Count); yield return 0; } for (int i = 0; i < routines.Count; i++) { LoadedAssets.Add(paths[i], routines[i].assetBundle); } progressBar?.SetProgress("", 1); } public static AssetBundle LoadFromFile(string path) { var bundle = AssetBundle.LoadFromFile(path); _mainInstance.LoadedAssets.Add(path, bundle); return bundle; } public void UnloadAssets(List paths) { for (int i = 0; i < paths.Count; i++) { UnloadAsset(paths[i]); } } public void UnloadAsset(string path) { if (LoadedAssets.ContainsKey(path)) { LoadedAssets[path].Unload(false); LoadedAssets.Remove(path); } } }