#scriptable objects
1 messages · Page 1 of 1 (latest)
making a thread
so, first, about the lifecycle of scriptable objects
ScriptableObject lets you define new kinds of assets.
that's why you usually have the [CreateAssetMenu] attribute on their declarations
for example...
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Localization;
public abstract class ConfigItem : Identifiable, IDescribable
{
[field : SerializeField]
public LocalizedString Label { get; private set; } = new("Config Names", "");
[field : SerializeField]
public LocalizedString Description { get; private set; } = new("Config Descriptions", "");
public ConfigCategory category;
}
wait this isn't an example lmao
this is an abstract class, so it can't be created
[CreateAssetMenu(fileName = "New Float Config Item", menuName = "Configs/Float Config Item"]
public class FloatConfigItem : ConfigItem
{
...
}
So, I have created several FloatConfigItem assets.
Just like any other kind of asset -- prefabs, materials, scripts -- I can reference them elsewhere
to be pedantic: if you have two components attached to game objects in two different scenes, both of those components can reference the same ScriptableObject asset
That's fine.
If you reference an asset from anywhere in a scene, the asset will be loaded when the scene loads.
in the situation you're describing, it'll also work like you expect
you'll be referencing the same object in both scenes
Once the object loads, it sticks around until you unload every scene that uses the asset.
So let's do a practical example
public class FloatHolder : ScriptableObject {
public float myFloat;
}
Say you have a reference to this in both Scene A and Scene B
Your component in Scene A does this:
holder.myFloat = 123;
Then you load Scene B.
The component in Scene B will see a value of 123 in holder.myFloat
because it's the exact same object
The "gotcha" is when you don't have a reference in Scene B
Scene A -> Scene B -> Scene A
when scene B loads, the object unloads
when scene A loads, the object loads again
and now the value is gone!
it's back to whatever the asset originally contained
If you log the instance ID of the object, you'll see that it changes
now, back to your question about dictionaries
I got around this problem by just making sure that the objects are never allowed to unload.
They can only unload when:
- no scene is using the Unity object
- you've lost every reference to the C# object
so, if you load a bunch of scriptable objects and stick them in a list, those objects will survive for as long as the list does
now, if that list was on a component in a scene, it would die when the scene unloaded
but if that list is stored in a static field, it will live forever
you'll always have a reference to the object, so it will never be allowed to unload
(a good chunk of the time it takes unity to change scenes is just it cleaning up all of the garbage!)
thank you again
i only need to store some prefabs that i want to acces from some scripts bc i dont want to have too many objects in every script.
i was worried that the file content will be deeted once i load another scene
but i understand now
what you meant when you said that the file will load again
thank you so much for guiding me through this!
Oh! Okay, so you aren't storing mutable data in there in the first place 😅
ha, well it's good to know anyhow. you're welcome!
I mostly use SOs for immutable data like that
also, here's a neat trick
using UnityEngine;
public abstract class SingletonSO<T> : ScriptableObject where T : SingletonSO<T>
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = Resources.Load<T>("SingletonSO" + "/" + typeof(T).Name);
}
return _instance;
}
}
}