- Home /
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?
Answer by Bunny83 · Mar 15, 2017 at 04:55 PM
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.
Btw: "assets" in the sense of the engine have nothing to do with "files". Assets are packed into an assetdatabase that is made up by only a few package-files which contain all assets that have been included into the build.
If you want to know which assets actually made it into a build, check the build log report inside the editor log file after creating a build.
Answer by unityBerserker · Mar 15, 2017 at 06:41 PM
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:
Thanks. I just wanted to make a way and make sure that the designer added a manager and selected the gameasset file in a scene and if they failed to, the scripts could make sure of it. But because there isn't a way to load AssetDatabase during gameplay, I had to make sure the designer did those things with the help of custom editor windows :)
Do you know how work assetbundles? I'm not proficient with they but AFI$$anonymous$$ with them it should be possible. (If I understand what you want to do)
Here is example how to load data from disk:
http://answers.unity3d.com/questions/1030792/will-using-resourcesloadasync-to-load-prefabs-redu.html
Answer by Matt1000 · Mar 16, 2017 at 08:29 PM
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.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Excessive space in PropertyDrawer within Editor [ignore previous version of this question] 0 Answers
Initialising List array for use in a custom Editor 1 Answer
Reading level specific file in build (from another level) 0 Answers