public static void Open(Type nodeType, Action <GameObject> onAddButtonPushed) { if (!nodeType.IsSubclassOf(typeof(NodeBase))) { throw new ArgumentException(nodeType.ToString() + " is not a subclass of NodeBase."); } if (pickerWindow == null) { pickerWindow = CreateInstance <NodePickerWindow>(); pickerWindow.titleContent = new GUIContent("Select Node"); } pickerWindow.OnAddButtonPushed = (x) => { onAddButtonPushed(x.FirstOrDefault()); }; pickerWindow.treeView = new PickerTreeView <GameObject>( new TreeViewState(), () => EnumerateNodes(nodeType), EditorGUIUtility.IconContent("PrefabNormal Icon").image as Texture2D); pickerWindow.treeView.TreeViewCanMultiSelect = false; pickerWindow.treeView.ItemDoubleClicked = (x) => { onAddButtonPushed(x); pickerWindow.Close(); }; pickerWindow.treeView.Reload(); pickerWindow.ShowAuxWindow(); }
/// <summary> /// NodeBaseを継承しているクラス専用のオブジェクトフィールドを配置する /// </summary> /// <param name="title">タイトル(空文字列を設定するとレイアウトが左詰めになる)</param> /// <param name="nodeType">Nodeの型(NodeBaseを継承しているクラスである必要がある)</param> /// <param name="targetSerializedObject">編集対象のオブジェクト</param> /// <param name="targetProperty">編集対象のプロパティ</param> /// <param name="onPropertyChanged">プロパティの値が変化した時に呼ばれるデリゲート</param> /// <param name="isCreateNodeOnDoubleClick">フィールドをダブルクリックした時に呼ばれるデリゲート</param> public static void PencilNodeField( string title, Type nodeType, SerializedObject targetSerializedObject, SerializedProperty targetProperty, Action <GameObject> onPropertyChanged, Action onFieldDoubleClicked = null) { var targetObjectName = targetProperty.objectReferenceValue ? targetProperty.objectReferenceValue.name : "None (Game Object)"; EditorGUILayout.LabelField( new GUIContent(title), new GUIContent( targetObjectName, EditorGUIUtility.IconContent("PrefabNormal Icon").image), GUI.skin.FindStyle("ObjectField")); var objectFieldRect = GUILayoutUtility.GetLastRect(); // フィールド右側の☉ボタンの範囲 var pickerButtonRect = objectFieldRect; pickerButtonRect.x += pickerButtonRect.width - 15; pickerButtonRect.width = 15; // クリックイベントのハンドル if (Event.current.type == EventType.MouseDown && Event.current.button == 0) // 左クリック { if (pickerButtonRect.Contains(Event.current.mousePosition)) { // ☉ボタンのクリック NodePickerWindow.Open(nodeType, x => { targetSerializedObject.Update(); if (targetProperty.objectReferenceValue != x) { targetProperty.objectReferenceValue = x; onPropertyChanged(targetProperty.objectReferenceValue as GameObject); } targetSerializedObject.ApplyModifiedProperties(); }); } else if (objectFieldRect.Contains(Event.current.mousePosition)) { // テキストフィールドのクリック EditorGUIUtility.PingObject(targetProperty.objectReferenceValue); // テキストフィールドのダブルクリック if (DoubleClickCounter.IsDoubleClicked(GUIUtility.GetControlID(FocusType.Passive))) { if (onFieldDoubleClicked != null && targetProperty.objectReferenceValue == null) { onFieldDoubleClicked(); } else { Selection.activeObject = targetProperty.objectReferenceValue; } } } } // ドラッグイベント if (Event.current.type == EventType.DragUpdated && objectFieldRect.Contains(Event.current.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; DragAndDrop.activeControlID = GUIUtility.GetControlID(FocusType.Passive); } if (Event.current.type == EventType.DragPerform && objectFieldRect.Contains(Event.current.mousePosition)) { DragAndDrop.AcceptDrag(); // MEMO: 複数のオブジェクトがD&Dされた場合、最初の物以外は無視する var draggedObject = DragAndDrop.objectReferences.FirstOrDefault(); if (draggedObject != null && draggedObject is GameObject && (draggedObject as GameObject).GetComponent(nodeType) != null) { targetSerializedObject.Update(); if (targetProperty.objectReferenceValue != draggedObject) { targetProperty.objectReferenceValue = draggedObject; onPropertyChanged(targetProperty.objectReferenceValue as GameObject); } targetSerializedObject.ApplyModifiedProperties(); } DragAndDrop.activeControlID = 0; Event.current.Use(); } }