Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Storing data to be accessed from code at runtime

Discussion in 'Scripting' started by liortal, Jun 22, 2014.

  1. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    Hi all,

    I have a scenario where a non-MonoBehaviour derived class needs access to data at runtime.
    This data may be simple strings, but can also be GameObject references, AudioClips, etc.

    It would be ideal if i could <somehow> have an asset in my Project that i could query to check out its fields for the required data.

    One solution could be to create a Prefab and add it to the scene. The prefab would be located using GameObject.Find and then i could gain access to a component on it that would store all the data.

    This is a bit "messy" as multiple prefabs would be needed at runtime, and so i would have to place multiple prefabs in the scene (not sure if that's a best practice in Unity).

    What could be other solutions to this issue? I was looking at ScriptableObjects but i am not 100% sure how to sue these and how could i create these with the data associated to them (e.g: drag GameObject references to them in the inspector at edit-time) and then load them at runtime.

    What other possible solution can i use?
     
  2. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    I personally would use scriptable objects. Simply derive your types from them and store instances of those to disk.

    Code (CSharp):
    1. public static void CreateAsset<T>() where T : ScriptableObject {
    2.             T asset = ScriptableObject.CreateInstance<T>();
    3.  
    4.             string path = AssetDatabase.GetAssetPath( Selection.activeObject );
    5.             if( path == "" ) {
    6.                 path = "Assets";
    7.             } else if( Path.GetExtension( path ) != "" ) {
    8.                     path = path.Replace( Path.GetFileName( AssetDatabase.GetAssetPath( Selection.activeObject )), "" );
    9.                 }
    10.  
    11.             string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath( path + "/New " + typeof(T).ToString() + ".asset" );
    12.  
    13.             AssetDatabase.CreateAsset( asset, assetPathAndName );
    14.  
    15.             AssetDatabase.SaveAssets();
    16.             EditorUtility.FocusProjectWindow();
    17.             Selection.activeObject = asset;
    18.         }
    This does simply store the scriptable object to the path in your project wizard where you do have an asset selected.

    Now to proceed, store them in your Resources/ folder so you can simply load them by name at runtime via Resources.Load
     
  3. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    Why isn't there a built-in way of instantiating a ScriptableObject asset from the editor ? or is there?
     
  4. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    Code (csharp):
    1. ScriptableObject.CreateInstance<T>();
    Use this to instanciate, and my above code to store it.

    As of why it is not given by default, it somehow is. Its just way to trivial to store whatever object in the asset database to make it special to scriptable objects.
     
  5. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    How do i create an ScriptableObject asset and store it in the AssetDatabase, except for doing it from code?
     
  6. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    There is no other way as far as I know.