예제 #1
0
        /// <summary> Make a simple port field. </summary>
        public static void PortField(Vector2 position, XNode.NodePort port)
        {
            if (port == null)
            {
                return;
            }

            Rect rect = new Rect(position, new Vector2(16, 16));

            Color backgroundColor = new Color32(90, 97, 105, 255);
            Color tint;

            if (NodeEditorWindow.nodeTint.TryGetValue(port.node.GetType(), out tint))
            {
                backgroundColor *= tint;
            }
            Color col = NodeEditorWindow.current.graphEditor.GetTypeColor(port.ValueType);

            DrawPortHandle(rect, backgroundColor, col, Node.PortStyle.Default);

            // Register the handle position
            Vector2 portPos = rect.center;

            if (NodeEditor.portPositions.ContainsKey(port))
            {
                NodeEditor.portPositions[port] = portPos;
            }
            else
            {
                NodeEditor.portPositions.Add(port, portPos);
            }
        }
예제 #2
0
        /// <summary> Make a simple port field. </summary>
        public static void PortField(GUIContent label, XNode.NodePort port, params GUILayoutOption[] options)
        {
            if (port == null)
            {
                return;
            }
            if (options == null)
            {
                options = new GUILayoutOption[] { GUILayout.MinWidth(30) }
            }
            ;
            Vector2    position = Vector3.zero;
            GUIContent content  = label != null ? label : new GUIContent(ObjectNames.NicifyVariableName(port.fieldName));

            // If property is an input, display a regular property field and put a port handle on the left side
            if (port.direction == XNode.NodePort.IO.Input)
            {
                // Display a label
                EditorGUILayout.LabelField(content, options);

                Rect rect = GUILayoutUtility.GetLastRect();
                position = rect.position - new Vector2(16, 0);
            }
            // If property is an output, display a text label and put a port handle on the right side
            else if (port.direction == XNode.NodePort.IO.Output)
            {
                // Display a label
                EditorGUILayout.LabelField(content, NodeEditorResources.OutputPort, options);

                Rect rect = GUILayoutUtility.GetLastRect();
                position = rect.position + new Vector2(rect.width, 0);
            }
            PortField(position, port);
        }
예제 #3
0
 /// <summary> Draws an input and an output port on the same line </summary>
 public static void PortPair(XNode.NodePort input, XNode.NodePort output)
 {
     GUILayout.BeginHorizontal();
     NodeEditorGUILayout.PortField(input, GUILayout.MinWidth(0));
     NodeEditorGUILayout.PortField(output, GUILayout.MinWidth(0));
     GUILayout.EndHorizontal();
 }
예제 #4
0
 public override object GetValue(XNode.NodePort port)
 {
     vector.x = GetInputValue <float>("x", this.x);
     vector.y = GetInputValue <float>("y", this.y);
     vector.z = GetInputValue <float>("z", this.z);
     return(vector);
 }
예제 #5
0
        /// <summary> Duplicate selected nodes and select the duplicates </summary>
        public void DuplicateSelectedNodes()
        {
            UnityEngine.Object[] newNodes = new UnityEngine.Object[Selection.objects.Length];
            Dictionary <XNode.Node, XNode.Node> substitutes = new Dictionary <XNode.Node, XNode.Node>();

            for (int i = 0; i < Selection.objects.Length; i++)
            {
                if (Selection.objects[i] is XNode.Node)
                {
                    XNode.Node srcNode = Selection.objects[i] as XNode.Node;
                    if (srcNode.graph != graph)
                    {
                        continue;                         // ignore nodes selected in another graph
                    }
                    XNode.Node newNode = graphEditor.CopyNode(srcNode);
                    substitutes.Add(srcNode, newNode);
                    newNode.position = srcNode.position + new Vector2(30, 30);
                    newNodes[i]      = newNode;
                }
            }

            // Walk through the selected nodes again, recreate connections, using the new nodes
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                if (Selection.objects[i] is XNode.Node)
                {
                    XNode.Node srcNode = Selection.objects[i] as XNode.Node;
                    if (srcNode.graph != graph)
                    {
                        continue;                         // ignore nodes selected in another graph
                    }
                    foreach (XNode.NodePort port in srcNode.Ports)
                    {
                        for (int c = 0; c < port.ConnectionCount; c++)
                        {
                            XNode.NodePort inputPort  = port.direction == XNode.NodePort.IO.Input ? port : port.GetConnection(c);
                            XNode.NodePort outputPort = port.direction == XNode.NodePort.IO.Output ? port : port.GetConnection(c);

                            XNode.Node newNodeIn, newNodeOut;
                            if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut))
                            {
                                newNodeIn.UpdateStaticPorts();
                                newNodeOut.UpdateStaticPorts();
                                inputPort  = newNodeIn.GetInputPort(inputPort.fieldName);
                                outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
                            }
                            if (!inputPort.IsConnectedTo(outputPort))
                            {
                                inputPort.Connect(outputPort);
                            }
                        }
                    }
                }
            }
            Selection.objects = newNodes;
        }
예제 #6
0
    public override object GetValue(XNode.NodePort port)
    {
        Module m = GetModule();

        if (m != null)
        {
            return(new ModuleWrapper(m));
        }
        return(null);
    }
예제 #7
0
 /// <summary> Make a field for a serialized property. Automatically displays relevant node port. </summary>
 public static void PropertyField(SerializedProperty property, GUIContent label, bool includeChildren = true, params GUILayoutOption[] options)
 {
     if (property == null)
     {
         throw new NullReferenceException();
     }
     XNode.Node     node = property.serializedObject.targetObject as XNode.Node;
     XNode.NodePort port = node.GetPort(property.name);
     PropertyField(property, label, port, includeChildren);
 }
