In my game development, for the convenience of debugging, I implemented some special classes to serialize data structures (such as dictionaries, object, etc.) and display them on the Inspector panel But this display is only for the convenience of viewing data on the Inspector panel, not for serializing data. These data structures will only be generated during game runtime For example:
#nullable enable
using System;
using UnityEngine;
/// <summary>
/// Used to display interface types inherited from UnityObject
/// </summary>
[Serializable]
public struct UnityObjectInterface<T> where T : class
{
public UnityObjectInterface(T value) : this() => Value = value;
[SerializeField] private UnityEngine.Object? value;
public T? Value
{
get
{
if (value != null && value is T t) return t;
value = null;
return null;
}
set
{
if (value is UnityEngine.Object o) this.value = o;
}
}
}
public interface ITestInterface
{
void Tick();
}
public class TestMono : MonoBehaviour
{
#if UNITY_EDITOR
[SerializeField] private UnityObjectInterface<ITestInterface> testInterface;
public ITestInterface? TestInterface
{
get => testInterface.Value;
set => testInterface.Value = value;
}
#else
public ITestInterface? TestInterface { get; set; }
#endif
private void Awake()
{
TestInterface = GetComponent<ITestInterface>();
}
private void Update()
{
TestInterface?.Tick();
}
}
But there is an question here. In editor mode, Unity will serialize many additional data structures according to the script in the editor model, but these data structures are meaningless at runtime, resulting in some useless fields in the. asset file, such as:
(the first is the. asset file in editor mode; the second is the. asset file that should appear in runtime mode)
I know keeping these meaningless fields in the. asset file is to prevent a script change from causing all objects to be modified But I have two questions about this useless field
Because I extensively use this type of serialized display object in my game (of course, they are all empty), will these useless fields affect performance during serialization and deserialization?
If such useless fields will have a certain impact on performance, I would also like to ask, will all files be checked during Unity packaging, and will useless fields be removed before packaging?
I mean if you don’t need this data at runtime why serialise it into the asset in the first place? If you want to view data in a certain way for convenience, use a custom inspector for that instead.
Yes. More stuff to serialize/deserialize => more work => less performance. How much less is completely dependent on how many of these that’s around.
What do you mean by “packaging” here? Builds?
Anyway, it depends. For more recent versions of Unity (at least 2021 or later), you can have serialized fields behind #if UNITY_EDITOR, and the data from those fields will not be included in builds. In earlier versions that caused bad errors due to a different set of fields existing when building and running.
So in your example, the serialized data will not exist, so the size of your TestMono will be lower in builds than in editor, and accessing your TestInterface will be faster in builds than in editor due to one less indirection.
That being said, this level on genericism and abstraction is often not a very good idea, and will lead to very simple things being very convoluted and hard to understand. So consider if just referencing the things you need without a InterfaceWrapper? is a lot better for everyone involved - yourself, the reader, and the computer. It probably is.
I know you can customize the Inspector panel, but for example, in the example in my code above, I would like to see which UnityObject my interface references. This cannot be done by the default mechanism of Unity I cannot accomplish this by simply rewriting a PropertyDrawer Rewriting the UnityObject Editor to display objects in these interfaces would be too cumbersome (as it requires handling display issues in nested classes)
Although using plugins such as Odin can easily solve these problems, these plugins are all paid for
There’s completely free and open-source TriInspector which has essentially the same functionality as Odin when it comes to attributes and validation.
You should not serialize data to runtime asset files which you would like to exclude in a build. This can cause many other issues as well as the data layout of the serialized data suddenly changes.
So instead of serializing data you don’t actually want to be serialized, you may just want to implement a property drawer which you can simply add to any actual serialized field to add arbitrary unrelated gui to your inspector. You can use custom PropertyAttributes to provide context (like the name of a field) and use reflection in the drawer to do whatever you want. That way you don’t add anything to the serialized data.
On the other hand, when you’re working with interfaces, you might want to check out my SerializableInterface struct. It actually allows you to drag and drop objects (Monobehaviours or ScriptableObjects) which implement the given interface and have that reference serialized. That way you don’t need to use any GetComponent call but you do have direct access to the interface. The getter does do the casting on the first access for you.
Note that usually a DecoratorDrawer would be better, however Unity unfortunately doesn’t provide any context (SerializedProperty) to a decorator which makes decorators almost useless as they have no way to access the serialized class or property. However PropertyDrawers could simply be chained. So a PropertyDrawer can actually use EditorGUI.PropertyField itself to draw the next drawer so the actual field isn’t affected. You should need to manage your property height accordingly to include your “decoration”. Of course another approach would be a generic custom inspector which does react to your own attributes or directly handles the display of certain things that aren’t serialized.
As others have suggested, things like Odin do exactly those things. Of course you can always roll your own approach, but getting it right takes quite some time, knowledge and skill.
Messing with serialized data that shouldn’t be serialized in the first place is never a good approach, though.
may I present you Runtime Inspector
it’s a free asset that I heavily used for our game editor, which is really complex. you should be able to configure it to only show what you need, I don’t know if new versions have more granular display filtering options, as I have an older one, but that’s where I’d start.