Inspector中的自定义组件
将属性暴露到Inspector
自定义组件中的属性可以被暴露到Inspector,什么组件会被暴露到Inspector面板由设计这个组件的程序员决定。
实现这个组件,将它挂到任意一个GameObject上,观察Inspector中这个组件可以配置的属性:
public class InspectorTest : MonoBehavior
{
public int publicProperty;
private int privateProperty;
protected int protectedProperty;
internal int internalProperty;
}
可以发现,只有使用public限定词的属性才能被暴露到Inspector面板。但是为了将属性暴露到Inspector面板,就不得不将一些访问权限不应该为public的属性写为public,这会破坏类的封装性。同时,为了提供一些接口,我们不得不将访问权限为public的属性暴露到Inspector面板,这又会让Inspector面板变得乱糟糟。为了解决这两个问题,我们引入了两个新Attribute——SerializeField和HideInInspector。实验这些Attribute,将上面的组件改写,再次观察Inspector面板中的属性:
public class InspectorTest : MonoBehavior
{
[HideInInspector]
public int publicProperty;
[SerializeField]
private int privateProperty;
[SerializeField]
protected int protectedProperty;
[SerializeField]
internal int internalProperty;
}
果然,具有SerializeField标签的属性被强制暴露到了Inspector,而具有HideInInspector标签的属性则被强制从Inspector中隐藏了。同时我们还发现,在Inspector中属性的排列顺序和脚本中属性的定义顺序是一致的。
实现下面的组件,将其附加到任意GameObject,观察Inspector中暴露的属性:
public class InspectorTest2 : MonoBehaviour
{
public int normalProperty;
public int functionalProperty { get; private set; }
public readonly int readonlyProperty;
public static int staticProperty;
public const int constProperty = 0;
}
可见,readonly、static、const等关键词都会阻止属性暴露到Inspector,同时,函数化的属性也不能被暴露到Inspector。
属性在Inspector中的形态
实现下面的组件,将其附加到任意GameObject,观察Inspector中暴露的属性:
public class InspectorTest3 : MonoBehaviour
{
public int m_int;
public float m_float;
public char m_char;
public bool m_bool;
public string m_string;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RBRG9R9l-1569859801126)(C:\Users\UPiracy\AppData\Roaming\Typora\typora-user-images\1568477288182.png)]
显然,数值类型可以输入数字,字符类型可以输入字符,布尔类型是一个勾选框,而字符串则是一个文本输入框。
注:在Unity中声明以"m_"作为前缀的属性时,暴露到Inspector面板的属性会自动隐藏这个前缀,使用其它的字母+下划线前缀则不能触发这个效果。顺便,按照驼峰法命名属性时,暴露到Inspector的属性不会将单词粘连在一起显示,而是将单词分开。
重写上述组件,再次观察Inspector中暴露的属性,了解几个Attribute的作用:
public class InspectorTest3 : MonoBehaviour
{
public int m_int;
[Range(0,100)]
public float m_float;
public char m_char;
public bool m_bool;
[MultiLine(2)]
public string m_string;
[TextArea]
public string m_textArea;
}
Range标签可以限制数值类型属性(整形、浮点型)的范围,同时在Inspector面板中渲染为一个滑动条。
MultiLine标签可以使一个字符串的输入框高度边变为n行字符的高度,TextArea标签可以使一个字符串的输入框不限高度。
实现下面的组件,观察:
public class InspectorTest4 : MonoBehaviour
{
public Vector3 m_vector3;
public Vector4 m_vector4;
public Quaternion m_quaternion;
public Color m_color;
}
可见,四元数并没有像Transform组件中那样显示为三维的欧拉角,而是直接显示为XYZW的四元向量。
颜色类则直接可以使用吸管和调色盘。
实现下面的组件,观察:
public class InspectorTest5: MonoBehavior
{
public SerilizableClass m_serilizableClass;
public UnserilizableClass m_unserilizableClass;
public ComponentClass m_componentClass;
public ScriptableClass m_scriptableClass;
}
[System.Serializable]
public class SerilizableClass
{
public int m_value = 1;
public SerializableEunm m_serilizableEnum;
public UnserializableEunm m_unserilizableEnum;
}
[System.Serializable]
public class ComponentClass : MonoBehaviour
{
public int m_value = 1;
public SerializableEunm m_serilizableEnum;
public UnserializableEunm m_unserilizableEnum;
}
[System.Serializable]
public class ScriptableClass : ScriptableObject
{
public int m_value = 1;
public SerializableEunm m_serilizableEnum;
public UnserializableEunm m_unserilizableEnum;
}
public class UnserilizableClass
{
public int m_value = 1;
public SerializableEunm m_serilizableEnum;
public UnserializableEunm m_unserilizableEnum;
}
[System.Serializable]
public enum SerializableEunm { A, B, C }
public enum UnserializableEunm { A, B, C }
Inspector中显示的效果如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zZOgpa6-1569859801128)(C:\Users\UPiracy\AppData\Roaming\Typora\typora-user-images\1568479106573.png)]
可见,继承自MonoBehaviour的组件类和继承自ScriptableObject的数据类都会显示为拖动框的形式。不继承自这两个类的其它类,若具有System.Serializable标签,则可以被展开并显示其中的public属性,而不具有这个标签的类则无法在Inspector中显示。Struct的结论和Class一致。
然而,无论是否具有System.Serializable标签,Enum都可以显示在Inspector中。