What youâre having Unity to do is store an instance of a running GameEventListener into the serializable field of a ScriptableObject, which is an asset on disk. This is just as invalid as dragging a scene instance object into a public field on a Prefab on disk: once you stop running, that on-disk scriptable object is now pointing at a dead object.
The difference is that the tutorial doesnât serialize that list. The ScriptableObject is an asset that lives in the project files- it is not specific to any given scene, and cannot serialize scene references and maintain them between you pressing play/stop or building the application. It can be used by scene objects, but only for the duration that the scene is actually running, and never in a way that itâll properly display its registered listeners in the inspector.
By serializing this list, youâre trying to use it in a way that has no logical way of working. Just leave the [SerializeField] off, and it should work just fine, so long as you donât expect it to maintain the list between sessions.
Incase anyone else has this problem like I did, to expand on what DonLoquacious said, you canât serialize the fields, and this includes marking it public I believe. So for me instead of not including [SerializeField] I had to make it private readonly.
Iâve been trying to leverage ScriptableObjects to avoid having to roll my own serialized data system, and for the most part theyâre working. However Iâve run into a similar issue where property fields that reference GameObjects arenât persisting (âMissingâ or âType Mismatchâ) if close and re-open the editor despite even setting dirty manually.
If iâm understanding correctly, ScriptableObjects canât store references to GameObjects in the hierarchy of a scene.
As an aside:
It would be awesome if unity would serialize object references as [Scene].[Object] and display a message to the developer indicating that the referenced princess component is in another castle scene.
I have a feeling iâm going to need to create another custom editor, this time one that shows the GameObject field, but extracts a GUID from it and stores the GUID in the ScriptableObject for use with a scene specific lookup table laterâŚ
For anyone else who followed the same tutorial as above, it lists the references as Type mismatch in the RuntimeSet but still works. If you look at the example project (provided with the video), his example does the same thing.
Sorry for necroing but I find this very interesting and deserving of discussion.
What are the drawbacks of using a ScriptableObject as a runtime storage for non serializable data?
For instance I can assign a transform from the scene to a Transform field inside a SO asset, this works but it does say âType mismatchâ - even though I can click on the field and the correct transform is pinged in the scene hierarchy, so itâs clearly working. Tested it in builds on a couple devices as well and havenât noticed anything to indicate otherwise.
Thereâs mentions in this thread of storing/serializing dead pointers here, which seems a valid drawback - from my testing Unity does flush these dead pointers when e.g. restarting editor etc. and I have not gotten any errors or warnings about this (except the Type mismatch indication inside the field itself).
I mean it does seem like an extremely handy way of managing runtime variables but Iâm a bit cautious. Anyone got any more knowledge on this?
There are not really any issues when doing that. In a build game the serialized asset data can not be changed permanently anyways. So after restarting the game all the data is back as it was when you shipped the game. Assigning references to objects (UnityEngine.Object derived objects) which are destroyed later essentially always have the same result: When the object with that reference gets serialized, that reference will simply become null.
Just to clarify the Unite Talk of Ryan Hipple that was mentioned above: They used ScriptableObjects for almost every game data. So there never was any need to reference into the scene because all relevant data was stored as assets. So even runtime values / objects were stored as assets in the project. This allowed scenes and other assets to reference each other without any problems. If you have no idea what I just said, I recommend to watch that Unite talk.