[Unity] Custom Editor (2) – RectTransform Reset
這篇利用 Decorator Editor 針對 RectTransform
再建立一個能夠重設位置、旋轉與縮放的 Custom Editor
如果不知道 Decorator Editor 的話請先看這一篇:
[Unity] Custom Editor (1) – Transform Reset
Overview
1. Transform Resetter:建立能夠儲存一組 Position、Rotation、Scale 的類別
2. Transform Inspector
3. 找出 RectTransform 的 Editor 類別名稱與屬性名稱
4. RectTransform Inspector
1. Transform Resetter:建立能夠儲存一組 Position、Rotation、Scale 的類別
由於 Transform 和 RectTransform 都擁有一組 Position、Rotation 和 Scale 的屬性
因此建立了一個儲存這些屬性的 Decorator Editor
並且修改了原本儲存方式,採用 Unity 的 JsonUtility 來轉換為 string 儲存
public abstract class TransformResetter : DecoratorEditor { private const string RESET_POSITION = "RESET_POSITION"; private const string RESET_ROTATION = "RESET_ROTATION"; private const string RESET_SCALE = "RESET_SCALE"; protected bool m_unFold = false; protected static Vector3 m_resetPosition = Vector3.zero; protected static Vector3 m_resetRotation = Vector3.zero; protected static Vector3 m_resetScale = Vector3.one; public TransformResetter(string name) : base(name) { } protected void LoadCustomValues() { if (EditorPrefs.HasKey(RESET_POSITION)) { m_resetPosition = JsonUtility.FromJson<Vector3>(EditorPrefs.GetString(RESET_POSITION)); } if (EditorPrefs.HasKey(RESET_ROTATION)) { m_resetRotation = JsonUtility.FromJson<Vector3>(EditorPrefs.GetString(RESET_ROTATION)); } if (EditorPrefs.HasKey(RESET_SCALE)) { m_resetScale = JsonUtility.FromJson<Vector3>(EditorPrefs.GetString(RESET_SCALE)); } } protected void DrawCustomValues() { string originLabel; if (m_resetPosition != Vector3.zero || m_resetRotation != Vector3.zero || m_resetScale != Vector3.one) { originLabel = "Set Origin [Custom]"; } else { originLabel = "Set Origin [Default]"; } m_unFold = EditorGUILayout.Foldout(m_unFold, originLabel); if (m_unFold) { EditorGUI.BeginChangeCheck(); if (GUILayout.Button("Clear Custom Origin", EditorStyles.miniButton)) { m_resetPosition = Vector3.zero; m_resetRotation = Vector3.zero; m_resetScale = Vector3.one; GUI.FocusControl(null); } GUI.backgroundColor = Color.white; m_resetPosition = EditorGUILayout.Vector3Field("Position", m_resetPosition); m_resetRotation = EditorGUILayout.Vector3Field("Rotation", m_resetRotation); m_resetScale = EditorGUILayout.Vector3Field("Scale", m_resetScale); if (EditorGUI.EndChangeCheck()) { EditorPrefs.SetString(RESET_POSITION, EditorJsonUtility.ToJson(m_resetPosition)); EditorPrefs.SetString(RESET_ROTATION, EditorJsonUtility.ToJson(m_resetRotation)); EditorPrefs.SetString(RESET_SCALE, EditorJsonUtility.ToJson(m_resetScale)); } } } }
2. Transform Inspector
接下來修改一下原本的 Transform Inspector
改繼承自 Transform Resetter
做的事情就單純多了
按下按鈕時 把值設回 Resetter 中紀錄的值就好了
[CustomEditor(typeof(Transform)), CanEditMultipleObjects] public class TransformInspector : TransformResetter { private SerializedProperty m_position; private SerializedProperty m_rotation; private SerializedProperty m_scale; public TransformInspector() : base("TransformInspector") { } void OnEnable() { m_position = serializedObject.FindProperty("m_LocalPosition"); m_rotation = serializedObject.FindProperty("m_LocalRotation"); m_scale = serializedObject.FindProperty("m_LocalScale"); LoadCustomValues(); } public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); GUI.backgroundColor = new Color(0.75f, 1, 0); if (GUILayout.Button("Position", EditorStyles.miniButtonLeft)) { m_position.vector3Value = m_resetPosition; serializedObject.ApplyModifiedProperties(); GUI.FocusControl(null); } if (GUILayout.Button("Rotation", EditorStyles.miniButtonMid)) { m_rotation.quaternionValue = Quaternion.Euler(m_resetRotation); serializedObject.ApplyModifiedProperties(); GUI.FocusControl(null); } if (GUILayout.Button("Scale", EditorStyles.miniButtonRight)) { m_scale.vector3Value = m_resetScale; serializedObject.ApplyModifiedProperties(); GUI.FocusControl(null); } EditorGUILayout.EndHorizontal(); DrawCustomValues(); } }
3. 找出 RectTransform 的 Editor 類別名稱與屬性名稱
接下來要找出 RectTransform 在 Unity 中的 Editor 類別檔
叫做 RectTransformEditor
在建構式裡要塞這個名字進去
public RectTransformInspector() : base("RectTransformEditor") { }
不知道怎麼找的話可以看這一篇:
[Unity] 如何找到 Unity 預設的 Editor 類別名稱
由於 Transform 的位置、旋轉與縮放的成員名稱分別叫做
m_LocalPosition、m_LocalRotation 與 m_LocalScale
因此我們很容易會覺得,RectTransform 也是叫一樣的名稱
但如果使用 m_LocalPosition 這個名字
就會發現在 RectTransformEditor.cs 下是找不到的
他有的只有 m_LocalPositionZ
以及另外一個 Vector2 成員:m_AnchoredPosition
所以我們所需要的 SerializedProperty 會多一個:
m_position = serializedObject.FindProperty("m_AnchoredPosition"); m_positionZ = serializedObject.FindProperty("m_LocalPosition.z"); m_rotation = serializedObject.FindProperty("m_LocalRotation"); m_scale = serializedObject.FindProperty("m_LocalScale");
4. RectTransform Inspector
只要找到對應的 Property 名稱
剩下來的事情就簡單了
一樣只要在按下按鈕時把值重設就好了
以下是完整的程式碼
[CustomEditor(typeof(RectTransform)), CanEditMultipleObjects] public class RectTransformInspector : TransformResetter { SerializedProperty m_position; SerializedProperty m_positionZ; SerializedProperty m_rotation; SerializedProperty m_scale; public RectTransformInspector() : base("RectTransformEditor") { } void OnEnable() { m_position = serializedObject.FindProperty("m_AnchoredPosition"); m_positionZ = serializedObject.FindProperty("m_LocalPosition.z"); m_rotation = serializedObject.FindProperty("m_LocalRotation"); m_scale = serializedObject.FindProperty("m_LocalScale"); LoadCustomValues(); } public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUILayout.BeginHorizontal(); GUI.backgroundColor = new Color(0.75f, 1, 0); if (GUILayout.Button("Position", EditorStyles.miniButtonLeft)) { m_position.vector2Value = m_resetPosition; m_positionZ.floatValue = m_resetPosition.z; serializedObject.ApplyModifiedProperties(); GUI.FocusControl(null); } if (GUILayout.Button("Rotation", EditorStyles.miniButtonMid)) { m_rotation.quaternionValue = Quaternion.Euler(m_resetRotation); serializedObject.ApplyModifiedProperties(); GUI.FocusControl(null); } if (GUILayout.Button("Scale", EditorStyles.miniButtonRight)) { m_scale.vector3Value = m_resetScale; serializedObject.ApplyModifiedProperties(); GUI.FocusControl(null); } EditorGUILayout.EndHorizontal(); DrawCustomValues(); } }
完成後,RectTransform 也同樣可以進行 Reset 囉!
Github 完整專案
歡迎您留言與分享!(Welcome for comments or sharing!)
- [Unity] Custom Editor (1) – Transform Reset
- [Unity] Editor Window – Keyboard Event