Search Unity

[Best practice questions] Scriptable Objects and Prefabs reference

Discussion in 'General Discussion' started by Epic_Cube, Jan 3, 2018.

  1. Epic_Cube

    Epic_Cube

    Joined:
    Jul 3, 2012
    Posts:
    100
    Hi to all,
    I'm relatively new to Scriptable Objects and now I'm starting using them.
    As I understood, the Scriptable Object are perfect data storage solutions similar to table-based DBs.

    Anyway, they cannot replace prefabs at all (of course).

    Some questions:
    • Is it better to have a DB of Scriptable Objects referencing the prefabs to be instantiated at runtime or a set of prefabs that use the scriptable objects as data to be used?
    • Is there any difference in memory usage? I've looked around and I did not found many info about memory usage of prefabs and scriptable objects
     
    aaaavvvv likes this.
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Here are a few talks that might help to give a better understanding of ScriptableObject's...






     
    Last edited: Jan 3, 2018
    aaaavvvv and Ryiah like this.
  3. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,853
    That is hours of video. What is the skinny on using them condensed from the vids?
     
  4. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,659
    That London Unity User Group video is basically the same content as my talk at Unite Europe, btw - just an earlier, less-polished version of it.
     
    lyingturkey, CoCoNutti and Peter77 like this.
  5. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    Memory usage is a key reason for using them.

    I wouldnt call the manual page about them brilliant, but its not a bad intro and its short.

    https://docs.unity3d.com/Manual/class-ScriptableObject.html

    Personally I first noticed they existed when using the unity Post-processing stuff, and have more recently been inspired to use them for creating my own presets for one of my systems, with the bonus benefit of them retaining changes made in play mode in the editor.
     
    theANMATOR2b and Epic_Cube like this.
  6. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Thanks, I edited my post to reflect this info.
     
    superpig likes this.
  7. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    The approach I generally use for scriptable objects is to not link to them directly from prefabs but to have a master component that has references to all of the scriptable objects. I treat it more as a central database.
    So my component is called Catalog. and then I can just call Catalog.Items/Catalog.Abilities/etc.. You can make it a singleton I generally have base classes deriving from MonoBehaviour with protected methods that cache stuff like Catalog.

    Having it all self contained like that also makes it very easy to serialize everything for use on say a server.
     
  8. Epic_Cube

    Epic_Cube

    Joined:
    Jul 3, 2012
    Posts:
    100
    hi all and thx for replies,

    thx @elbows for the reference. Very useful explanation of memory usage of Scriptable Objects :)

    From the documentation, I understood that each Scriptable Object is loaded exactly once at game startup. I read that they are compiled as resource files, so, I suppose that they are actually loaded in memory when they are referenced for the first time in game, isn't it? Please tell me if I'm wrong.

    @superpig And what about scriptable objects non-referenced in the current scene?
    An example: in my project I have defined 10 scriptable objects, but in the current level I reference just 3 of them. The other 7 are anyway loaded at game startup, or are they loaded when referenced for the first time?

    And, on the other hand: what about memory usage of prefabs? I have read that every prefab is loaded at game startup as a inactive-zombie structure, that is actually cloned when you instantiate it from script. Same question of scriptable objects: the memory of the prefabs is always occupied at game startup, or just when they are referenced for the first time?

    @snacktime it's not always possible to have a unique, DB master component. To centralize all the data in an unique component that gives access to each Scriptable Object, looks like to have a unique singleton manager referenced by each component in game. It seems that one of the advantages of using scriptable object is to avoid an excessive centralization of references. Don't you think so? In your data model each script present in each prefab, must know the Catalog manager. Isn't it some kind of forcing?
     
    Last edited: Jan 4, 2018
  9. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    bowserscastle and Epic_Cube like this.
  10. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    The case against singletons has nothing to do with centralizing. Have a single coherent structure and api for data access is a good thing. The whole point of scriptable objects is a database of shared data that you don't have to tie to specific scenes or components.

    I was giving simple examples, note that I said I don't use singletons, and I also usually make all scriptable object fields private and provide a structured api to the data.
     
  11. Epic_Cube

    Epic_Cube

    Joined:
    Jul 3, 2012
    Posts:
    100
    @snacktime That's right. But one of the most convenient features of scriptable object is the possibility to edit them directly from editor. If you mark your fields as private, you will lose this possibility. Of course, if you need to populate the data set with mlilions of entries from code, it's another case :)

    @Peter77 I read that page too, and I agree in avoid using resources if not absolutely necessary.

    So, what about prefab memory usage? WHEN are they actually loaded in memory? Game startup? Scene startup? ...?
     
  12. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    No you don't lose the ability to edit them by marking them private. SerializeField is one route, custom editors are another.
     
    Plaximo and Rakesh6720 like this.
  13. Epic_Cube

    Epic_Cube

    Joined:
    Jul 3, 2012
    Posts:
    100
    yes I know... but look like pretty pesky... :p
     
  14. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Ya well pesky is the difference between bad/average and good developers.
     
    Meltdown likes this.
  15. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,659
    They behave like assets, so if they aren't referenced anywhere (and aren't packed into an AssetBundle or the Resources folder) then they won't be included in the build. If they're referenced in some other scene, they'll be loaded when that scene is loaded.

    As long as they're referenced by something in the scene (or by something that's referenced by something that's referenced by something that's referenced... etc) then I think they should be loaded when the scene is loaded.
     
    bowserscastle likes this.
  16. Epic_Cube

    Epic_Cube

    Joined:
    Jul 3, 2012
    Posts:
    100
    thx a lot :)
     
  17. Jacob_Unity

    Jacob_Unity

    Administrator

    Joined:
    Jan 2, 2017
    Posts:
    187
    Brackeys just did a video on Scriptable Objects:

     
    bowserscastle likes this.
  18. PabloIH

    PabloIH

    Joined:
    Sep 20, 2014
    Posts:
    12
    Yess, I do the same usually. It works, a centric ScriptableObject with other ScriptableObjects to manage audio, levels etc.
     
  19. DarkGate

    DarkGate

    Joined:
    Jan 26, 2016
    Posts:
    33
    Storing your data in a scriptable object ensures that your data is safe. Imagine for a second that you created hierarchal prefabs and stored all of your data in monobehaviors. One day, you mess something up in your script and your serialized data is forever lost into the void, I have had this happened to me several times. Having your data in scriptable objects ensures that this does not ever happen. In fact, you can even store your data as JSON and load that from a server if you wanted. Clear separation of data and behaviors is a good paradigm to follow.
     
    ritesh_khokhani likes this.