示例#1
0
        // Create a connection between two slots.
        public static bool ConnectSlots(Graphs.Slot fromSlot, Graphs.Slot toSlot)
        {
            var nodeTo = ((Node)toSlot.node).runtimeInstance;
            var triggerEvent = GetEventOfOutputSlot(fromSlot);
            var targetMethod = GetMethodOfInputSlot(toSlot);

            // Determine the type of the target action.
            var actionType = GetUnityActionToInvokeMethod(targetMethod);

            if (actionType == null) return false; // invalid target method type

            // Create an action that is bound to the target method.
            var targetAction = Delegate.CreateDelegate(
                actionType, nodeTo, targetMethod
            );

            if (triggerEvent is UnityEvent)
            {
                // The trigger event has no parameter.
                // Add the action to the event with a default parameter.
                if (actionType == typeof(UnityAction))
                {
                    UnityEventTools.AddVoidPersistentListener(
                        triggerEvent, (UnityAction)targetAction
                    );
                    return true;
                }
                if (actionType == typeof(UnityAction<float>))
                {
                    UnityEventTools.AddFloatPersistentListener(
                        triggerEvent, (UnityAction<float>)targetAction, 1.0f
                    );
                    return true;
                }
            }
            else if (triggerEvent is UnityEvent<float>)
            {
                // The trigger event has a float parameter.
                // Then the target method should have a float parameter too.
                if (actionType == typeof(UnityAction<float>))
                {
                    // Add the action to the event.
                    UnityEventTools.AddPersistentListener(
                       (UnityEvent<float>)triggerEvent,
                       (UnityAction<float>)targetAction
                    );
                    return true;
                }
            }
            else if (triggerEvent is UnityEvent<Vector3>)
            {
                // The trigger event has a Vector3 parameter.
                // Then the target method should have a Vector3 parameter too.
                if (actionType == typeof(UnityAction<Vector3>))
                {
                    // Add the action to the event.
                    UnityEventTools.AddPersistentListener(
                       (UnityEvent<Vector3>)triggerEvent,
                       (UnityAction<Vector3>)targetAction
                    );
                    return true;
                }
            }
            else if (triggerEvent is UnityEvent<Quaternion>)
            {
                // The trigger event has a Quaternion parameter.
                // Then the target method should have a Quaternion parameter too.
                if (actionType == typeof(UnityAction<Quaternion>))
                {
                    // Add the action to the event.
                    UnityEventTools.AddPersistentListener(
                       (UnityEvent<Quaternion>)triggerEvent,
                       (UnityAction<Quaternion>)targetAction
                    );
                    return true;
                }
            }
            else if (triggerEvent is UnityEvent<Color>)
            {
                // The trigger event has a color parameter.
                // Then the target method should have a color parameter too.
                if (actionType == typeof(UnityAction<Color>))
                {
                    // Add the action to the event.
                    UnityEventTools.AddPersistentListener(
                       (UnityEvent<Color>)triggerEvent,
                       (UnityAction<Color>)targetAction
                    );
                    return true;
                }
            }

            return false; // trigger-target mismatch
        }
示例#2
0
 // Returns an event instance that is bound to a given output slot.
 static UnityEventBase GetEventOfOutputSlot(Graphs.Slot slot)
 {
     var node = ((Node)slot.node).runtimeInstance;
     var flags = BindingFlags.Instance | BindingFlags.NonPublic;
     var field = node.GetType().GetField(slot.name, flags);
     return (UnityEventBase)field.GetValue(node);
 }
示例#3
0
 // Returns a method that is bound to a given input slot.
 static MethodInfo GetMethodOfInputSlot(Graphs.Slot slot)
 {
     var node = ((Node)slot.node).runtimeInstance;
     return node.GetType().GetMethod(slot.name);
 }
示例#4
0
文件: GraphGUI.cs 项目: keijiro/Klak
        public override void NodeGUI(Graphs.Node node)
        {
            SelectNode(node);

            foreach (var slot in node.inputSlots)
                LayoutSlot(slot, slot.title, false, true, true, Styles.pinIn);

            node.NodeUI(this);

            foreach (var slot in node.outputSlots)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                LayoutSlot(slot, slot.title, true, false, true, Styles.pinOut);
                EditorGUILayout.EndHorizontal();
            }

            DragNodes();
        }
示例#5
0
        // Disconnect given two slots.
        public static void DisconnectSlots(Graphs.Slot fromSlot, Graphs.Slot toSlot)
        {
            var nodeTo = ((Node)toSlot.node).runtimeInstance;
            var triggerEvent = GetEventOfOutputSlot(fromSlot);
            var targetMethod = GetMethodOfInputSlot(toSlot);

            var methodName = targetMethod.Name;

            var eventCount = triggerEvent.GetPersistentEventCount();
            for (var i = 0; i < eventCount; i++)
            {
                if (nodeTo == triggerEvent.GetPersistentTarget(i) &&
                    methodName == triggerEvent.GetPersistentMethodName(i))
                {
                    UnityEventTools.RemovePersistentListener(triggerEvent, i);
                    break;
                }
            }
        }
