Asset usability question

Hi, just wanted to get some perspective on a system I’ve been working on for the last month.

I’m creating a Sequence editor, something that can spawn objects, run events, evaluate curves and other things over time. However, for the past week I’ve been hitting many walls, all to do with serialization. Specifically, object references. After a weeks work I’ve got 2 solutions and was wondering what people would prefer.

Imagine an Object “Timeline” which contains 100 keyframes, each keyframe can have a reference to an object, both from the scene and project. Would you:

  1. Prefer these keyframes to be GameObjects, even though there’s no reason for them to be so? But “Timeline” can be saved as a prefab.
  2. Prefer these keyframes as ScriptableObjects. but “Timeline” cannot be saved as a prefab.

In both cases, Scene references are lost upon creating a prefab, but in the first case, the list of keyframes are preserved. ScriptableObjects are not saved to an object when it becomes a prefab unless they’re an asset. And if a ScriptableObject is an asset, it can’t reference Scene objects, even though the ScriptableObject parent is a scene object, ugh.

I’ve been struggling with this for a week and these are the only 2 solutions I can come up with. I prefer option 2 as it doesn’t require useless GameObjects, but having a potentially huge data structure that is only saved to a scene seems very flawed.

What do you guys think?

Hi CDF,

I can identify with the “weeks work” and “hitting many walls”. :stuck_out_tongue: Honestly, I don’t have much idea, but I like #1 better, since it sounds more useable, and tangible, while having less of a performance impact.

Any chance you can flush out what this does in more concrete terms or examples?

Lastly, you may get some better feedback if you post this in the “W.I.P” (Work In Progress) forum area. :smile:

Thanks. Didn’t know about the WIP forum, can any mods move this there?

So if you’ve created 1000 keyframes in your timeline, you would be happy with 1000 GameObjects in your scene?

This is a Spawn system, much like the Animation Window, except you don’t animate properties of an object, you animate Spawning of objects by creating keyframes. You can also add events, loop keyframes, randomness, movable transforms, and add curves which can control spawning/spawned properties (think difficulty over time).

Originally it was designed for an endless runner game, allowing you to create fixed levels with randomness while also being repeatable. But it could be used for creating waves in a shooter or something similar. Anything that requires events that happen over time.

It’s almost complete, I just need a way to enable people to reference scene objects. Something that seems so simple is so hard to do :(. I’m almost considering writing my own SerializedObject class with custom drawers so that I can hook up references based on some id value. Then I could ditch the ScriptableObjects and GameObjects and just use plain old system.Object, But that’s at least 1 month of solid 8hr day work.

Hi CDF,

Yes, I see your point about 1000 GameObjects in the scene… Hopefully a mod will move this for you. :slight_smile:

Ok I think I have a better solution. Inside “Timeline” GameObject create 1 child GameObject named “Data”. This “Data” GameObject contains all the Keyframe components, I get scene references and can create a prefab without 1000 gameObjects. However, I’ll have 1 gameObject which contains 1000 components :expressionless:

I struggled with this same thing about a year ago when creating Behavior Designer. I ended up doing my own serialization but Acegikmo recently made a post showing how objects are serialized. For your situation it sounds like you should go with ScriptableObject. To get around the issue where ScriptableObjects cannot be saved within prefabs you can save the ScriptableObjects individually within the prefab.

Thanks, the problem is references on a Scriptable Object, as soon as a ScriptableObject is added to an asset or prefab, it can no longer accept scene references. If the Scriptable Object is not part of another asset, but simply added as a property of another object it can accept scene references, but is not saved to that object. Very frustrating

You’ll always have that problem - even with regular GameObjects. Objects saved out in the project (via prefabs or .asset files) cannot reference scene objects. It does look like it serializes correctly when you initially save out a GameObject as a prefab which references an object within the scene, however when you restart Unity or try to actually build the project that reference will be gone. References to other Unity objects are only saved correctly if they are included in the same prefab/asset file as the script making the reference.

yep that’s what I would like to happen, show that the reference is bold indicating it’s not saved to the prefab. But these ScriptableObjects have many other properties associated with them, ints, floats, strings… The problem is the entire ScriptableObject is lost when saving the prefab if the ScriptableObject is not an asset. And if it is an asset, even with the prefab in the scene, scene references can’t be added to it, as I assume the reference to the ScriptableObject is the one inside the asset and not an instantiated version of itself.

If there’s some way to take properties from a ScriptableObject asset then apply them to an instance of a ScriptableObject, and vice versa. I’d love to know about it :slight_smile:

If ScriptableObjects parented to a prefab would Instantiate themselves upon creation my life would be so much easier. Like setting a hideFlag on the ScriptableObject, hideFlags = HideFlags.Instance, ensuring that whenever that object is created, it becomes an instance of itself and not the asset directly.

Ok, so another option, sigh.

for every keyframe, add an “asset” property, this “asset” points to an asset on disk which is of the same type.
Add a button “Save” to my EditorWindow, hitting that button goes through all scene assets and applies their changes to their disk assets. Of course scene references are lost, but other data is maintained.

Instantiating the “Timeline” will require going through its keyframe array and updating the values stored on disk.

So the scene is dealing with Instantiated ScriptableObjects at all times, they simply update properties on the disk asset when required. Downside is that hitting “Apply” will do nothing. I think I can get around the confusion a little if the disk assets aren’t actually part of a prefab, rather a “.asset” object. Kind of like an Animator and Animator Controller has 2 assets associated with it. 1 represents the data, the other represents the controller.

Good news, using a data asset works, and for some unknown reason Scene references are preserved when you copy the data from the asset into the ScriptableObject instance and vice/versa!