diff --git a/Source/Editor/Scripting/ScriptType.cs b/Source/Editor/Scripting/ScriptType.cs
index ada049c08..10956e9ba 100644
--- a/Source/Editor/Scripting/ScriptType.cs
+++ b/Source/Editor/Scripting/ScriptType.cs
@@ -1106,6 +1106,17 @@ namespace FlaxEditor.Scripting
throw new NotImplementedException("TODO: Script.Type.GetGenericTypeDefinition for custom types");
}
+ ///
+ /// Returns a type object that represents an array of the current type.
+ ///
+ /// A type object representing a one-dimensional array of the current type.
+ public ScriptType MakeArrayType()
+ {
+ if (_managed != null)
+ return new ScriptType(_managed.MakeArrayType());
+ throw new NotImplementedException("TODO: Script.Type.MakeArrayType for custom types");
+ }
+
///
/// Searches for the specified members of the specified member type, using the specified binding constraints.
///
diff --git a/Source/Editor/Windows/Assets/VisualScriptWindow.cs b/Source/Editor/Windows/Assets/VisualScriptWindow.cs
index 729fc71cd..76e0b8797 100644
--- a/Source/Editor/Windows/Assets/VisualScriptWindow.cs
+++ b/Source/Editor/Windows/Assets/VisualScriptWindow.cs
@@ -70,6 +70,83 @@ namespace FlaxEditor.Windows.Assets
}
}
+ private sealed class EditParamTypeAction : IUndoAction
+ {
+ private struct BrokenConnection
+ {
+ public uint ANode;
+ public int ABox;
+ public uint BNode;
+ public int BBox;
+ }
+
+ private List _connectionsToRestore = new List();
+ private List _connectionsToRestorePrev = new List();
+
+ public IVisjectSurfaceWindow Window;
+ public int Index;
+ public ScriptType BeforeType;
+ public object BeforeValue;
+ public ScriptType AfterType;
+ public object AfterValue;
+
+ public string ActionString => "Edit parameter type";
+
+ public void Do()
+ {
+ Set(AfterType, AfterValue);
+ }
+
+ public void Undo()
+ {
+ Set(BeforeType, BeforeValue);
+ }
+
+ private void Set(ScriptType type, object value)
+ {
+ _connectionsToRestore.Clear();
+ Window.VisjectSurface.NodesDisconnected += OnNodesDisconnected;
+ var param = Window.VisjectSurface.Parameters[Index];
+ param.Type = type;
+ param.Value = value;
+ Window.VisjectSurface.OnParamEdited(param);
+ Window.VisjectSurface.NodesDisconnected -= OnNodesDisconnected;
+
+ // Restore connections broken previously
+ foreach (var connection in _connectionsToRestorePrev)
+ {
+ var aNode = Window.VisjectSurface.FindNode(connection.ANode);
+ var bNode = Window.VisjectSurface.FindNode(connection.BNode);
+ var aBox = aNode?.GetBox(connection.ABox) ?? null;
+ var bBox = bNode?.GetBox(connection.BBox) ?? null;
+ if (aBox != null && bBox != null)
+ aBox.CreateConnection(bBox);
+ }
+ _connectionsToRestorePrev.Clear();
+ _connectionsToRestorePrev.AddRange(_connectionsToRestore);
+ }
+
+ private void OnNodesDisconnected(IConnectionInstigator a, IConnectionInstigator b)
+ {
+ // Capture any auto-disconnected boxes after parameter type change to restore them back on undo
+ if (a is Surface.Elements.Box aBox && b is Surface.Elements.Box bBox)
+ {
+ _connectionsToRestore.Add(new BrokenConnection
+ {
+ ANode = aBox.ParentNode.ID, ABox = aBox.ID,
+ BNode = bBox.ParentNode.ID, BBox = bBox.ID,
+ });
+ }
+ }
+
+ public void Dispose()
+ {
+ _connectionsToRestore = null;
+ _connectionsToRestorePrev = null;
+ Window = null;
+ }
+ }
+
private sealed class VisualParametersEditor : ParametersEditor
{
public VisualParametersEditor()
@@ -88,9 +165,55 @@ namespace FlaxEditor.Windows.Assets
var b = cmAccess.ContextMenu.AddButton("Public", () => window.SetParamAccess(index, true));
b.Checked = param.IsPublic;
b.Enabled = window._canEdit;
+ b.TooltipText = "Sets the parameter access level to Public. It will be accessible and visible everywhere.";
b = cmAccess.ContextMenu.AddButton("Private", () => window.SetParamAccess(index, false));
b.Checked = !param.IsPublic;
b.Enabled = window._canEdit;
+ b.TooltipText = "Sets the parameter access level to Private. It will be accessible only within this script and won't be visible outside (eg. in script properties panel).";
+ }
+
+ // Parameter type editing
+ var cmType = menu.AddChildMenu("Type");
+ {
+ var b = cmType.ContextMenu.AddButton(window.Surface.GetTypeName(param.Type) + "...", () =>
+ {
+ // Show context menu with list of parameter types to use
+ var cm = new ItemsListContextMenu(180);
+ var newParameterTypes = window.NewParameterTypes;
+ foreach (var newParameterType in newParameterTypes)
+ {
+ var item = new TypeSearchPopup.TypeItemView(newParameterType);
+ if (newParameterType.Type != null)
+ item.Name = window.VisjectSurface.GetTypeName(newParameterType);
+ cm.AddItem(item);
+ }
+ cm.ItemClicked += (ItemsListContextMenu.Item item) => window.SetParamType(index, (ScriptType)item.Tag);
+ cm.SortChildren();
+ cm.Show(window, window.PointFromScreen(Input.MouseScreenPosition));
+ });
+ b.Enabled = window._canEdit;
+ b.TooltipText = "Opens the type picker window to change the parameter type.";
+ cmType.ContextMenu.AddSeparator();
+
+ ScriptType singleValueType, arrayType;
+ if (param.Type.IsArray)
+ {
+ singleValueType = new ScriptType(param.Type.GetElementType());
+ arrayType = param.Type;
+ }
+ else
+ {
+ singleValueType = param.Type;
+ arrayType = param.Type.MakeArrayType();
+ }
+ b = cmType.ContextMenu.AddButton("Value", () => window.SetParamType(index, singleValueType));
+ b.Checked = param.Type == singleValueType;
+ b.Enabled = window._canEdit;
+ b.TooltipText = "Changes parameter type to a single value.";
+ b = cmType.ContextMenu.AddButton("Array", () => window.SetParamType(index, arrayType));
+ b.Checked = param.Type == arrayType;
+ b.Enabled = window._canEdit;
+ b.TooltipText = "Changes parameter type to an array.";
}
}
}
@@ -1064,6 +1187,24 @@ namespace FlaxEditor.Windows.Assets
action.Do();
}
+ private void SetParamType(int index, ScriptType type)
+ {
+ var param = Surface.Parameters[index];
+ if (param.Type == type)
+ return;
+ var action = new EditParamTypeAction
+ {
+ Window = this,
+ Index = index,
+ BeforeType = param.Type,
+ BeforeValue = param.Value,
+ AfterType = type,
+ AfterValue = TypeUtils.GetDefaultValue(type),
+ };
+ _undo.AddAction(action);
+ action.Do();
+ }
+
///
public override void OnPlayBeginning()
{