Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

[Resolved] When reference asset from scriptableObject is load and unload from memory ?

Discussion in 'Scripting' started by DungDajHjep, Sep 14, 2018.

  1. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203
    update: real device work like @fogsight talk, all asset have a reference to a scriptableObject will start loading when you load a scene have a reference to this scriptableObject. it's unload when you load a scene with no reference to scriptableObject.
    So feel free to do anything with scriptableObject

    [Origin]
    I plan to make a PoolSystem base on ScriptableObject but im not sure when scriptable object is loading, anyone know about it ?

    in unity document scriptable call OnEnable when it's load, but on editor it's call alway when me edit and recomplie script, on Play Mode it's alway call OnDisable first and call OnEnable after, it's so confusing.

    first scene menu is no ref to scriptableObject, i mean all ref asset only loading on scene ref to it loading or on start program ??

    Capture.PNG
     
    Last edited: Sep 16, 2018
    Sarai and CyrilGhys like this.
  2. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    A scriptable object does not destroy on scene change like a Monobehaviour would. So if you have a scriptable object with references to monob instances those will point to destroyed monobs after scene change.
     
  3. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203
    not really understand but scriptableObject is a var in Monobehaviour, scriptableObject not ref to Monob, Mono is ref to scriptableObject
     
  4. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    You're going to want to look into DontDestroyOnLoad() and LoadSceneAdditive. I've also been told that you can create a file and store your assets for the next scene there. Then reference a list to retrieve, but I've never tried it myself. Sounds legit though ;)
     
  5. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203


    now i know how to test it
     
  6. Suduckgames

    Suduckgames

    Joined:
    Nov 28, 2016
    Posts:
    218
    Scriptable objects will remain in the memory for the lifetime of the app. They are loaded at the begin of the application. So they persist across scenes. however the monobehaviour will be destroyed, so If you have references to monobehaviours from scriptable objects, they will be losed
     
  7. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203
    oh, someone dont think same you

    i ask on discord:

     
  8. fogsight

    fogsight

    Joined:
    Apr 6, 2010
    Posts:
    65
    In this case, I believe, Scriptable Object is not loaded in the first scene because it's not referenced. It's loaded with the next one. And if you dereference it, it can be cleaned up with Resources.UnloadUnusedAssets() even if GC won't get to it.
     
    Sarai and DungDajHjep like this.
  9. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Where do you go in Unity to find this?
     
  10. fogsight

    fogsight

    Joined:
    Apr 6, 2010
    Posts:
    65
  11. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    That was a great read! I'm curious about the WebGL. Is that like an emulator?
     
  12. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Lets clear some things up.

    Code (CSharp):
    1. public class MySO : ScriptableObject
    2. {
    3.    [SerializeField]
    4.    private  MyMonoB[] myBs;
    5. }
    you save a instance of this as Resources/MySo.asset and drag and drop MonoB prefabs to this instance.

    At runtime you can do

    Code (CSharp):
    1. var singleton = Resources.Load("MySo");
    This will point to the actual asset reference and the array will point to each Prefab (not a instance of a prefab).

    This is most often not the effect you want, you instead do

    Code (CSharp):
    1. var instance = Object.Instantiate(Resources.Load("MySo"));
    Now you have a instance copy of the MySo.asset. But the array of prefabs will still Point to the prefabs. This also is most often not the case you want.

    So in the ScriptableObject instead do

    Code (CSharp):
    1. public class MySO : ScriptableObject
    2. {
    3.    [SerializeField]
    4.    private  MyMonoB[] myBPrefabs;
    5.    private IEnumerable<MyMonoB> instances;
    6.  
    7.    protected virtual void Awake()
    8.    {
    9.       instances = myBPrefabs.Select(prefab => Object.Instantiate(prefab)).ToList();
    10.    }
    11. }
    Now you will have a copy of the asset AND copies of the monob prefabs. Keep in mind the instances will not be destroyed on scene load so you need to fix that yourself

    Edit: typo, the prefab instaces will be destroyed but not the scrtipable object so it will point to destroyed instances
     
    Last edited: Sep 14, 2018
    DungDajHjep and MisterSkitz like this.
  13. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203
    update:
    need test again on real device

    update 2:
    real device work like as @fogsight talk
     
    Last edited: Sep 16, 2018
  14. DouglasPotesta

    DouglasPotesta

    Joined:
    Nov 6, 2014
    Posts:
    109
    I’m pretty sure they shouldn’t be loaded when the application starts unless they are in the resources folder.
     
  15. fogsight

    fogsight

    Joined:
    Apr 6, 2010
    Posts:
    65
    Bear in mind that profiler shows everything loaded including the editor's memory. You need to look at the list who references it in the profiler.
     
  16. fogsight

    fogsight

    Joined:
    Apr 6, 2010
    Posts:
    65
    They also shouldn't be loaded if they are in Resource folder. Anything in Resource folder just always gets compiled in the build, referenced or not. It is mainly used to load into memory dynamically. But AssetBundles are much more practical for that purpose.
     
  17. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203
    please make a simple test with profiler and show your result
     
  18. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    I did some tests on the Awake method on a SO in the Resources folder. In editor the Awake trigger when you create the SO, then it will not trigger again when you start the game from Play button or when you do Resources.Load on it since its already loaded. If you restart the editor it probably will run first when you focus the .asset or run the game and do a Resources.Load on it, but didnt try.

    When the game is built the Awake method runs first when you do Resources.Load on it. So it does not run directly as suggested in this thread. If you do Object.Instantiate(Resources.Load("MyTest")) it will run twice, first for the Loaded SO and then for the instance.

    Resources.Load caches the object so any subsequent calls to Resources.Load will return the same reference and the Awake will not be called
     
  19. fogsight

    fogsight

    Joined:
    Apr 6, 2010
    Posts:
    65
    2018-09-15_14-23-20.png
    @DungDajHjep I'm not not sure what test are you after. This is how Scriptable Object asset instance looks when it is referenced, if you dereference it, it will be null. (if you are launching the editor for the first time and it's not been referenced yet, you won't see it in assets here at all, only after you reference it at least once, profiler will keep track of it in memory.) If you instantiate SO at runtime, its clone will appear in the scene memory.

    Again, all these objects are in memory because editor is referencing them, or has in the past at least once, during this run. If you want to judge if something will be in the memory in build version, you can do that by looking if they were referenced or not. You can also create a build with Development mode on and "Autoconnect profiler" option on and look at the actual application memory at runtime.
     
    DungDajHjep likes this.
  20. DungDajHjep

    DungDajHjep

    Joined:
    Mar 25, 2015
    Posts:
    203
    @fogsight thanks for help, i will test it again

    update: real device work like @fogsight talk, all asset have a reference to a scriptableObject will start loading when you load a scene have a reference to this scriptableObject. it's unload when you load a scene with no reference to scriptableObject

    So feel free to do anything with scriptableObject
     
    Last edited: Sep 16, 2018
  21. fogsight

    fogsight

    Joined:
    Apr 6, 2010
    Posts:
    65