예제 #8
0
        /// <summary> Show right-click context menu for hovered port </summary>
        void ShowPortContextMenu(XNode.NodePort hoveredPort)
        {
            GenericMenu contextMenu = new GenericMenu();

            contextMenu.AddItem(new GUIContent("Clear Connections"), false, () => hoveredPort.ClearConnections());
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
            if (NodeEditorPreferences.GetSettings().autoSave)
            {
                AssetDatabase.SaveAssets();
            }
        }
예제 #9
0
    public override object GetValue(XNode.NodePort port)
    {
        // Get new a and b values from input connections. Fallback to field values if input is not connected
        if (port.fieldName != "output")
        {
            return(null);
        }

        //preview = Utils.GeneratePreview(noise, 128, 128);

        return(new ModuleWrapper(GetModule()));
    }
예제 #10
0
        private void OnCreateReorderableList(ReorderableList list)
        {
            list.drawHeaderCallback =
                (Rect rect) => {
                SerializedProperty expandedProperty = serializedObject.FindProperty("expanded");
                string             title            = "Actions";
                if (Application.isPlaying)
                {
                    title = "Actions (" + node.repeatCount + "/" + node.repeats + " repeats)";
                }
                EditorGUI.BeginChangeCheck();
                expandedProperty.boolValue = EditorGUI.Foldout(rect, expandedProperty.boolValue, title, DelftStyles.foldoutNoHighlight);
                if (EditorGUI.EndChangeCheck())
                {
                    serializedObject.ApplyModifiedProperties();
                    serializedObject.SetIsDifferentCacheDirty();
                    serializedObject.Update();
                }
            };
            list.drawElementCallback =
                (Rect rect, int index, bool isActive, bool isFocused) => {
                SerializedProperty expandedProperty = serializedObject.FindProperty("expanded");
                if (!expandedProperty.boolValue)
                {
                    return;
                }

                XNode.NodePort     port     = node.GetPort("actions " + index);
                SerializedProperty itemData = serializedObject.FindProperty("actions").GetArrayElementAtIndex(index);
                if (node.currentAction == index)
                {
                    EditorGUI.DrawRect(rect, Color.gray);
                }
                EditorGUI.PropertyField(rect, itemData);
                Vector2 pos = rect.position + (port.IsOutput ? new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
                serializedObject.ApplyModifiedProperties();
                serializedObject.Update();
                NodeEditorGUILayout.PortField(pos, port);
            };
            list.elementHeightCallback =
                (int index) => {
                SerializedProperty expandedProperty = serializedObject.FindProperty("expanded");
                if (!expandedProperty.boolValue)
                {
                    return(0f);
                }
                SerializedProperty itemData = serializedObject.FindProperty("actions").GetArrayElementAtIndex(index);
                return(EditorGUI.GetPropertyHeight(itemData));
            };
        }
예제 #11
0
        /// <summary> Make a simple port field. </summary>
        public static void PortField(GUIContent label, XNode.NodePort port, params GUILayoutOption[] options)
        {
            if (port == null)
            {
                return;
            }
            if (label == null)
            {
                EditorGUILayout.LabelField(ObjectNames.NicifyVariableName(port.fieldName), options);
            }
            else
            {
                EditorGUILayout.LabelField(label, options);
            }
            Rect rect = GUILayoutUtility.GetLastRect();

            if (port.direction == XNode.NodePort.IO.Input)
            {
                rect.position = rect.position - new Vector2(16, 0);
            }
            else if (port.direction == XNode.NodePort.IO.Output)
            {
                rect.position = rect.position + new Vector2(rect.width, 0);
            }
            rect.size = new Vector2(16, 16);

            Color backgroundColor = new Color32(90, 97, 105, 255);

            if (NodeEditorWindow.nodeTint.ContainsKey(port.node.GetType()))
            {
                backgroundColor *= NodeEditorWindow.nodeTint[port.node.GetType()];
            }
            Color col = NodeGraphEditor.GetEditor(port.node.graph).GetTypeColor(port.ValueType);

            DrawPortHandle(rect, backgroundColor, col);

            // Register the handle position
            Vector2 portPos = rect.center;

            if (NodeEditor.portPositions.ContainsKey(port))
            {
                NodeEditor.portPositions[port] = portPos;
            }
            else
            {
                NodeEditor.portPositions.Add(port, portPos);
            }
        }
예제 #12
0
        /// <summary>
        /// 简单渲染
        /// </summary>
        /// <param name="list"></param>
        public void SimpleDrawList(ReorderableList list)
        {
            if (chatNode == null)
            {
                chatNode = target as ChatNode;
            }


            //  Debug.Log("简单渲染中");
            //获取序列化后的chatslist数据
            SerializedProperty arrayData = serializedObject.FindProperty(fieldName);
            bool hasArrayData            = arrayData != null && arrayData.isArray;

            list.drawHeaderCallback = (Rect rect) =>
            {
                string title = "对话列表";
                GUI.Label(rect, title);
            };

            list.drawElementCallback = (Rect rect, int index, bool selected, bool focused) =>
            {
                #region 自定义渲染动态节点

                XNode.Node     node = serializedObject.targetObject as XNode.Node;
                XNode.NodePort port = node.GetPort(fieldName + " " + index);

                EditorGUI.LabelField(rect, "");
                if (port != null && chatNode.chatslist[index].chatType == ChatType.option || chatNode.chatslist[index].chatType == ChatType.jump)
                {
                    Vector2 pos = rect.position + (port.IsOutput ? new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
                    NodeEditorGUILayout.PortField(pos, port);
                }
                #endregion
            };

            list.elementHeightCallback = (int index) =>
            {
                if (chatNode.chatslist[index].chatType == ChatType.option || chatNode.chatslist[index].chatType == ChatType.jump)
                {
                    SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);
                    return(EditorGUI.GetPropertyHeight(itemData));
                }
                else
                {
                    return(0);
                }
            };
        }
예제 #13
0
        /// <summary>
        /// Shows all the property fields from the node
        /// </summary>
        protected virtual void ShowBodyFields()
        {
            string[] excludes = { "m_Script", "graph", "position", "ports" };

            // Iterate through serialized properties and draw them like the Inspector (But with ports)
            SerializedProperty iterator = serializedObject.GetIterator();
            bool enterChildren          = true;

            EditorGUIUtility.labelWidth = LabelWidth;
            GUILayout.Space(m_PortRect.height * 0.5f);
            while (iterator.NextVisible(enterChildren))
            {
                enterChildren = false;

                if (excludes.Contains(iterator.name))
                {
                    continue;
                }

                XNode.Node     node = iterator.serializedObject.targetObject as XNode.Node;
                XNode.NodePort port = node.GetPort(iterator.name);

                // Don't allow to draw ports (// TO DO, add ports to the list now?)
                if (port != null)
                {
                    continue;
                }

                // Save original editorStyle
                Color originalContentColor = GUI.contentColor;
                Color originalColor        = EditorStyles.label.normal.textColor;
                Font  originalFont         = EditorStyles.label.font;
                int   origianlFontSize     = EditorStyles.label.fontSize;

                // Replace skin for entire editorStyle with custom
                EditorStyles.label.normal.textColor = Color.white;
                EditorStyles.label.font             = m_NodeSkin.label.font;
                EditorStyles.label.fontSize         = 13;

                // Draw property
                NodeEditorGUILayout.PropertyField(iterator, (NodePort)null, true);

                // Place original skin back to not mess other nodes
                EditorStyles.label.normal.textColor = originalColor;
                EditorStyles.label.font             = originalFont;
                EditorStyles.label.fontSize         = origianlFontSize;
            }
        }
예제 #14
0
        /// <summary> Show right-click context menu for hovered port </summary>
        void ShowPortContextMenu(XNode.NodePort hoveredPort)
        {
            GenericMenu contextMenu = new GenericMenu();

            foreach (var port in hoveredPort.GetConnections())
            {
                var name  = port.node.name;
                var index = hoveredPort.GetConnectionIndex(port);
                contextMenu.AddItem(new GUIContent($"Disconnect({name})"), false, () => hoveredPort.Disconnect(index));
            }
            contextMenu.AddItem(new GUIContent("Clear Connections"), false, () => hoveredPort.ClearConnections());
            contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
            if (NodeEditorPreferences.GetSettings().autoSave)
            {
                AssetDatabase.SaveAssets();
            }
        }
예제 #15
0
        /// <summary> Add a port field to previous layout element. </summary>
        public static void AddPortField(XNode.NodePort port)
        {
            if (port == null)
            {
                return;
            }
            Rect rect = new Rect();

            // If property is an input, display a regular property field and put a port handle on the left side
            if (port.direction == XNode.NodePort.IO.Input)
            {
                rect          = GUILayoutUtility.GetLastRect();
                rect.position = rect.position - new Vector2(16, 0);
                // If property is an output, display a text label and put a port handle on the right side
            }
            else if (port.direction == XNode.NodePort.IO.Output)
            {
                rect          = GUILayoutUtility.GetLastRect();
                rect.position = rect.position + new Vector2(rect.width, 0);
            }

            rect.size = new Vector2(16, 16);

            Color backgroundColor = new Color32(90, 97, 105, 255);
            Color tint;

            if (NodeEditorWindow.nodeTint.TryGetValue(port.node.GetType(), out tint))
            {
                backgroundColor *= tint;
            }
            Color col = NodeEditorWindow.current.graphEditor.GetTypeColor(port.ValueType);

            DrawPortHandle(rect, backgroundColor, col, Node.PortStyle.Default);

            // Register the handle position
            Vector2 portPos = rect.center;

            if (NodeEditor.portPositions.ContainsKey(port))
            {
                NodeEditor.portPositions[port] = portPos;
            }
            else
            {
                NodeEditor.portPositions.Add(port, portPos);
            }
        }
예제 #16
0
        /// <summary> Is this port part of an InstancePortList? </summary>
        public static bool IsInstancePortListPort(XNode.NodePort port)
        {
            string[] parts = port.fieldName.Split(' ');
            if (parts.Length != 2)
            {
                return(false);
            }
            Dictionary <string, ReorderableList> cache;

            if (reorderableListCache.TryGetValue(port.node, out cache))
            {
                ReorderableList list;
                if (cache.TryGetValue(parts[0], out list))
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #17
0
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                foreach (XNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    if (!portConnectionPoints.ContainsKey(output))
                    {
                        continue;
                    }
                    Vector2 from = _portConnectionPoints[output].center;
                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        XNode.NodePort input = output.GetConnection(k);
                        if (input == null)
                        {
                            continue;                //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        if (!input.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        if (!_portConnectionPoints.ContainsKey(input))
                        {
                            continue;
                        }
                        Vector2 to = _portConnectionPoints[input].center;
                        Color   connectionColor = currentGraphEditor.GetTypeColor(output.ValueType);
                        DrawConnection(from, to, connectionColor);
                    }
                }
            }
        }
예제 #18
0
        // GetValue should be overridden to return a value for any specified output port
        public override object GetValue(XNode.NodePort port)
        {
            // Get new a and b values from input connections. Fallback to field values if input is not connected
            float a = GetInputValue <float>("a", this.a);
            float b = GetInputValue <float>("b", this.b);

            // After you've gotten your input values, you can perform your calculations and return a value
            result = 0f;
            if (port.fieldName == "result")
            {
                switch (mathType)
                {
                case MathType.Add:
                default: result = a + b; break;

                case MathType.Subtract: result = a - b; break;

                case MathType.Multiply: result = a * b; break;

                case MathType.Divide: result = a / b; break;
                }
            }
            return(result);
        }
예제 #19
0
        public static Vector2 GetPortPosition(XNode.NodePort port)
        {
            Vector2 position = Vector3.zero;

            if (port == null)
            {
                return(position);
            }

            // If property is an input, display a regular property field and put a port handle on the left side
            if (port.direction == XNode.NodePort.IO.Input)
            {
                Rect rect = GUILayoutUtility.GetLastRect();
                position = rect.position - new Vector2(15, -65);
            }
            // If property is an output, display a text label and put a port handle on the right side
            else if (port.direction == XNode.NodePort.IO.Output)
            {
                Rect rect = GUILayoutUtility.GetLastRect();
                position = rect.position + new Vector2(rect.width, 0);
            }

            return(position);
        }
예제 #20
0
 /// <summary> Make a simple port field. </summary>
 public static void PortField(XNode.NodePort port, params GUILayoutOption[] options)
 {
     PortField(null, port, options);
 }
예제 #21
0
 public RerouteReference(XNode.NodePort port, int connectionIndex, int pointIndex)
 {
     this.port            = port;
     this.connectionIndex = connectionIndex;
     this.pointIndex      = pointIndex;
 }
예제 #22
0
        /// <summary> Draws all connections </summary>
        public void DrawConnections()
        {
            Vector2 mousePos = Event.current.mousePosition;
            List <RerouteReference> selection = preBoxSelectionReroute != null ? new List <RerouteReference>(preBoxSelectionReroute) : new List <RerouteReference>();

            hoveredReroute = new RerouteReference();

            List <Vector2> gridPoints = new List <Vector2>(2);

            Color col = GUI.color;

            foreach (XNode.Node node in graph.nodes)
            {
                //If a null node is found, return. This can happen if the nodes associated script is deleted. It is currently not possible in Unity to delete a null asset.
                if (node == null)
                {
                    continue;
                }

                // Draw full connections and output > reroute
                foreach (XNode.NodePort output in node.Outputs)
                {
                    //Needs cleanup. Null checks are ugly
                    Rect fromRect;
                    if (!portConnectionPoints.TryGetValue(output, out fromRect))
                    {
                        continue;
                    }

                    Color portColor = graphEditor.GetPortColor(output);
                    for (int k = 0; k < output.ConnectionCount; k++)
                    {
                        XNode.NodePort input = output.GetConnection(k);

                        Gradient     noodleGradient  = graphEditor.GetNoodleGradient(output, input);
                        float        noodleThickness = graphEditor.GetNoodleThickness(output, input);
                        NoodlePath   noodlePath      = graphEditor.GetNoodlePath(output, input);
                        NoodleStroke noodleStroke    = graphEditor.GetNoodleStroke(output, input);

                        // Error handling
                        if (input == null)
                        {
                            continue;                //If a script has been updated and the port doesn't exist, it is removed and null is returned. If this happens, return.
                        }
                        if (!input.IsConnectedTo(output))
                        {
                            input.Connect(output);
                        }
                        Rect toRect;
                        if (!portConnectionPoints.TryGetValue(input, out toRect))
                        {
                            continue;
                        }

                        List <Vector2> reroutePoints = output.GetReroutePoints(k);

                        gridPoints.Clear();
                        gridPoints.Add(fromRect.center);
                        gridPoints.AddRange(reroutePoints);
                        gridPoints.Add(toRect.center);
                        DrawNoodle(noodleGradient, noodlePath, noodleStroke, noodleThickness, gridPoints);

                        // Loop through reroute points again and draw the points
                        for (int i = 0; i < reroutePoints.Count; i++)
                        {
                            RerouteReference rerouteRef = new RerouteReference(output, k, i);
                            // Draw reroute point at position
                            Rect rect = new Rect(reroutePoints[i], new Vector2(12, 12));
                            rect.position = new Vector2(rect.position.x - 6, rect.position.y - 6);
                            rect          = GridToWindowRect(rect);

                            // Draw selected reroute points with an outline
                            if (selectedReroutes.Contains(rerouteRef))
                            {
                                GUI.color = NodeEditorPreferences.GetSettings().highlightColor;
                                GUI.DrawTexture(rect, NodeEditorResources.dotOuter);
                            }

                            GUI.color = portColor;
                            GUI.DrawTexture(rect, NodeEditorResources.dot);
                            if (rect.Overlaps(selectionBox))
                            {
                                selection.Add(rerouteRef);
                            }
                            if (rect.Contains(mousePos))
                            {
                                hoveredReroute = rerouteRef;
                            }
                        }
                    }
                }
            }
            GUI.color = col;
            if (Event.current.type != EventType.Layout && currentActivity == NodeActivity.DragGrid)
            {
                selectedReroutes = selection;
            }
        }
예제 #23
0
 // GetValue should be overridden to return a value for any specified output port
 public override object GetValue(XNode.NodePort port)
 {
     return(this);
 }
예제 #24
0
        /// <summary> Make a field for a serialized property. Manual node port override. </summary>
        public static void PropertyField(SerializedProperty property, GUIContent label, XNode.NodePort port, bool includeChildren = true, params GUILayoutOption[] options)
        {
            if (property == null)
            {
                throw new NullReferenceException();
            }

            // If property is not a port, display a regular property field
            if (port == null)
            {
                EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
            }
            else
            {
                Rect rect = new Rect();

                // If property is an input, display a regular property field and put a port handle on the left side
                if (port.direction == XNode.NodePort.IO.Input)
                {
                    // Get data from [Input] attribute
                    XNode.Node.ShowBackingValue showBacking = XNode.Node.ShowBackingValue.Unconnected;
                    XNode.Node.InputAttribute   inputAttribute;
                    if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out inputAttribute))
                    {
                        showBacking = inputAttribute.backingValue;
                    }

                    switch (showBacking)
                    {
                    case XNode.Node.ShowBackingValue.Unconnected:
                        // Display a label if port is connected
                        if (port.IsConnected)
                        {
                            EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName));
                        }
                        // Display an editable property field if port is not connected
                        else
                        {
                            EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        }
                        break;

                    case XNode.Node.ShowBackingValue.Never:
                        // Display a label
                        EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName));
                        break;

                    case XNode.Node.ShowBackingValue.Always:
                        // Display an editable property field
                        EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        break;
                    }

                    rect          = GUILayoutUtility.GetLastRect();
                    rect.position = rect.position - new Vector2(16, 0);
                    // If property is an output, display a text label and put a port handle on the right side
                }
                else if (port.direction == XNode.NodePort.IO.Output)
                {
                    // Get data from [Output] attribute
                    XNode.Node.ShowBackingValue showBacking = XNode.Node.ShowBackingValue.Unconnected;
                    XNode.Node.OutputAttribute  outputAttribute;
                    if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out outputAttribute))
                    {
                        showBacking = outputAttribute.backingValue;
                    }

                    switch (showBacking)
                    {
                    case XNode.Node.ShowBackingValue.Unconnected:
                        // Display a label if port is connected
                        if (port.IsConnected)
                        {
                            EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.outputPort, GUILayout.MinWidth(30));
                        }
                        // Display an editable property field if port is not connected
                        else
                        {
                            EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        }
                        break;

                    case XNode.Node.ShowBackingValue.Never:
                        // Display a label
                        EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.outputPort, GUILayout.MinWidth(30));
                        break;

                    case XNode.Node.ShowBackingValue.Always:
                        // Display an editable property field
                        EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
                        break;
                    }

                    rect          = GUILayoutUtility.GetLastRect();
                    rect.position = rect.position + new Vector2(rect.width, 0);
                }

                rect.size = new Vector2(16, 16);

                Color backgroundColor = new Color32(90, 97, 105, 255);
                if (NodeEditorWindow.nodeTint.ContainsKey(port.node.GetType()))
                {
                    backgroundColor *= NodeEditorWindow.nodeTint[port.node.GetType()];
                }
                Color col = NodeGraphEditor.GetEditor(port.node.graph).GetTypeColor(port.ValueType);
                DrawPortHandle(rect, backgroundColor, col);

                // Register the handle position
                Vector2 portPos = rect.center;
                if (NodeEditor.portPositions.ContainsKey(port))
                {
                    NodeEditor.portPositions[port] = portPos;
                }
                else
                {
                    NodeEditor.portPositions.Add(port, portPos);
                }
            }
        }
