예제 #1
0
        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();
        }
예제 #2
0
        /// <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();
            }
        }