diff --git a/Source/Editor/Surface/Archetypes/Function.cs b/Source/Editor/Surface/Archetypes/Function.cs
index cffb2ad6f..d027dd8f1 100644
--- a/Source/Editor/Surface/Archetypes/Function.cs
+++ b/Source/Editor/Surface/Archetypes/Function.cs
@@ -2228,6 +2228,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Function Input",
Description = "The graph function input data",
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2247,6 +2248,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Function Output",
Description = "The graph function output data",
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2265,6 +2267,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = string.Empty,
Description = "Overrides the base class method with custom implementation",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2279,6 +2282,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new InvokeMethodNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2302,6 +2306,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ReturnNode(id, context, arch, groupArch),
Title = "Return",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(100, 40),
DefaultValues = new object[]
{
@@ -2320,6 +2325,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "New Function",
Description = "Adds a new function to the script",
Flags = NodeFlags.VisualScriptGraph,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 20),
DefaultValues = new object[]
{
@@ -2332,6 +2338,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new GetFieldNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2347,6 +2354,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new SetFieldNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2363,6 +2371,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new BindEventNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(260, 60),
DefaultValues = new object[]
{
@@ -2385,6 +2394,7 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new UnbindEventNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
+ NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(260, 60),
DefaultValues = new object[]
{
diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
index 7b0ce6c85..f8b7d9d51 100644
--- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
+++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
@@ -3,11 +3,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using FlaxEditor.Scripting;
using FlaxEditor.Surface.Elements;
using FlaxEditor.Utilities;
using FlaxEngine;
using FlaxEngine.GUI;
+using FlaxEngine.Utilities;
namespace FlaxEditor.Surface.ContextMenu
{
@@ -121,13 +123,70 @@ namespace FlaxEditor.Surface.ContextMenu
Visible = true;
return true;
}
-
- if (_archetype?.Elements == null)
+
+ if (_archetype == null)
{
Visible = false;
return false;
}
-
+
+ bool isCompatible = false;
+ if (_archetype.Elements != null)
+ {
+ isCompatible = CheckElementsCompatibility(startBox);
+ }
+
+ if (_archetype.NodeTypeHint == NodeTypeHint.FunctionNode)
+ {
+ isCompatible = false;
+ ScriptMemberInfo memberInfo = ScriptMemberInfo.Null;
+
+ if (_archetype.Tag is ScriptMemberInfo info)
+ {
+ memberInfo = info;
+ }
+ else if(_archetype.DefaultValues is { Length: > 1 })
+ {
+ var eventName = (string)_archetype.DefaultValues[1];
+ var eventType = TypeUtils.GetType((string)_archetype.DefaultValues[0]);
+ memberInfo = eventType.GetMember(eventName, MemberTypes.Event, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
+ }
+
+ if (memberInfo != ScriptMemberInfo.Null)
+ {
+ if (startBox.IsOutput)
+ {
+ var parameters = memberInfo.GetParameters();
+ ScriptType outType = startBox.CurrentType;
+
+ if (!memberInfo.IsStatic)
+ {
+ var scriptType = TypeUtils.GetType((string)_archetype.DefaultValues[0]);
+ isCompatible |= CanCastToType(scriptType, outType, _archetype.ConnectionsHints);
+ }
+
+ if (!memberInfo.IsEvent)
+ {
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ ScriptType inType = parameters[i].Type;
+ isCompatible |= CanCastToType(inType, outType, _archetype.ConnectionsHints);
+ }
+ }
+ }
+ else
+ {
+
+ }
+ }
+ }
+
+ Visible = isCompatible;
+ return isCompatible;
+ }
+
+ private bool CheckElementsCompatibility(Box startBox)
+ {
bool isCompatible = false;
foreach (NodeElementArchetype element in _archetype.Elements)
{
@@ -153,15 +212,12 @@ namespace FlaxEditor.Surface.ContextMenu
hint = startBox.ParentNode.Archetype.ConnectionsHints;
}
- bool checkCompatibility = CanCastToType(inType, outType, hint);
- isCompatible |= checkCompatibility;
+ isCompatible |= CanCastToType(inType, outType, hint);
}
-
- Visible = isCompatible;
-
+
return isCompatible;
}
-
+
private bool CanCastToType(ScriptType currentType, ScriptType type, ConnectionsHint hint)
{
if (VisjectSurface.CanUseDirectCastStatic(type, currentType, false))
diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs
index 6dc923ce2..1cdaee2d2 100644
--- a/Source/Editor/Surface/NodeArchetype.cs
+++ b/Source/Editor/Surface/NodeArchetype.cs
@@ -73,6 +73,20 @@ namespace FlaxEditor.Surface
All = Scalar | Vector | Enum | Anything | Value | Array | Dictionary,
}
+ [HideInEditor]
+ public enum NodeTypeHint
+ {
+ ///
+ /// Is Node.
+ ///
+ Default = 0,
+
+ ///
+ /// Is Function Node.
+ ///
+ FunctionNode = 1,
+ }
+
///
/// Surface node archetype description.
///
@@ -152,6 +166,11 @@ namespace FlaxEditor.Surface
///
public ConnectionsHint ConnectionsHints;
+ ///
+ /// Node Type hints.
+ ///
+ public NodeTypeHint NodeTypeHint;
+
///
/// Array with independent boxes IDs.
///
@@ -193,6 +212,7 @@ namespace FlaxEditor.Surface
DefaultValues = (object[])DefaultValues?.Clone(),
DefaultType = DefaultType,
ConnectionsHints = ConnectionsHints,
+ NodeTypeHint = NodeTypeHint,
IndependentBoxes = (int[])IndependentBoxes?.Clone(),
DependentBoxes = (int[])DependentBoxes?.Clone(),
Elements = (NodeElementArchetype[])Elements?.Clone(),
diff --git a/Source/Editor/Surface/VisualScriptSurface.cs b/Source/Editor/Surface/VisualScriptSurface.cs
index e961f686d..b6c0112a9 100644
--- a/Source/Editor/Surface/VisualScriptSurface.cs
+++ b/Source/Editor/Surface/VisualScriptSurface.cs
@@ -370,7 +370,7 @@ namespace FlaxEditor.Surface
bindNode.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member);
bindNode.SubTitle = string.Format(" (in {0})", scriptTypeName);
((IList)group.Archetypes).Add(bindNode);
-
+
// Add Unbind event node
var unbindNode = (NodeArchetype)Archetypes.Function.Nodes[9].Clone();
unbindNode.DefaultValues[0] = scriptTypeTypeName;
@@ -589,6 +589,7 @@ namespace FlaxEditor.Surface
node.DefaultValues[0] = name;
node.DefaultValues[1] = parameters.Length;
node.Title = "Override " + name;
+ node.Tag = member;
nodes.Add(node);
}
}