예제 #25
0
 /// <summary> Make a field for a serialized property. Manual node port override. </summary>
 public static void PropertyField(SerializedProperty property, XNode.NodePort port, bool includeChildren = true, params GUILayoutOption[] options)
 {
     PropertyField(property, null, port, includeChildren, options);
 }
예제 #26
0
        public void DrawList(ReorderableList list)
        {
            IList l = list.list;

            if (chatNode == null)
            {
                chatNode = target as ChatNode;
            }


            if (dialogueGraph == null)
            {
                dialogueGraph = window.graph as DialogueGraph;
            }

            tAsset = dialogueGraph.GetAsset();

            if (tAsset != null)
            {
                foreach (var person in tAsset.persons)
                {
                    //Debug.Log("角色名" + person.Name);
                    chatNode.tPersonNameList.Add(person.Name);
                }
            }

            //获取序列化后的chatslist数据
            SerializedProperty arrayData = serializedObject.FindProperty(fieldName);
            bool hasArrayData            = arrayData != null && arrayData.isArray;

            list.drawHeaderCallback = (Rect rect) => {
                // Debug.Log("AAAAAAAAAAAAAAAAA");
                string title = "对话列表";
                GUI.Label(rect, title);
            };

            list.drawElementCallback = (Rect rect, int index, bool selected, bool focused) =>
            {
                //if (MilliSeconds() < lastBodyGUITime + 100)
                //{
                //    return;
                //}

                //lastBodyGUITime = MilliSeconds();


                #region 自定义渲染动态节点

                XNode.Node     node = serializedObject.targetObject as XNode.Node;
                XNode.NodePort port = node.GetPort(fieldName + " " + index);

                EditorGUI.LabelField(rect, "");
                if (port != null && chatNode.chatslist[index].chatType == ChatType.option || chatNode.chatslist[index].chatType == ChatType.jump)
                {
                    Vector2 pos = rect.position + (port.IsOutput ? new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
                    NodeEditorGUILayout.PortField(pos, port);
                }

                #endregion

                #region 详细定义每个元素的位置



                // 设置属性名宽度
                //EditorGUIUtility.labelWidth = 1;
                Rect position = rect;
                position.height = EditorGUIUtility.singleLineHeight;

                //单个singlechatclass数据
                SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);
                if (chatNode.chatslist[index].chatType == ChatType.cEvent || chatNode.chatslist[index].chatType == ChatType.pause)
                {
                    //这里用原本的对话内容代替停止的时间


                    Rect typeRect = new Rect(position)
                    {
                        width  = 130,
                        y      = position.y + 5,
                        height = 20
                    };

                    Rect methodNameRect = new Rect(typeRect)
                    {
                        width  = position.width - 140,
                        x      = position.x + 140,
                        height = 20
                    };

                    SerializedProperty content_Timeproperty = itemData.FindPropertyRelative("content");
                    SerializedProperty typeproperty         = itemData.FindPropertyRelative("chatType");

                    content_Timeproperty.stringValue = EditorGUI.TextArea(methodNameRect, content_Timeproperty.stringValue);

                    SingleChatClass temp = chatNode.chatslist[index];
                    ChatType        ty   = new ChatType();
                    ty = (ChatType)EditorGUI.EnumPopup(typeRect, temp.chatType);

                    typeproperty.enumValueIndex = (int)ty;
                }
                else
                {
                    Rect iconRect = new Rect(position)
                    {
                        width  = 50,
                        height = 50
                    };

                    Rect nameTypeRect = new Rect(position)
                    {
                        width = position.width - 270,
                        x     = position.x + 60
                    };

                    Rect typeRect = new Rect(nameTypeRect)
                    {
                        width  = position.width - 270,
                        y      = nameTypeRect.y + EditorGUIUtility.singleLineHeight + 7,
                        height = 20
                    };
                    Rect contentRect = new Rect(position)
                    {
                        width  = position.width - 140,
                        height = 50,
                        x      = position.x + 140
                    };

                    iconProperty = itemData.FindPropertyRelative("emoji");
                    SerializedProperty nameProperty    = itemData.FindPropertyRelative("name");
                    SerializedProperty contentproperty = itemData.FindPropertyRelative("content");
                    SerializedProperty typeproperty    = itemData.FindPropertyRelative("chatType");



                    iconProperty.objectReferenceValue =
                        EditorGUI.ObjectField(iconRect, iconProperty.objectReferenceValue, typeof(Sprite), false);



                    SingleChatClass temp = chatNode.chatslist[index];

                    nameProperty.intValue = EditorGUI.Popup(nameTypeRect, temp.name, chatNode.tPersonNameList.ToArray());

                    ChatType ty = new ChatType();
                    ty = (ChatType)EditorGUI.EnumPopup(typeRect, temp.chatType);

                    typeproperty.enumValueIndex = (int)ty;

                    contentproperty.stringValue =
                        EditorGUI.TextArea(contentRect, contentproperty.stringValue);
                }


                #endregion
            };

            list.elementHeightCallback = (int index) => {
                //Debug.Log("CCCCCCCCCCCCCCCCC");
                if (hasArrayData)
                {
                    if (arrayData.arraySize <= index)
                    {
                        return(EditorGUIUtility.singleLineHeight);
                    }
                    SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);

                    if (chatNode.chatslist[index].chatType == ChatType.cEvent || chatNode.chatslist[index].chatType == ChatType.pause)
                    {
                        return(EditorGUI.GetPropertyHeight(itemData) + 12);
                    }

                    return(EditorGUI.GetPropertyHeight(itemData) + 36);
                }
                else
                {
                    return(EditorGUIUtility.singleLineHeight);
                }
            };
        }