示例#6
0
文件: Graph.cs 项目: keijiro/Klak
        // Establish a connection between slots.
        public override Graphs.Edge Connect(Graphs.Slot fromSlot, Graphs.Slot toSlot)
        {
            var edge = base.Connect(fromSlot, toSlot);

            if (_isEditing)
            {
                // Make this operation undoable.
                var fromNodeRuntime = ((Node)fromSlot.node).runtimeInstance;
                Undo.RecordObject(fromNodeRuntime, "Create Connection");

                // Add a serialized event.
                ConnectionTools.ConnectSlots(fromSlot, toSlot);

                // Send a repaint request to the inspector window because
                // the inspector is shown at this point in most cases.
                GUIUtility.RepaintAllInspectors();
            }

            return edge;
        }
示例#7
0
文件: Graph.cs 项目: keijiro/Klak
        // Remove a connection between slots.
        public override void RemoveEdge(Graphs.Edge edge)
        {
            if (_isEditing)
            {
                var fromSlot = edge.fromSlot;
                var toSlot = edge.toSlot;

                // Make this operation undoable.
                var fromNodeRuntime = ((Node)fromSlot.node).runtimeInstance;
                Undo.RecordObject(fromNodeRuntime, "Disconnect");

                // Remove the serialized event.
                ConnectionTools.DisconnectSlots(fromSlot, toSlot);
            }

            base.RemoveEdge(edge);
        }
示例#8
0
文件: EdgeGUI.cs 项目: keijiro/Klak
 static Vector2 GetPositionAsToSlot(Graphs.Slot slot)
 {
     var rect = GetSlotPosition(slot);
     return GUIClip(new Vector2(rect.x, rect.y + kEdgeSlotYOffset));
 }
示例#9
0
文件: Graph.cs 项目: keijiro/Klak
 // Check if slots can be connected.
 public override bool CanConnect(Graphs.Slot fromSlot, Graphs.Slot toSlot)
 {
     // If the outlet is bang, any inlet can be connected.
     if (fromSlot.dataType == null) return true;
     // Apply simple type matching.
     return fromSlot.dataType == toSlot.dataType;
 }
示例#10
0
文件: EdgeGUI.cs 项目: keijiro/Klak
 // Accessors for Slot.m_Position
 static Rect GetSlotPosition(Graphs.Slot slot)
 {
     var flags = BindingFlags.NonPublic | BindingFlags.Instance;
     var func = typeof(Graphs.Slot).GetField("m_Position", flags);
     return (Rect)func.GetValue(slot);
 }
示例#11
0
文件: EdgeGUI.cs 项目: keijiro/Klak
 static void DrawEdge(Graphs.Edge edge, Color color)
 {
     var p1 = GetPositionAsFromSlot(edge.fromSlot);
     var p2 = GetPositionAsToSlot(edge.toSlot);
     DrawEdge(p1, p2, color * edge.color);
 }
示例#12
0
文件: EdgeGUI.cs 项目: keijiro/Klak
        public void EndSlotDragging(Graphs.Slot slot, bool allowMultiple)
        {
            Debug.Assert(allowMultiple);

            // Do nothing if no target was specified.
            if (_dropTarget != slot) return;

            // If we're going to modify an existing edge, remove it.
            if (_moveEdge != null) slot.node.graph.RemoveEdge(_moveEdge);

            // Try to connect the edge to the target.
            try
            {
                slot.node.graph.Connect(_dragSourceSlot, slot);
            }
            finally
            {
                EndDragging();
                slot.node.graph.Dirty();
                Event.current.Use();
            }

            UnityEngine.GUIUtility.ExitGUI();
        }
示例#13
0
文件: EdgeGUI.cs 项目: keijiro/Klak
        public void SlotDragging(Graphs.Slot slot, bool allowEndDrag, bool allowMultiple)
        {
            Debug.Assert(allowMultiple);

            if (!allowEndDrag) return;
            if (_dragSourceSlot == null || _dragSourceSlot == slot) return;

            // Is this slot can be a drop target?
            if (_dropTarget != slot &&
                slot.node.graph.CanConnect(_dragSourceSlot, slot) &&
                !slot.node.graph.Connected(_dragSourceSlot, slot))
            {
                _dropTarget = slot;
            }

            Event.current.Use();
        }
示例#14
0
文件: EdgeGUI.cs 项目: keijiro/Klak
        public void BeginSlotDragging(Graphs.Slot slot, bool allowStartDrag, bool allowEndDrag)
        {
            if (allowStartDrag)
            {
                // Start dragging with a new connection.
                _dragSourceSlot = slot;
                Event.current.Use();
            }

            if (allowEndDrag && slot.edges.Count > 0)
            {
                // Start dragging to modify an existing connection.
                _moveEdge = slot.edges[slot.edges.Count - 1];
                _dragSourceSlot = _moveEdge.fromSlot;
                _dropTarget = slot;
                Event.current.Use();
            }
        }