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

update: real device work like @fogsight1 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 ??

3676783--301840--Capture.PNG

2 Likes

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.

not really understand but scriptableObject is a var in Monobehaviour, scriptableObject not ref to Monob, Mono is ref to scriptableObject

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 :wink:

now i know how to test it

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

3 Likes

oh, someone dont think same you

i ask on discord:

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.

2 Likes

Where do you go in Unity to find this?

@Tim-Duval Unity - Manual: The Profiler window

1 Like

That was a great read! I’m curious about the WebGL. Is that like an emulator?

Lets clear some things up.

public class MySO : ScriptableObject
{
   [SerializeField]
   private  MyMonoB[] myBs;
}

you save a instance of this as Resources/MySo.asset and drag and drop MonoB prefabs to this instance.

At runtime you can do

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

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

public class MySO : ScriptableObject
{
   [SerializeField]
   private  MyMonoB[] myBPrefabs;
   private IEnumerable<MyMonoB> instances;
 
   protected virtual void Awake()
   {
      instances = myBPrefabs.Select(prefab => Object.Instantiate(prefab)).ToList();
   }
}

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

2 Likes

update:
need test again on real device

update 2:
real device work like as @fogsight1 talk

I’m pretty sure they shouldn’t be loaded when the application starts unless they are in the resources folder.

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.

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.

please make a simple test with profiler and show your result

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


@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.

1 Like

@fogsight1 thanks for help, i will test it again

update: real device work like @fogsight1 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