Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Instances of scriptableobjects and memory

Discussion in 'Scripting' started by Dezeris85, Dec 21, 2016.

  1. Dezeris85

    Dezeris85

    Joined:
    Dec 16, 2016
    Posts:
    15
    So I been watching videos on scriptableobjects and most videos gives the "pros and Cons" of them. And one pro was if you have 100 enemies instead of having each enemy with its own data that takes up memory you can have a scriptableobject with that data and those enemies all can refrence it.

    Now I was wondering if I have one of the instance of my scriptableobject but then change data with another script , like give it extra health. But dont change the other 99.. now does that instance have its own Data/memory? Since it differs from the rest. This could be a dumb question but couldnt help from wondering.
     
  2. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    I'm pretty sure there's no magic going on here. The pro that the videos are almost certainly referencing is the option to let multiple scripts share an instance of ScriptableObject. But if you go that route, then that simply means that all instances of those scripts are referring to a single chunk of memory. If any one of those scripts alters that memory (increasing health, for example), then all of the script instances will see that change.

    If you want a specific script instance to have a distinctly different amount of memory, then you'll need to explicitly clone the shared ScriptableObject, so that your one special script refers to its own copy and can alter that copy without affecting the original that everything else is still referencing.

    Addendum: The contrast is of course with putting the data in the scripts themselves, which means that a copy of all that data needs to be stored individually for each instance of the script. For things like current health, that's definitely appropriate, as you would expect each instance to potentially have a different current health value from all the others. Sharing instances of ScriptableOjbect is instead useful for things like max health, something you know won't change for all the various scripts that reference a particular copy of that ScriptableObject. If even max health can change on an individual level, then you'll need to further consider the details of how you want to store your data.
     
    Kiwasi likes this.
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,698
    This. ScriptableObjects are just regular old C# classes, with regular old C# instances. The only real magic is that ScriptableObject instances can be created and configured in the editor.

    They mislead you. This is not a pro of a ScriptableObject.

    The pros of a ScriptableObject are
    • Instances can be set up in the inspector and configured via the editor
    • Unity takes care of all of the serialisation for you
    • You can drag and drop instances
    I'm picking the cons were messed up to. The cons are
    • You can only use data types that are compatible with the inspector
    • Entering large amounts of data via the editor is difficult
    Sharing an instance of a data class between multiple other classes is something that can be done with ScriptableObject. But it doesn't have to be shared data. Nor is ScriptableObject unique in allowing instance sharing. You can do instance sharing with any instance.
     
    Duffer123 and AndyGainey like this.
  4. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    With the caveat that instance sharing with plain C# classes not inheriting from ScriptableObject only works during runtime (or as a temporary relationship during edit-time). If you setup a shared instance of such a class from an editor script on a MonoBehaviour field, it will get serialized and subsequently deserialized as a bunch of copies, not as a single instance with multiple scripts referencing it. This can be quite surprising to anyone who is more familiar with C#'s reference/value treatment of classes vs structs than they are with Unity's non-standard serialization process.

    If you want instance sharing that survives Unity's serialization, you must inherit from ScriptableObject. Similarly, and for related reasons, if you use inheritance and want to preserve the actual derived type of the instance, you need it to be a ScriptableObject. Otherwise, Unity will ignore the actual instance type and simply serialize and deserialize according to the field type, even if that is only a base class. Neither strikes me as useful behavior; if I wanted it to work that way, I'd have used a struct instead of a class.
     
    Kiwasi likes this.
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,698
    Very true.

    I'm the opposite, I'm far more familiar with how Unity's process works then how regular C# land works.
     
  6. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    Another con to ScriptableObjects is that Unity's serialization really sucks for any data structure that gets interesting at all. If you stick to primitives, you're fine, but, wait until you serialize a list of objects inheriting from an abstract base class...after pulling my hair out several times from bugs relating to Unity's serialization, I hate it. They need to burn their serialization to the ground and replace it with proper serialization.
     
    AndyGainey and Kiwasi like this.
  7. Dezeris85

    Dezeris85

    Joined:
    Dec 16, 2016
    Posts:
    15
    So should I be using scriptableobject(SO) for lets say... a city builder game and for building types and have a SO for structures and just make assests and change each assest variables (maintain cost, profit generated, etc) and load the data into a new instance with resourse.load () when making a new building.
    Would this be useful to make into a SO? Or just use c# classes and structs. Also if you wanted to save the game and need to save structure type and where its placed. Would xml be the choice for that? And does that handle SO instances?
     
    Last edited: Dec 22, 2016
    Duffer123 likes this.
unityunity