Finding ScriptableObject file in GamePlay

Hi,

I have googled around a bit and didn’t find any good solution. I know that AssetsDatabase is only for UnityEditor so I won’t be able to use it on my project builds.

Is there any way where I can find a ScriptableObject .asset file by type during the start of the gameplay (in a MonoBehaviour script)? (without any references except the class name). The .asset file won’t be in a resources folder and it contains references to all other asset files. Or should I just make sure to manually select it within the Inspector for every scene?

Any kind of asset that isn’t either referenced from an included asset / an included scene or is inside a resources folder won’t be included into your build at all. It simply doesn’t exist. Unity only ships assets which are used somewhere. The only exception is the resources folder. Those assets are always included into a build.

So to answer your question: It’s not possible to access an asset that doesn’t exist. If you want to ensure that an asset is actually packed into your build you have to either reference it from somewhere or place it in a resources folder.

First disable Collapse option in console.

Here is piece of code giving ability to find assets in memory in editor. Add this script to editor folder.

	#region Find assets in memory

	[MenuItem ("Mein Menu/Find all assets of scriptableObjects loaded to memory", false, 90)]
	static void FindComponents ()
	{
		FindAssetInMemory (typeof(ScriptableObject));
	}

	static void FindAssetInMemory (System.Type typeOfAsset)
	{
		#region Lists with finded objects
		List<UnityEngine.Object> sceneMemoryInProfiler = new List<UnityEngine.Object> ();
		List<UnityEngine.Object> assetsInProfilerInAssetFolder = new List<UnityEngine.Object> ();
		List<UnityEngine.Object> notSavedInProfiler = new List<UnityEngine.Object> ();
		List<UnityEngine.Object> assetsInProfilerInUnityEditorResources = new List<UnityEngine.Object> ();
		List<UnityEngine.Object> builtinResourcesInProfiler = new List<UnityEngine.Object> ();
		#endregion
		UnityEngine.Object[] findedAssets = Resources.FindObjectsOfTypeAll (typeOfAsset);
		Debug.Log ("<b><size=15> <color=#0AA374>All objects of type  </color><color=#CD1426FF>" + typeOfAsset.ToString ().Substring (12) + "</color>" + "<color=#0392CF>: " + findedAssets.Length + "  </color> </size></b>");
		Debug.Log ("");
		#region Sorting

		foreach (var item in findedAssets) {
			string pathToAsset = UnityEditor.AssetDatabase.GetAssetPath (item);
			if (item.hideFlags == HideFlags.None && !pathToAsset.Equals ("") || pathToAsset.StartsWith ("Assets/"))
				assetsInProfilerInAssetFolder.Add (item);
			else if (item.hideFlags == HideFlags.None && pathToAsset.Equals (""))
				sceneMemoryInProfiler.Add (item);
			else if (item.hideFlags == HideFlags.NotEditable)//&& pathToAsset.StartsWith ("Resources/")
				assetsInProfilerInUnityEditorResources.Add (item);
			else if ((item.hideFlags & HideFlags.HideInInspector) != HideFlags.HideInInspector && pathToAsset.Equals (""))
				notSavedInProfiler.Add (item);
			else if (((item.hideFlags & (HideFlags.HideInInspector | HideFlags.DontSave)) == (HideFlags.HideInInspector | HideFlags.DontSave)) && pathToAsset.StartsWith ("Library/"))
				builtinResourcesInProfiler.Add (item);
			else if (item.hideFlags == (HideFlags.HideAndDontSave) && pathToAsset.StartsWith ("Library/")) // dla monoscript
				builtinResourcesInProfiler.Add (item);
		}


		#endregion
		#region Writing to console
		WriteListOfObjectsOfType (sceneMemoryInProfiler, "Scene Memory - gameObjects and components in loaded scenes: ");
		WriteListOfObjectsOfType (assetsInProfilerInAssetFolder, "Assets - assets in assets folder : ");
		WriteListOfObjectsOfType (assetsInProfilerInUnityEditorResources, "Assets - assets in editor Resources folder(unity installation path) and able to use: ");
		WriteListOfObjectsOfType (builtinResourcesInProfiler, "Builtin Resources (used to build editor): ");
		WriteListOfObjectsOfType (notSavedInProfiler, "Not Saved (used to build editor): ");
		#endregion
	}

	static void WriteListOfObjectsOfType (List<UnityEngine.Object> nameOfList, string description)
	{
		if (nameOfList.Count > 0) {					
			Debug.Log ("<b><size=15> <color=#B92CEFFF>" + description + nameOfList.Count + "</color></size></b>");
			Debug.Log ("");
			foreach (var item in nameOfList) {
				WriteElementToConsole (item);
			}
			Debug.Log ("");
		}
	}


	static void WriteElementToConsole (UnityEngine.Object item)
	{
		string pathToAsset = UnityEditor.AssetDatabase.GetAssetPath (item);
		Debug.Log ("<b><size=15> <color=#CD1426FF>" + item.name + "</color>" + "<color=#0392CF> HIDEFLAGS: " + item.hideFlags + "  </color>" + " " + "  <color=#0AA374>PATH: "
		+ pathToAsset + "</color></size></b>", item);
		//  <color=#F37736>MEMORY: " + UnityEngine.Profiling.Profiler.GetRuntimeMemorySize (item) + "</color><color=#0392CF>B</color> // you can check size in memory
	}

	#endregion

In place of asset you could any type of asset to see if it is added to memory. It’ s returning same as Detailed option in profiler.

What is important? FLAGS.

Just change few conditions in upper script for runtime.

Here is example how I find gameObjects or prefabs in runtime:

if (item.hideFlags == HideFlags.None && item.scene.rootCount > 0)

item.scene.rootCount>0 - find gameobjects in scene

item.scene.rootCount == 0 - find prefabs

In this same what you can sort any kind of assets but you must find conditions.

Here all type of wrappers(AFIK) for assets:

To be honest, the easyest and simplest way to do it is putting it into a Resources folder. If you dont want it to be in another folder but in your (for example) Enemies folder, simply create another Resources folder in your enemies folder and that wil work too (you can have as many Resources folders as you want).

Otherwise the only other posibility is to manually set it in the inspector (as a public variable). Just as with prefabs, either you put them in a Resources folder or you manually set them.