UniversalViewer/Assets/Scripts/ModelViewerBase/AssetLibrary.cs

187 lines
5.7 KiB
C#
Raw Permalink Normal View History

2024-04-21 22:38:26 +08:00
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;
using static UnityEngine.EventSystems.EventTrigger;
using System.ComponentModel;
2024-04-21 22:38:26 +08:00
public class AssetLibrary : MonoBehaviour
{
protected static AssetLibrary _mainInstance;
public ResourceLocationMap AddressableResourceMap;
public List<Shader> Shaders;
public string LocalFilesPath;
private List<string> _addressableKeys;
public Dictionary<string, AssetBundle> LoadedAssets = new Dictionary<string, AssetBundle>();
public Transform UIAssetList => ModelViewerInterface.GetInstance().CanvasContainer.AssetsList.content;
protected virtual void Awake()
{
_mainInstance = this;
}
2024-04-21 22:38:26 +08:00
public static AssetLibrary GetInstance()
{
return _mainInstance;
}
2024-04-21 22:38:26 +08:00
public static T GetInstance<T>() where T : AssetLibrary
{
return _mainInstance as T;
}
public List<string> GetAddressableKeys()
{
if (_addressableKeys == null)
{
_addressableKeys = AddressableResourceMap.Keys.Select(k=>k.ToString()).ToList();
}
return _addressableKeys.ToList();
}
/// <summary>
/// Load catalog.json from games that use addressables
/// </summary>
/// <param name="catalogPath"></param>
/// <returns></returns>
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<string> dependencies)
2024-04-21 22:38:26 +08:00
{
dependencies = new List<string>();
2024-04-21 22:38:26 +08:00
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<string> 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<string> paths)
{
var progressBar = ModelViewerInterface.GetInstance().ProgressBar;
for (int i = paths.Count - 1; i >= 0; i--)
{
if (!File.Exists(paths[i]))
{
paths.RemoveAt(i);
}
}
List<AssetBundleCreateRequest> routines = new List<AssetBundleCreateRequest>();
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 static void UnloadAssets(List<string> paths)
{
for (int i = 0; i < paths.Count; i++)
{
UnloadAsset(paths[i]);
}
}
public static void UnloadAsset(string path)
{
var loadedAssets = _mainInstance.LoadedAssets;
if (loadedAssets.ContainsKey(path))
{
loadedAssets[path].Unload(false);
loadedAssets.Remove(path);
}
}
public void SetAssetList(List<string[]> loadedAssets)
{
for(int i = UIAssetList.childCount - 1; i >= 0; i--)
{
Destroy(UIAssetList.GetChild(i).gameObject);
}
if (loadedAssets == null) return;
foreach(var entry in loadedAssets)
{
var button = Instantiate(SharedResources.Instance.Button, UIAssetList);
button.GetComponentInChildren<TMPro.TMP_Text>().text = entry[0];
button.onClick.AddListener(() => { System.Diagnostics.Process.Start("explorer.exe", "/select," + Path.GetFullPath(entry[1])); });
2024-04-21 22:38:26 +08:00
}
}
}