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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Question about ScriptalbeObject read/write speed vs Monobehaviour.

Discussion in 'Scripting' started by KaOzz, Oct 3, 2022.

  1. KaOzz

    KaOzz

    Joined:
    Oct 15, 2012
    Posts:
    82
    Hi, I want to ask if anybody knows if using ScriptableObject to store data to read/write in Update loops are less performant that read/write data from a Monobehaviour.

    Example using ScriptableObject:
    - I have a car and I want to have a speedometer for it.
    - I create a scriptableobject to read/write that speedometer value.
    - In every frame I will read and also write that value.

    Since ScriptableObjects live in disk, Im worried that this read/write in disk every frame can be less performant than read/write the value from a Monobehaviour that have a variable for the speedometer.

    Ok, the example is just for one gauge (speedometer). Imagine if I have a tons of gauges.

    So, questions:
    - When I update every frame (write a value data in scriptableobject), is this write in the disk at the same time?
    - If yes, will this cause performant issues compared to write on memory on a monobehaviour?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,962
    Sort of... fields that are eligible for serialization are written to disk, but this only happens at certain times, such as if you mark the object dirty, or play / stop happens, and potentially a few other places.

    If you're using SOs for storing numbers and passing them around, just mark the field that contains the data as [NonSerialized].

    IOW, I don't think you'd see any difference in performance, unless you're doing the things above.
     
  3. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,185
    ScriptableObjects are like other assets. They are stored on disk only until they are needed. Once needed they are loaded into system memory where they will be accessed from that point forward and don't leave memory until the application has ended.

    Once in memory they have most of the same performance characteristics as MonoBehaviours with the only major difference being in instantiation. An SO will be loaded into memory only once (unless you manually make copies) whereas an MB will be instantiated for every object it is a component of.

    While in the editor you can write to the original asset modifying it but once in a build that is no longer available and the only way it can be written to disk is through the code you write to handle saved data.
     
    Last edited: Oct 3, 2022
    Kurt-Dekker likes this.
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,196
    - doesn't matter
    - no

    For the simple reason that at runtime or in playmode, the scriptableobject will reside in memory only. Nothing gets written to disk at runtime on a ScriptableObject. (*)

    (*) There are ways to write SO to disk at runtime that require setup.
     
  5. KaOzz

    KaOzz

    Joined:
    Oct 15, 2012
    Posts:
    82
    Okey, its clear now for me. Thanks you all!
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,572
    I just want to point out that there's literally no difference between a ScriptableObject and a MonoBehaviour. On the native engine side a ScriptableObject is literally the same as a MonoBehaviour, just without a gameobject. On the managed side they are just two different .NET classes. The fact about serialization applies to both equally, though since they are usually used differently, this may be where the difference comes in.

    A MonoBehaviour attached to a gameobject that is a prefab, behaves the same as a ScriptableObject that is stored in an asset as well. Likewise an instantiated ScriptableObject (using Instantiate or CreateInstance) "lives" in the scene just like any other instantiated MonoBehaviour.

    So there's no real difference between ScriptableObjects and MonoBehaviour, just in the way you may use them. Before we got the CreateAssetMenu attribute it was a pain to work with scriptable objects as you always had to write editor code to create instances. (this was in the very beginning, years ago). At that time no one used ScriptableObjects but instead most were using prefabs instead. So an object in the scene would have a reference to a prefab asset and just use the values stored in that prefab without ever creating an instance in the scene. This was the layman ScriptableObject at the time. Since we can now easily create ScriptableObjects they are much lighter than creating a prefab and attaching a MonoBehaviour each time.

    Note: The Unity editor uses ScriptableObjects all over the place. Almost every editor class is derived from ScriptableObject (Editor, EditorWindow, SceneView, Tools, ...)
     
    MelvMay likes this.
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,622
    True. To add, the "MonoBehaviour" script has a "Script Type" internally and can be one of these:
    Code (CSharp):
    1.     kScriptTypeMonoBehaviourDerived = 0,
    2.     kScriptTypeScriptableObjectDerived = 1,
    3.     kScriptTypeEditorScriptableObjectDerived = 2,
    4.     kScriptTypeComponentDerived = 3
    It's MonoBehaviours all the way down. ;)