Last active
March 17, 2021 16:16
-
-
Save ababilinski/afd46e9f7752bb352380177737b12e96 to your computer and use it in GitHub Desktop.
Abstract class for making reload-proof singletons out of Uniy3D ScriptableObjects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using UnityEngine; | |
/// <summary> | |
/// Abstract class for making reload-proof singletons out of ScriptableObjects | |
/// Returns the asset created on editor, null if there is none | |
/// Based on https://www.youtube.com/watch?v=VBA1QCoEAX4 | |
/// </summary> | |
/// <typeparam name="T">Type of the singleton</typeparam> | |
public abstract class SingletonScriptableObject<T> : ScriptableObject where T : ScriptableObject | |
{ | |
static T _instance = null; | |
public static T Instance | |
{ | |
get | |
{ | |
if (!_instance) | |
_instance = FindAsset(_instance); | |
return _instance; | |
} | |
} | |
/// <summary> | |
/// We have to find the asset through AssetDatabase in case the asset is not loaded. | |
/// </summary> | |
/// <typeparam name="TO"></typeparam> | |
/// <param name="typeObject"></param> | |
/// <returns></returns> | |
public static TO FindAsset<TO>(TO typeObject) where TO : Object | |
{ | |
#if UNITY_EDITOR | |
if (UnityEditor.EditorPrefs.HasKey(typeof(TO).ToString())) | |
#else | |
if (false) | |
#endif | |
{ | |
#if UNITY_EDITOR | |
string objectPath = UnityEditor.EditorPrefs.GetString(typeof(TO).ToString()); | |
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath(objectPath, typeof(TO)) as TO; | |
if (asset == null) | |
{ | |
var assets = UnityEditor.AssetDatabase.FindAssets("t:" + typeof(TO)); | |
if (assets.Length > 0) | |
{ | |
var assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(assets[0]); | |
var foundAsset = (TO)UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, typeof(TO)); | |
UnityEditor.EditorPrefs.SetString(typeof(TO).ToString(), assetPath); | |
return foundAsset; | |
} | |
} | |
else | |
{ | |
return asset; | |
} | |
#endif | |
} | |
else | |
{ | |
#if UNITY_EDITOR | |
var assets = UnityEditor.AssetDatabase.FindAssets("t:" + typeof(TO)); | |
if (assets.Length > 0) | |
{ | |
var assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(assets[0]); | |
var foundAsset = (TO)UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, typeof(TO)); | |
UnityEditor.EditorPrefs.SetString(typeof(TO).ToString(), assetPath); | |
return foundAsset; | |
} | |
#endif | |
var asset = Resources.FindObjectsOfTypeAll<TO>().FirstOrDefault(); | |
if (asset != null) | |
{ | |
#if UNITY_EDITOR | |
string relPath = UnityEditor.AssetDatabase.GetAssetPath(asset); | |
UnityEditor.EditorPrefs.SetString(typeof(TO).ToString(), relPath); | |
#endif | |
return asset; | |
} | |
} | |
return default; | |
} | |
} |
UPDATE
updated the way the asset is found. I had issues with the asset not loading in the editor and having to select the asset in order for the return value not to be null
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Abstract class for making reload-proof singletons out of ScriptableObjects
Returns the asset created on editor,
null
if there is noneBased on Unite 2017 Video