利用Unity的EditorWindow和ReorderableList來取得特定Gameobject上的Component
[Serializable]
public struct item
{
public GameObject target;
public MonoScript script;
}
public class HolderItems :ScriptableObject
{
public List<item> items = new List<item> ();
}
void OnEnable ()
{
var m_HolderItems = CreateInstance<HolderItems> ();
if (m_HolderItems != null) {
SerializedObject holderItemsSo = new SerializedObject (m_HolderItems);
ReorderableList list = new ReorderableList (holderItemsSo, holderItemsSo.FindProperty ("items"), false, false, true, true);
//繪製Title
list.drawHeaderCallback = rect => EditorGUI.LabelField (rect, string.Format ("Create Assets/{0}Holder.cs", holderName));
//繪製每一列
list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
var element = list.serializedProperty.GetArrayElementAtIndex (index);
rect.y += 2;
GameObject go = (GameObject)element.FindPropertyRelative ("target").objectReferenceValue;
EditorGUI.PropertyField (new Rect (rect.x, rect.y, 150, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative ("target"), GUIContent.none);
if (go != null) {
//取得特定Gameobject的Components並秀出
componData [index].componGo = go;
Component[] compons = go.GetComponents<Component> ();
List<string> componsName = new List<string> ();
for (int i = 0; i < compons.Length; i++) {
if (compons [i].GetType ().Name.Contains ("CanvasRenderer"))
continue;
componsName.Add (compons [i].GetType ().Name);
}
GameObject parentGo = (index != 0) ? go : componData [0].componGo;
while (parentGo.transform.parent != null) {
if (parentGo.transform.parent.name.Contains ("canvas_"))
break;
parentGo = parentGo.transform.parent.gameObject;
}
StringBuilder holderNameBuilder = new StringBuilder ();
string[] parentNames = parentGo.name.Split ('_');
for (int s = 0; s < parentNames.Length; s++) {
holderNameBuilder.Append (upperStringFirst (parentNames [s]));
}
if (index != 0) {
if (!holderNameBuilder.ToString ().Equals (holderName)) {
Debug.LogErrorFormat ("{0} && First GameObejct is not Same Root , {0} Parent is {1} !", go.name, parentGo.name);
}
} else {
holderName = holderNameBuilder.ToString ();
}
componsName.Add (go.GetType ().Name);
componsName.Add ("Script");
componData [index].SetComponsName (componsName);
componData [index].componIndex = EditorGUI.Popup (new Rect (rect.x + 200, rect.y, 150, EditorGUIUtility.singleLineHeight), componData [index].componIndex, componsName.ToArray (), EditorStyles.popup);
if (componData [index].GetComponName ().Equals ("Script")) {
EditorGUI.PropertyField (new Rect (rect.x + 400, rect.y, 150, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative ("script"), GUIContent.none);
} else {
componData [index].arrayIndex = EditorGUI.Popup (new Rect (rect.x + 400, rect.y, 150, EditorGUIUtility.singleLineHeight), componData [index].arrayIndex, componData [index].componIsArray, EditorStyles.popup);
}
}
};
}
list.onAddCallback = (ReorderableList addList) => {
//Base Add
var index = addList.serializedProperty.arraySize;
addList.serializedProperty.arraySize++;
addList.index = index;
//ComponData List Add Item
componData.Add (new holderComponData ());
//Gameobject Clear
var element = addList.serializedProperty.GetArrayElementAtIndex (index);
element.FindPropertyRelative ("target").objectReferenceValue = null;
};
list.onRemoveCallback = (ReorderableList removeList) => {
//ComponData List Remove At ListIndex
componData.RemoveAt (removeList.index);
//Base Remove
ReorderableList.defaultBehaviours.DoRemoveButton (removeList);
};
Repaint ();
}
void OnGUI ()
{
if (holderItemsSo.targetObject != null) {
holderItemsSo.Update ();
list.DoLayoutList ();
holderItemsSo.ApplyModifiedProperties ();
}
}