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中。