123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- using UnityEngine;
- using System.Collections.Generic;
- #if UNITY_5_4_OR_NEWER
- using UnityEngine.SceneManagement;
- #endif
- namespace I2.Loc
- {
- public interface IResourceManager_Bundles
- {
- Object LoadFromBundle(string path, System.Type assetType );
- }
- public class ResourceManager : MonoBehaviour
- {
- #region Singleton
- public static ResourceManager pInstance
- {
- get {
- bool changed = mInstance==null;
- if (mInstance==null)
- mInstance = (ResourceManager)FindObjectOfType(typeof(ResourceManager));
- if (mInstance==null)
- {
- GameObject GO = new GameObject("I2ResourceManager", typeof(ResourceManager));
- GO.hideFlags = GO.hideFlags | HideFlags.HideAndDontSave; // Only hide it if this manager was autocreated
- mInstance = GO.GetComponent<ResourceManager>();
- #if UNITY_5_4_OR_NEWER
- SceneManager.sceneLoaded += MyOnLevelWasLoaded;
- #endif
- }
- if (changed && Application.isPlaying)
- DontDestroyOnLoad(mInstance.gameObject);
- return mInstance;
- }
- }
- static ResourceManager mInstance;
- #endregion
- #region Management
- public List<IResourceManager_Bundles> mBundleManagers = new List<IResourceManager_Bundles>();
- #if UNITY_5_4_OR_NEWER
- public static void MyOnLevelWasLoaded(Scene scene, LoadSceneMode mode)
- #else
- public void OnLevelWasLoaded()
- #endif
- {
- pInstance.CleanResourceCache();
- LocalizationManager.UpdateSources();
- }
- #endregion
- #region Assets
- public Object[] Assets;
- // This function tries finding an asset in the Assets array, if not found it tries loading it from the Resources Folder
- public T GetAsset<T>( string Name ) where T : Object
- {
- T Obj = FindAsset( Name ) as T;
- if (Obj!=null)
- return Obj;
- return LoadFromResources<T>( Name );
- }
- Object FindAsset( string Name )
- {
- if (Assets!=null)
- {
- for (int i=0, imax=Assets.Length; i<imax; ++i)
- if (Assets[i]!=null && Assets[i].name == Name)
- return Assets[i];
- }
- return null;
- }
- public bool HasAsset( Object Obj )
- {
- if (Assets==null)
- return false;
- return System.Array.IndexOf (Assets, Obj) >= 0;
- }
- #endregion
- #region Resources Cache
- // This cache is kept for a few moments and then cleared
- // Its meant to avoid doing several Resource.Load for the same Asset while Localizing
- // (e.g. Lot of labels could be trying to Load the same Font)
- readonly Dictionary<string, Object> mResourcesCache = new Dictionary<string, Object>(System.StringComparer.Ordinal); // This is used to avoid re-loading the same object from resources in the same frame
- //bool mCleaningScheduled = false;
- public T LoadFromResources<T>( string Path ) where T : Object
- {
- try
- {
- if (string.IsNullOrEmpty( Path ))
- return null;
- Object Obj;
- // Doing Resource.Load is very slow so we are catching the recently loaded objects
- if (mResourcesCache.TryGetValue( Path, out Obj ) && Obj!=null)
- {
- return Obj as T;
- }
- T obj = null;
- if (Path.EndsWith("]", System.StringComparison.OrdinalIgnoreCase)) // Handle sprites (Multiple) loaded from resources : "SpritePath[SpriteName]"
- {
- int idx = Path.LastIndexOf("[", System.StringComparison.OrdinalIgnoreCase);
- int len = Path.Length - idx - 2;
- string MultiSpriteName = Path.Substring(idx + 1, len);
- Path = Path.Substring(0, idx);
- T[] objs = Resources.LoadAll<T>(Path);
- for (int j = 0, jmax = objs.Length; j < jmax; ++j)
- if (objs[j].name.Equals(MultiSpriteName))
- {
- obj = objs[j];
- break;
- }
- }
- else
- {
- obj = Resources.Load(Path, typeof(T)) as T;
- }
- if (obj == null)
- obj = LoadFromBundle<T>( Path );
- if (obj!=null)
- mResourcesCache[Path] = obj;
- /*if (!mCleaningScheduled)
- {
- Invoke("CleanResourceCache", 0.1f);
- mCleaningScheduled = true;
- }*/
- //if (obj==null)
- //Debug.LogWarningFormat( "Unable to load {0} '{1}'", typeof( T ), Path );
- return obj;
- }
- catch (System.Exception e)
- {
- Debug.LogErrorFormat( "Unable to load {0} '{1}'\nERROR: {2}", typeof(T), Path, e.ToString() );
- return null;
- }
- }
- public T LoadFromBundle<T>(string path ) where T : Object
- {
- for (int i = 0, imax = mBundleManagers.Count; i < imax; ++i)
- if (mBundleManagers[i]!=null)
- {
- var obj = mBundleManagers[i].LoadFromBundle(path, typeof(T)) as T;
- if (obj != null)
- return obj;
- }
- return null;
- }
- public void CleanResourceCache()
- {
- mResourcesCache.Clear();
- Resources.UnloadUnusedAssets();
- CancelInvoke();
- //mCleaningScheduled = false;
- }
- #endregion
- }
- }
|