SerializeField and default value optimization


I want if SerializeField has default value then remove in yaml field.
or can I use SerializedProperty to cast value dynamically (like thing)?

for example :

# (scene asset or prefab, asset, etc...)
...yaml data...
  items:
  - value: 157899130
...yaml data...
SerializedProperty v = serializedObject.FindProperty("value");
Debug.Log(v.stringValue);             //returns 157899130 as string value.
Debug.Log(v.objectReferenceValue);    //returns 157899130 as referencing UnityEngine.Object from fileID.

The reason I need this…


I want to create an RPGmaker-style event editor that is flexible and easy to edit.

However, SerializeField always has a fixed size and specification. I know this can be safe for type definitions. But I want to use it flexibly.

I wanted to use the int, string and ObjectField to refer to a scene or prefab. so that it could be edited and applied freely in the editor script, but unfortunately, SerializeField was hard to make it light because it strictly adheres to the specified standard as mentioned above.

At first I tried to create multiple classes that inherit one class to solve this, but it can
parent class only to be serialized.

So the second time I tried to make it using only string values. I was able to easily cast values such as int, float Vector3, etc. to a string.
But it was too difficult to implement the fields that reference UnityEngine.Object.

3456308--273984--커스텀_에디터.gif
So as a last resort, I created and assigned a class with multiple values (int, string, Vector3, UnityEngine.Object, never custom class).
I succeeded in implementing what I wanted but, the problem is that fields that are not used are also serialized, which can make them heavy.

I am looking for a way to figure out how to solve this.

have any solution?

Not really a solution to your problem, but you don’t need [SerializeField] on public fields, Unity serializes public fields by default (assuming the type of the field is already a serializeable type, which all value types, monobehaviours/components, lists/arrays and classes marked System.Serializeable are.)

I’m not quite fully understanding from a technical standpoint what you’re trying to do, but from what I’m assuming, I would think implementing Interfaces to share a common interaction method between classes might be what you’re looking for instead?

hello, Invertex

okay, so conclusion is…

  1. one SerializeProperty can use flexable type? (in unity possiblly types. UnityEngine.Object, Vector3, float, string…)

  2. if first question can not do then, can use string to refer scene object or prefab(by yaml’s fileID) in editor script?

  3. if second also can not do then, can hide value in yaml if it’s default value?

I still can not delay development, so I decided to use last thing. (multiple fields [int, float, bool, string, Vector series, UnityEngine.Object] in one serialize class)

but, I wish someone had a good answer to this problem though.

3457039--274062--1523376746187.GIF
this is my WIP of event editor.

(first item is delay event)
(second item is dialog text event)

I’ll make it to possible this video’s senario.

So if I’m understanding correctly, you want to build a list of non-homogenous data entries on a ScriptableObject? This is possible, although a little involved to set up:

  1. Make an abstract base class that derives from ScriptableObject (BaseEvent)
  2. Create the various ___Event classes (derived from it), which can have different serialized fields.
  3. EventStack holds a list of BaseEvent.

So that would do it, functionality-wise, but there’s two problems - you have to create each event as a separate asset, and they show up as links in the inspector rather than embedded.

Solution: custom inspector. From the picture it looks like you already have one, but if you need any information I found the tutorial at Custom List, a Unity C# Editor Tutorial to be quite helpful. For the two things:

// Create object as sub-asset
// You can decide type to add in various ways.  I used a drop-down that was populated by reflection.
var newEvent = ScriptableObject.CreateInstance(type) as BaseEvent;
newEvent.name = "Something descriptive is convenient for debugging, but it doesn't matter";
self.events.Add(newEvent); // self is the EventStack
AssetDatabase.AddObjectToAsset(newEvent, self);
...
UnityEngine.Object.DestroyImmediate(deletedEvent, true);  // Make sure to destroy when removing from the list
// Draw ScriptableObject embedded rather than a link to it
Editor innerEditor = Editor.CreateEditor(event, typeof(BaseEventEditor));
innerEditor.OnInspectorGUI();
// BaseEventEditor doesn't need to do anything special, it can just have the default behavior if you want.

Edit: Looking at your post again, if space-efficiency is your goal, this won’t do it; the extra overhead from a SO is probably more than the extra fields unless you start having a significantly large number of different parameters needed. I find it useful since it requires no further changes to support new subtypes though.

In terms of storing an object reference as a string, the GUID would be enough info to find it in the editor. For runtime I think you’d need an index object holding direct references to anything soft-referenced this way.

1 Like

Hello, Errorsatz.

You understand exactly what I want to do!
This answer is close to what I want.
When I get home, I will try it.

Thank you very much, I can’t wait for try this!

it’s works good as well and better then previous style.

List

first element is Parent class, List has reference this class.

second element is typeA child class, it’s contains string and UnityEngine.Object field.

third element is typeB child class, it’s contains Vector3 and UnityEngine.Object (using Transform) field.

Finally, I would like to question about how to reference UnityEngine.Object as a string.
Is there really only a way to create a prebuilt list in a different class, find the destination in a string in it, and then reference it?

Is there no way for referencing by using yaml’s fileID as string?

Oh, I missed Edited comment.
so, is already used solution(one class, multiple field) is a better way?

ehh it’s so hard to decide better way.

Over time, I thought about various things.
i think, the ‘single class, multi-field’ solution will probably have a memory problem at runtime. but space-efficiency will be good for editor.
And, ‘ScriptableObject’ solution may not editor friendly, but i think it’s will be better in runtime.

is this right…?

ScriptableObject is quite editor friendly, especially once you implement this:

1 Like

thanks, Invertex!

Ehh, I had another problem about ScriptableObject in the scene asset.

3461348--274526--1.PNG
While editing in the editor window works fine.

objectReferenceValue returns null because Unity can not find the ScriptableObject hidden in the scene data on the system when it first attempts to load or test the project.

3461348--274529--3.PNG
3461348--274527--2.PNG3461348--274530--4.PNG
Open project or start testing then will it happened.

how can I do alternative to use ScriptableObject for scene asset friendly? (class override possible)