patterncsharpMinor
Inspector interface serializer
Viewed 0 times
serializerinterfaceinspector
Problem
I've written some code that allows Unity3D's inspector to display fields that conform to an interface. Unity has some quirks about their inspector, so as a preface they are listed here:
The code
UnityInterfaceHelper.cs
```
[Serializable]
public class UnityInterfaceHelperBase
{
[Tooltip("The component that is of the type required.")]
[SerializeField]
public Component target;
}
[Serializable]
public class UnityInterfaceHelper where TInterface : class
{
public TInterface TargetAsInterface
{
get
{
if (targetAsInterface == null)
{
targetAsInterface = target as TInterface;
}
return targetAsInterface;
}
set
{
if (targetAsInterface != value)
{
targetAsInterface = value;
if (val
- If you add a
[Serializable]attribute to a class, Unity's Inspector will attempt to show all public fields inside that class.
- Any class extending
Monobehaviourautomatically has the[Serializable]attribute
- Unity's inspector will attempt to display any private field with the
[SerializeField]attribute.
- Unity's inspector will not attempt to display generic types or interfaces, with the exception of
List, which is hard-coded.
- Unity's inspector will not attempt to display properties. A common workaround is to have a private backing field for your property with
[SerializeField]attached. Setters won't be called on the value set in the inspector. It's typically only set pre-compilation time, although a developer can modify values in the inspector during runtime. Currently it is acceptable to me to only take the initial value, although if anybody has a simple and efficient way to update successfully, I'd be happy to hear it.
- Unity has a
PropertyDrawerclass you can extend to control how a type is displayed in the inspector. ThePropertyDrawerfor an interface or generic type will be ignored.
The code
UnityInterfaceHelper.cs
```
[Serializable]
public class UnityInterfaceHelperBase
{
[Tooltip("The component that is of the type required.")]
[SerializeField]
public Component target;
}
[Serializable]
public class UnityInterfaceHelper where TInterface : class
{
public TInterface TargetAsInterface
{
get
{
if (targetAsInterface == null)
{
targetAsInterface = target as TInterface;
}
return targetAsInterface;
}
set
{
if (targetAsInterface != value)
{
targetAsInterface = value;
if (val
Solution
Possible bug:
If you get the value,
If you then get the value again, you'll get the old value of
If you get the value,
targetAsInterface is initialized. One can then set the value to something that is not a Component. Like null. If you then get the value again, you'll get the old value of
target recasted to TInterface. Seems to me that this violates what get and set are supposed to do.Context
StackExchange Code Review Q#65028, answer score: 3
Revisions (0)
No revisions yet.