예제 #27
0
 public override object GetValue(XNode.NodePort port)
 {
     return(GetInputValue <object>("input"));
 }
예제 #28
0
        public void Controls()
        {
            wantsMouseMove = true;
            Event e = Event.current;

            switch (e.type)
            {
            case EventType.MouseMove:
                break;

            case EventType.ScrollWheel:
                float oldZoom = zoom;
                if (e.delta.y > 0)
                {
                    zoom += 0.1f * zoom;
                }
                else
                {
                    zoom -= 0.1f * zoom;
                }
                if (NodeEditorPreferences.GetSettings().zoomToMouse)
                {
                    panOffset += (1 - oldZoom / zoom) * (WindowToGridPosition(e.mousePosition) + panOffset);
                }
                break;

            case EventType.MouseDrag:
                if (e.button == 0)
                {
                    if (IsDraggingPort)
                    {
                        if (IsHoveringPort && hoveredPort.IsInput && draggedOutput.CanConnectTo(hoveredPort))
                        {
                            if (!draggedOutput.IsConnectedTo(hoveredPort))
                            {
                                draggedOutputTarget = hoveredPort;
                            }
                        }
                        else
                        {
                            draggedOutputTarget = null;
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldNode)
                    {
                        RecalculateDragOffsets(e);
                        currentActivity = NodeActivity.DragNode;
                        Repaint();
                    }
                    if (currentActivity == NodeActivity.DragNode)
                    {
                        // Holding ctrl inverts grid snap
                        bool gridSnap = NodeEditorPreferences.GetSettings().gridSnap;
                        if (e.control)
                        {
                            gridSnap = !gridSnap;
                        }

                        Vector2 mousePos = WindowToGridPosition(e.mousePosition);
                        // Move selected nodes with offset
                        for (int i = 0; i < Selection.objects.Length; i++)
                        {
                            if (Selection.objects[i] is XNode.Node)
                            {
                                XNode.Node node    = Selection.objects[i] as XNode.Node;
                                Vector2    initial = node.position;
                                node.position = mousePos + dragOffset[i];
                                if (gridSnap)
                                {
                                    node.position.x = (Mathf.Round((node.position.x + 8) / 16) * 16) - 8;
                                    node.position.y = (Mathf.Round((node.position.y + 8) / 16) * 16) - 8;
                                }

                                // Offset portConnectionPoints instantly if a node is dragged so they aren't delayed by a frame.
                                Vector2 offset = node.position - initial;
                                if (offset.sqrMagnitude > 0)
                                {
                                    foreach (XNode.NodePort output in node.Outputs)
                                    {
                                        Rect rect;
                                        if (portConnectionPoints.TryGetValue(output, out rect))
                                        {
                                            rect.position += offset;
                                            portConnectionPoints[output] = rect;
                                        }
                                    }

                                    foreach (XNode.NodePort input in node.Inputs)
                                    {
                                        Rect rect;
                                        if (portConnectionPoints.TryGetValue(input, out rect))
                                        {
                                            rect.position += offset;
                                            portConnectionPoints[input] = rect;
                                        }
                                    }
                                }
                            }
                        }
                        // Move selected reroutes with offset
                        for (int i = 0; i < selectedReroutes.Count; i++)
                        {
                            Vector2 pos = mousePos + dragOffset[Selection.objects.Length + i];
                            if (gridSnap)
                            {
                                pos.x = (Mathf.Round(pos.x / 16) * 16);
                                pos.y = (Mathf.Round(pos.y / 16) * 16);
                            }
                            selectedReroutes[i].SetPoint(pos);
                        }
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.HoldGrid)
                    {
                        currentActivity        = NodeActivity.DragGrid;
                        preBoxSelection        = Selection.objects;
                        preBoxSelectionReroute = selectedReroutes.ToArray();
                        dragBoxStart           = WindowToGridPosition(e.mousePosition);
                        Repaint();
                    }
                    else if (currentActivity == NodeActivity.DragGrid)
                    {
                        Vector2 boxStartPos = GridToWindowPosition(dragBoxStart);
                        Vector2 boxSize     = e.mousePosition - boxStartPos;
                        if (boxSize.x < 0)
                        {
                            boxStartPos.x += boxSize.x; boxSize.x = Mathf.Abs(boxSize.x);
                        }
                        if (boxSize.y < 0)
                        {
                            boxStartPos.y += boxSize.y; boxSize.y = Mathf.Abs(boxSize.y);
                        }
                        selectionBox = new Rect(boxStartPos, boxSize);
                        Repaint();
                    }
                }
                else if (e.button == 1 || e.button == 2)
                {
                    panOffset += e.delta * zoom;
                    isPanning  = true;
                }
                break;

            case EventType.MouseDown:
                Repaint();
                if (e.button == 0)
                {
                    draggedOutputReroutes.Clear();

                    if (IsHoveringPort)
                    {
                        if (hoveredPort.IsOutput)
                        {
                            draggedOutput = hoveredPort;
                        }
                        else
                        {
                            hoveredPort.VerifyConnections();
                            if (hoveredPort.IsConnected)
                            {
                                XNode.Node     node   = hoveredPort.node;
                                XNode.NodePort output = hoveredPort.Connection;
                                int            outputConnectionIndex = output.GetConnectionIndex(hoveredPort);
                                draggedOutputReroutes = output.GetReroutePoints(outputConnectionIndex);
                                hoveredPort.Disconnect(output);
                                draggedOutput       = output;
                                draggedOutputTarget = hoveredPort;
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                            }
                        }
                    }
                    else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                    {
                        // If mousedown on node header, select or deselect
                        if (!Selection.Contains(hoveredNode))
                        {
                            SelectNode(hoveredNode, e.control || e.shift);
                            if (!e.control && !e.shift)
                            {
                                selectedReroutes.Clear();
                            }
                        }
                        else if (e.control || e.shift)
                        {
                            DeselectNode(hoveredNode);
                        }

                        // Cache double click state, but only act on it in MouseUp - Except ClickCount only works in mouseDown.
                        isDoubleClick = (e.clickCount == 2);

                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    else if (IsHoveringReroute)
                    {
                        // If reroute isn't selected
                        if (!selectedReroutes.Contains(hoveredReroute))
                        {
                            // Add it
                            if (e.control || e.shift)
                            {
                                selectedReroutes.Add(hoveredReroute);
                            }
                            // Select it
                            else
                            {
                                selectedReroutes = new List <RerouteReference>()
                                {
                                    hoveredReroute
                                };
                                Selection.activeObject = null;
                            }
                        }
                        // Deselect
                        else if (e.control || e.shift)
                        {
                            selectedReroutes.Remove(hoveredReroute);
                        }
                        e.Use();
                        currentActivity = NodeActivity.HoldNode;
                    }
                    // If mousedown on grid background, deselect all
                    else if (!IsHoveringNode)
                    {
                        currentActivity = NodeActivity.HoldGrid;
                        if (!e.control && !e.shift)
                        {
                            selectedReroutes.Clear();
                            Selection.activeObject = null;
                        }
                    }
                }
                break;

            case EventType.MouseUp:
                if (e.button == 0)
                {
                    //Port drag release
                    if (IsDraggingPort)
                    {
                        //If connection is valid, save it
                        if (draggedOutputTarget != null)
                        {
                            XNode.Node node = draggedOutputTarget.node;
                            if (graph.nodes.Count != 0)
                            {
                                draggedOutput.Connect(draggedOutputTarget);
                            }

                            // ConnectionIndex can be -1 if the connection is removed instantly after creation
                            int connectionIndex = draggedOutput.GetConnectionIndex(draggedOutputTarget);
                            if (connectionIndex != -1)
                            {
                                draggedOutput.GetReroutePoints(connectionIndex).AddRange(draggedOutputReroutes);
                                if (NodeEditor.onUpdateNode != null)
                                {
                                    NodeEditor.onUpdateNode(node);
                                }
                                EditorUtility.SetDirty(graph);
                            }
                        }
                        //Release dragged connection
                        draggedOutput       = null;
                        draggedOutputTarget = null;
                        EditorUtility.SetDirty(graph);
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (currentActivity == NodeActivity.DragNode)
                    {
                        IEnumerable <XNode.Node> nodes = Selection.objects.Where(x => x is XNode.Node).Select(x => x as XNode.Node);
                        foreach (XNode.Node node in nodes)
                        {
                            EditorUtility.SetDirty(node);
                        }
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }
                    else if (!IsHoveringNode)
                    {
                        // If click outside node, release field focus
                        if (!isPanning)
                        {
                            EditorGUI.FocusTextInControl(null);
                            EditorGUIUtility.editingTextField = false;
                        }
                        if (NodeEditorPreferences.GetSettings().autoSave)
                        {
                            AssetDatabase.SaveAssets();
                        }
                    }

                    // If click node header, select it.
                    if (currentActivity == NodeActivity.HoldNode && !(e.control || e.shift))
                    {
                        selectedReroutes.Clear();
                        SelectNode(hoveredNode, false);

                        // Double click to center node
                        if (isDoubleClick)
                        {
                            Vector2 nodeDimension = nodeSizes.ContainsKey(hoveredNode) ? nodeSizes[hoveredNode] / 2 : Vector2.zero;
                            panOffset = -hoveredNode.position - nodeDimension;
                        }
                    }

                    // If click reroute, select it.
                    if (IsHoveringReroute && !(e.control || e.shift))
                    {
                        selectedReroutes = new List <RerouteReference>()
                        {
                            hoveredReroute
                        };
                        Selection.activeObject = null;
                    }

                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                else if (e.button == 1 || e.button == 2)
                {
                    if (!isPanning)
                    {
                        if (IsDraggingPort)
                        {
                            draggedOutputReroutes.Add(WindowToGridPosition(e.mousePosition));
                        }
                        else if (currentActivity == NodeActivity.DragNode && Selection.activeObject == null && selectedReroutes.Count == 1)
                        {
                            selectedReroutes[0].InsertPoint(selectedReroutes[0].GetPoint());
                            selectedReroutes[0] = new RerouteReference(selectedReroutes[0].port, selectedReroutes[0].connectionIndex, selectedReroutes[0].pointIndex + 1);
                        }
                        else if (IsHoveringReroute)
                        {
                            ShowRerouteContextMenu(hoveredReroute);
                        }
                        else if (IsHoveringPort)
                        {
                            ShowPortContextMenu(hoveredPort);
                        }
                        else if (IsHoveringNode && IsHoveringTitle(hoveredNode))
                        {
                            if (!Selection.Contains(hoveredNode))
                            {
                                SelectNode(hoveredNode, false);
                            }
                            GenericMenu menu = new GenericMenu();
                            NodeEditor.GetEditor(hoveredNode).AddContextMenuItems(menu);
                            menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
                            e.Use();     // Fixes copy/paste context menu appearing in Unity 5.6.6f2 - doesn't occur in 2018.3.2f1 Probably needs to be used in other places.
                        }
                        else if (!IsHoveringNode)
                        {
                            GenericMenu menu = new GenericMenu();
                            graphEditor.AddContextMenuItems(menu);
                            menu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
                        }
                    }
                    isPanning = false;
                }
                // Reset DoubleClick
                isDoubleClick = false;
                break;

            case EventType.KeyDown:
                if (EditorGUIUtility.editingTextField)
                {
                    break;
                }
                else if (e.keyCode == KeyCode.F)
                {
                    Home();
                }
                if (IsMac())
                {
                    if (e.keyCode == KeyCode.Return)
                    {
                        RenameSelectedNode();
                    }
                }
                else
                {
                    if (e.keyCode == KeyCode.F2)
                    {
                        RenameSelectedNode();
                    }
                }
                break;

            case EventType.ValidateCommand:
            case EventType.ExecuteCommand:
                if (e.commandName == "SoftDelete")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        RemoveSelectedNodes();
                    }
                    e.Use();
                }
                else if (IsMac() && e.commandName == "Delete")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        RemoveSelectedNodes();
                    }
                    e.Use();
                }
                else if (e.commandName == "Duplicate")
                {
                    if (e.type == EventType.ExecuteCommand)
                    {
                        DuplicateSelectedNodes();
                    }
                    e.Use();
                }
                Repaint();
                break;

            case EventType.Ignore:
                // If release mouse outside window
                if (e.rawType == EventType.MouseUp && currentActivity == NodeActivity.DragGrid)
                {
                    Repaint();
                    currentActivity = NodeActivity.Idle;
                }
                break;
            }
        }
예제 #29
0
 public override object GetValue(XNode.NodePort port)
 {
     return(new ModuleWrapper(GetModule()));
 }
예제 #30
0
 public virtual Color GetPortColor(XNode.NodePort port)
 {
     return(GetTypeColor(port.ValueType));
 }