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 ;
2024-04-23 18:25:12 +08:00
using UnityEngine.ResourceManagement.ResourceLocations ;
using System.IO ;
using UnityEngine.UI ;
2024-04-21 22:38:26 +08:00
public class AssetLibrary : MonoBehaviour
{
protected static AssetLibrary _mainInstance ;
public ResourceLocationMap AddressableResourceMap ;
2024-04-23 18:25:12 +08:00
public List < Shader > Shaders ;
2024-04-25 08:16:49 +08:00
public string LocalFilesPath = > ModelViewerSettings . Get ( "AssetsPath" ) ;
2024-04-23 18:25:12 +08:00
private List < string > _addressableKeys ;
public Dictionary < string , AssetBundle > LoadedAssets = new Dictionary < string , AssetBundle > ( ) ;
protected virtual void Awake ( )
{
_mainInstance = this ;
}
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 ;
}
}
2024-04-23 18:25:12 +08:00
public string GetResourcePath ( string resourceName , out List < string > dependencies )
2024-04-21 22:38:26 +08:00
{
2024-04-23 18:25:12 +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 )
{
2024-04-23 18:25:12 +08:00
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 void UnloadAssets ( List < string > 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 ) ;
2024-04-21 22:38:26 +08:00
}
}
}