Exemplo n.º 1
0
        /// <summary>
        /// Creates a graph link between the two specified pins
        /// </summary>
        /// <typeparam name="T">The type of the link. Should be GraphLink or one of its subclass</typeparam>
        /// <param name="output">The output pin from where the link originates</param>
        /// <param name="input">The input pin, where the link points to</param>
        /// <returns></returns>
        public static T CreateLink <T>(Graph graph, GraphPin output, GraphPin input) where T : GraphLink
        {
            // Make sure the pin types are correct
            if (output.PinType != GraphPinType.Output || input.PinType != GraphPinType.Input)
            {
                throw new System.ApplicationException("Invalid pin types while creating a link");
            }

            if (!GraphSchema.CanCreateLink(output, input))
            {
                return(null);
            }

            // Make sure a link doesn't already exists
            foreach (T link in graph.Links)
            {
                if (link.Input == input && link.Output == output)
                {
                    return(link);
                }
            }

            {
                Undo.RecordObject(graph, "Create Link");

                T link = CreateLink <T>(graph);
                link.Input  = input;
                link.Output = output;

                Undo.RegisterCreatedObjectUndo(link, "Create Link");
                return(link);
            }
        }
 public void Destroy()
 {
     UnityEngine.Object.DestroyImmediate(mousePin);
     UnityEngine.Object.DestroyImmediate(link);
     mousePin = null;
     link     = null;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Shows the context menu in the theme graph editor
        /// </summary>
        /// <param name="graph">The graph shown in the graph editor</param>
        /// <param name="sourcePin">The source pin, if the user dragged a link out of a pin. null otherwise</param>
        /// <param name="mouseWorld">The position of the mouse. The context menu would be shown from here</param>
        public void Show(Graph graph, GraphPin sourcePin, Vector2 mouseWorld)
        {
            showItemMeshNode          = false;
            showItemMarkerNode        = false;
            showItemMarkerEmitterNode = false;
            this.sourcePin            = sourcePin;
            this.mouseWorldPosition   = mouseWorld;
            if (sourcePin.Node is MarkerNode)
            {
                showItemMeshNode = true;
            }
            else if (sourcePin.Node is VisualNode)
            {
                if (sourcePin.PinType == GraphPinType.Input)
                {
                    // We can only create marker nodes from here
                    showItemMarkerNode = true;
                }
                else
                {
                    // We can only create marker emitter nodes from here
                    showItemMarkerEmitterNode = true;
                }
            }
            else if (sourcePin.Node is MarkerEmitterNode)
            {
                // we can only create mesh nodes from the input pin of this node
                showItemMeshNode = true;
            }

            ShowMenu(graph);
        }
        public void Draw(GraphRendererContext rendererContext, GraphCamera camera)
        {
            if (!active)
            {
                return;
            }

            var mouseWorld = camera.ScreenToWorld(mouseScreenPosition);

            mousePin.Position = mouseWorld;


            GraphLinkRenderer.DrawGraphLink(rendererContext, link, camera);

            // Check the pin that comes under the mouse pin
            var targetPin = graphEditor.GetPinUnderPosition(mouseWorld);

            if (targetPin != null)
            {
                var sourcePin = attachedPin;
                var pins      = new GraphPin[] { sourcePin, targetPin };
                Array.Sort(pins, new GraphPinHierarchyComparer());
                string errorMessage;
                if (!GraphSchema.CanCreateLink(pins[0], pins[1], out errorMessage))
                {
                    GraphTooltip.message = errorMessage;
                }
            }
        }
        void CreateLinkBetweenPins(GraphPin outputPin, GraphPin inputPin)
        {
            if (outputPin.PinType != GraphPinType.Output && inputPin.PinType != GraphPinType.Input)
            {
                Debug.LogError("Pin type mismatch");
                return;
            }

            // Make sure they are not from the same node
            if (outputPin.Node == inputPin.Node)
            {
                Debug.LogError("Linking pins from the same node");
                return;
            }

            // Create a link
            var link = GraphOperations.CreateLink <GraphLink>(graph, outputPin, inputPin);

            if (link != null)
            {
                DungeonEditorHelper.AddToAsset(graph, link);
                graph.NotifyStateChanged();
            }
            else
            {
                Debug.Log("GraphSchema: Link not allowed");
            }
        }
Exemplo n.º 6
0
 // Breaks all the links attached to the pin
 private static void BreakLinks(GraphPin pin)
 {
     GraphLink[] links = pin.GetConntectedLinks();
     foreach (var link in links)
     {
         DestroyLink(link);
     }
 }
        // Called when the mouse is released after dragging a link out of an existing pin
        void HandleMouseDraggedLinkReleased(Vector2 mousePositionScreen)
        {
            var mouseWorld = camera.ScreenToWorld(mousePositionScreen);
            var sourcePin  = cursorDragLink.AttachedPin;

            // Check if the mouse was released over a pin
            GraphPin targetPin = null;

            GraphNode[] sortedNodes = graph.Nodes.ToArray();
            System.Array.Sort(sortedNodes, new NodeReversedZIndexComparer());

            foreach (var node in sortedNodes)
            {
                if (node.Bounds.Contains(mouseWorld))
                {
                    // Check if we are above a pin in this node
                    var pins = new List <GraphPin>();
                    pins.AddRange(node.InputPins);
                    pins.AddRange(node.OutputPins);
                    foreach (var pin in pins)
                    {
                        if (pin.ContainsPoint(mouseWorld))
                        {
                            targetPin = pin;
                            break;
                        }
                    }
                    break;
                }
            }

            if (targetPin != null)
            {
                if (sourcePin.PinType != targetPin.PinType)
                {
                    GraphPin source, target;
                    if (sourcePin.PinType == GraphPinType.Output)
                    {
                        source = sourcePin;
                        target = targetPin;
                    }
                    else
                    {
                        source = targetPin;
                        target = sourcePin;
                    }
                    if (source.Node != target.Node)
                    {
                        CreateLinkBetweenPins(source, target);
                    }
                }
            }
            else
            {
                // We stopped drag on an empty space.  Show a context menu to allow user to create nodes from this position
                contextMenu.Show(graph, sourcePin, mouseWorld);
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Show the context menu
 /// </summary>
 /// <param name="graph">The owning graph</param>
 public void Show(Graph graph)
 {
     showItemMeshNode          = true;
     showItemMarkerNode        = true;
     showItemMarkerEmitterNode = true;
     sourcePin          = null;
     mouseWorldPosition = Vector2.zero;
     ShowMenu(graph);
 }
 public void Activate(GraphPin fromPin)
 {
     active                   = true;
     attachedPin              = fromPin;
     mousePin.PinType         = (attachedPin.PinType == GraphPinType.Input) ? GraphPinType.Output : GraphPinType.Input;
     mousePin.Tangent         = -attachedPin.Tangent;
     mousePin.TangentStrength = attachedPin.TangentStrength;
     AttachPinToLink(mousePin);
     AttachPinToLink(attachedPin);
 }
 void AttachPinToLink(GraphPin pin)
 {
     if (pin.PinType == GraphPinType.Input)
     {
         link.Input = pin;
     }
     else
     {
         link.Output = pin;
     }
 }
Exemplo n.º 11
0
        /// <summary>
        /// Destroys all links connected to this pin
        /// </summary>
        private static void DestroyPinLinks(GraphPin pin)
        {
            var pinLinks = pin.GetConntectedLinks();

            foreach (var link in pinLinks)
            {
                GraphOperations.DestroyLink(link);
            }

            pin.NotifyPinLinksDestroyed();
        }
Exemplo n.º 12
0
        /// <summary>
        /// Handles the mouse input and returns true if handled
        /// </summary>
        public static bool HandlePinInput(GraphPin pin, Event e, GraphEditor graphEditor)
        {
            var camera               = graphEditor.Camera;
            var mousePosition        = e.mousePosition;
            var mousePositionWorld   = camera.ScreenToWorld(mousePosition);
            int buttonIdDrag         = 0;
            int buttonIdDestroyLinks = 1;

            if (pin.ContainsPoint(mousePositionWorld))
            {
                if (e.type == EventType.MouseDown && e.button == buttonIdDrag)
                {
                    pin.ClickState = GraphPinMouseState.Clicked;
                    return(true);
                }

                if (e.button == buttonIdDestroyLinks)
                {
                    if (e.type == EventType.MouseDown)
                    {
                        pin.RequestLinkDeletionInitiated = true;
                    }
                    else if (e.type == EventType.MouseDrag)
                    {
                        pin.RequestLinkDeletionInitiated = false;
                    }
                    else if (e.type == EventType.MouseUp)
                    {
                        if (pin.RequestLinkDeletionInitiated)
                        {
                            DestroyPinLinks(pin);
                            if (pin.Node != null && pin.Node.Graph != null)
                            {
                                graphEditor.HandleGraphStateChanged();
                            }
                        }
                    }
                    return(true);
                }

                if (pin.ClickState != GraphPinMouseState.Clicked)
                {
                    pin.ClickState = GraphPinMouseState.Hover;
                }
            }
            else
            {
                pin.ClickState = GraphPinMouseState.None;
            }

            return(false);
        }
        public CursorDragLink(GraphEditor graphEditor)
        {
            this.graphEditor = graphEditor;
            mousePin         = ScriptableObject.CreateInstance <GraphPin>();
            mousePin.PinType = GraphPinType.Input;
            mousePin.name    = "Cursor_DragPin";

            link      = ScriptableObject.CreateInstance <GraphLink>();
            link.name = "Cursor_DragLink";

            mousePin.hideFlags = HideFlags.HideAndDontSave;
            link.hideFlags     = HideFlags.HideAndDontSave;
        }
Exemplo n.º 14
0
        static Color GetPinColor(GraphPin pin)
        {
            Color color;

            if (pin.ClickState == GraphPinMouseState.Clicked)
            {
                color = GraphEditorConstants.PIN_COLOR_CLICK;
            }
            else if (pin.ClickState == GraphPinMouseState.Hover)
            {
                color = GraphEditorConstants.PIN_COLOR_HOVER;
            }
            else
            {
                color = GraphEditorConstants.PIN_COLOR;
            }
            return(color);
        }
Exemplo n.º 15
0
        public static void Draw(GraphRendererContext rendererContext, GraphPin pin, GraphCamera camera)
        {
            var pinBounds      = new Rect(pin.GetBounds());
            var positionWorld  = pin.Node.Position + pinBounds.position;
            var positionScreen = camera.WorldToScreen(positionWorld);

            pinBounds.position = positionScreen;
            pinBounds.size    /= camera.ZoomLevel;

            var originalColor = GUI.backgroundColor;

            GUI.backgroundColor = GetPinColor(pin);
            GUI.Box(pinBounds, "");
            GUI.backgroundColor = originalColor;

            // Draw the pin texture
            var pinTexture = rendererContext.Resources.GetResource <Texture2D>(DungeonEditorResources.TEXTURE_PIN_GLOW);

            if (pinTexture != null)
            {
                GUI.DrawTexture(pinBounds, pinTexture);
            }
        }
Exemplo n.º 16
0
        protected bool BuildChoices(GraphPin inputPin, List <DialogueFragment> fragments)
        {
            DialoguePin pin = inputPin as DialoguePin;

            if (pin == null)
            {
                return(false);
            }

            BaseDialogueObject obj = pin.Node as BaseDialogueObject;

            if (obj == null)
            {
                return(false);
            }

            if (pin.Type == GraphPin.PinType.Output && obj is Dialogue)
            {
                return(true);                // connection to a dialogue output is reached so it's the end of the dialogue
            }
            bool processObject = true;

            if (pin.Script != null)
            {
                dynamic result = pin.Script.Run(this);
                if (pin.Type == GraphPin.PinType.Input)
                {
                    if (!(result is Boolean))
                    {
                        GameDebugger.Log(LogLevel.Warning, "One of input pins script on dialogue object '0x{0:X16}' exits with a non boolean result ({1})", obj.Id, result.GetType().Name);
                        return(true);                 // end the dialogue due to error
                    }
                    if (!result)                      // input pin is a condition. if it returns false, then object is not processed
                    {
                        processObject = false;
                    }
                }
            }

            if (processObject && !(obj is Dialogue) && pin.Type == GraphPin.PinType.Input)
            {
                if (BuildChoices(obj, fragments))
                {
                    return(true);
                }
            }

            foreach (GraphConnection conn in pin.Connections)
            {
                if (conn.Target == pin)
                {
                    continue;                             // ignore incoming connections
                }
                if (BuildChoices(conn.Target, fragments)) // recursion through connections
                {
                    return(true);
                }
            }

            return(false);
        }
        void OnMenuItemClicked(GraphMenuAction action, GraphContextMenuEvent e)
        {
            var       mouseScreen = lastMousePosition;
            GraphNode node        = null;

            if (action == GraphMenuAction.AddGameObjectNode)
            {
                node = CreateNode <GameObjectNode>(mouseScreen);
                SelectNode(node);
            }
            else if (action == GraphMenuAction.AddSpriteNode)
            {
                node = CreateNode <SpriteNode>(mouseScreen);
                SelectNode(node);
            }
            else if (action == GraphMenuAction.AddMarkerNode)
            {
                node = CreateNode <MarkerNode>(mouseScreen);
                SelectNode(node);
            }
            else if (action == GraphMenuAction.AddMarkerEmitterNode)
            {
                if (e.userdata != null)
                {
                    var markerName = e.userdata as String;
                    node = CreateMarkerEmitterNode(mouseScreen, markerName);
                    if (node != null)
                    {
                        SelectNode(node);
                    }
                }
            }


            if (node != null)
            {
                // Check if the menu was created by dragging out a link
                if (e.sourcePin != null)
                {
                    GraphPin targetPin =
                        e.sourcePin.PinType == GraphPinType.Input ?
                        node.OutputPins[0] :
                        node.InputPins[0];

                    // Align the target pin with the mouse position where the link was dragged and released
                    node.Position = e.mouseWorldPosition - targetPin.Position;

                    GraphPin inputPin, outputPin;
                    if (e.sourcePin.PinType == GraphPinType.Input)
                    {
                        inputPin  = e.sourcePin;
                        outputPin = targetPin;
                    }
                    else
                    {
                        inputPin  = targetPin;
                        outputPin = e.sourcePin;
                    }
                    CreateLinkBetweenPins(outputPin, inputPin);
                }
            }
        }
 void HandleDragPin(GraphPin pin)
 {
     cursorDragLink.Activate(pin);
 }
        void HandleDrag(Event e)
        {
            int dragButton = 0;

            if (draggingNodes)
            {
                if (e.type == EventType.MouseUp && e.button == dragButton)
                {
                    draggingNodes = false;
                }
                else if (e.type == EventType.MouseDrag && e.button == dragButton)
                {
                    // Drag all the selected nodes
                    foreach (var node in graph.Nodes)
                    {
                        if (node.Selected)
                        {
                            Undo.RecordObject(node, "Move Node");
                            node.DragNode(e.delta);
                        }
                    }
                }
            }
            else
            {
                // Check if we have started to drag
                if (e.type == EventType.MouseDown && e.button == dragButton)
                {
                    // Find the node that was clicked below the mouse
                    var mousePosition      = e.mousePosition;
                    var mousePositionWorld = camera.ScreenToWorld(mousePosition);

                    // sort the nodes front to back
                    GraphNode[] sortedNodes = graph.Nodes.ToArray();
                    System.Array.Sort(sortedNodes, new NodeReversedZIndexComparer());

                    GraphNode mouseOverNode = null;
                    foreach (var node in sortedNodes)
                    {
                        var mouseOver = node.Bounds.Contains(mousePositionWorld);
                        if (mouseOver)
                        {
                            mouseOverNode = node;
                            break;
                        }
                    }

                    if (mouseOverNode != null && mouseOverNode.Selected)
                    {
                        // Make sure we are not over a pin
                        var pins = new List <GraphPin>();
                        pins.AddRange(mouseOverNode.InputPins);
                        pins.AddRange(mouseOverNode.OutputPins);
                        bool     isOverPin      = false;
                        GraphPin overlappingPin = null;
                        foreach (var pin in pins)
                        {
                            if (pin.ContainsPoint(mousePositionWorld))
                            {
                                isOverPin      = true;
                                overlappingPin = pin;
                                break;
                            }
                        }
                        if (!isOverPin)
                        {
                            draggingNodes = true;
                        }
                        else
                        {
                            HandleDragPin(overlappingPin);
                        }
                    }
                }
            }
        }
Exemplo n.º 20
0
 public override void Show(GraphEditor graphEditor, GraphPin sourcePin, Vector2 mouseWorld)
 {
 }
Exemplo n.º 21
0
 /// <summary>
 /// Shows the context menu in the theme graph editor
 /// </summary>
 /// <param name="graph">The graph shown in the graph editor</param>
 /// <param name="sourcePin">The source pin, if the user dragged a link out of a pin. null otherwise</param>
 /// <param name="mouseWorld">The position of the mouse. The context menu would be shown from here</param>
 public abstract void Show(GraphEditor graphEditor, GraphPin sourcePin, Vector2 mouseWorld);