diff --git a/Source/Editor/Surface/Archetypes/Constants.cs b/Source/Editor/Surface/Archetypes/Constants.cs
index cbe7822e3..e3cbd1b86 100644
--- a/Source/Editor/Surface/Archetypes/Constants.cs
+++ b/Source/Editor/Surface/Archetypes/Constants.cs
@@ -7,11 +7,13 @@ using Real = System.Single;
#endif
using System;
+using System.Linq;
using System.Reflection;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
using FlaxEditor.Surface.Elements;
+using FlaxEditor.Surface.Undo;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
@@ -347,6 +349,75 @@ namespace FlaxEditor.Surface.Archetypes
}
}
+ private class ConstantNode : SurfaceNode
+ {
+ private ScriptType _type;
+
+ ///
+ public ConstantNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch, ScriptType type)
+ : base(id, context, nodeArch, groupArch)
+ {
+ _type = type;
+ }
+
+ ///
+ public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Float2 location)
+ {
+ base.OnShowSecondaryContextMenu(menu, location);
+
+ menu.AddSeparator();
+ menu.AddButton("Convert to Parameter", OnConvertToParameter);
+ }
+
+ private void OnConvertToParameter()
+ {
+ if(Surface.Owner is not IVisjectSurfaceWindow window)
+ throw new Exception("Surface owner is not a Visject Surface Window");
+
+ Asset asset = Surface.Owner.SurfaceAsset;
+ if (asset == null || !asset.IsLoaded)
+ {
+ Editor.LogError("Asset is null or not loaded");
+ return;
+ }
+
+ var paramIndex = Surface.Parameters.Count;
+ var paramAction = new AddRemoveParamAction
+ {
+ Window = window,
+ IsAdd = true,
+ Name = Utilities.Utils.IncrementNameNumber("New parameter", x => OnParameterRenameValidate(null, x)),
+ Type = _type,
+ Index = paramIndex,
+ InitValue = Values[0],
+ };
+ paramAction.Do();
+
+ var parameterGuid = Surface.Parameters[paramIndex].ID;
+
+ bool undoEnabled = Surface.Undo.Enabled;
+ Surface.Undo.Enabled = false;
+ SurfaceNode node = Surface.Context.SpawnNode(6, 1, this.Location, new object[] {parameterGuid});
+ Surface.Undo.Enabled = undoEnabled;
+
+ if (node is not Parameters.SurfaceNodeParamsGet getNode)
+ throw new Exception("Node is not a ParamsGet node!");
+
+ var spawnNodeAction = new AddRemoveNodeAction(getNode, true);
+ var removeConstantAction = new AddRemoveNodeAction(this, false);
+
+ Surface.AddBatchedUndoAction(new MultiUndoAction(paramAction, spawnNodeAction, removeConstantAction));
+ removeConstantAction.Do();
+ }
+
+ private bool OnParameterRenameValidate(RenamePopup popup, string value)
+ {
+ if(Surface.Owner is not IVisjectSurfaceWindow window)
+ throw new Exception("Surface owner is not a Visject Surface Window");
+ return !string.IsNullOrWhiteSpace(value) && window.VisjectSurface.Parameters.All(x => x.Name != value);
+ }
+ }
+
///
/// The nodes for that group.
///
@@ -356,6 +427,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 1,
Title = "Bool",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(bool))),
Description = "Constant boolean value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -388,6 +460,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 2,
Title = "Integer",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(int))),
Description = "Constant integer value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -415,6 +488,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 3,
Title = "Float",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(float))),
Description = "Constant floating point",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -442,6 +516,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 4,
Title = "Float2",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Float2))),
Description = "Constant Float2",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 60),
@@ -472,6 +547,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 5,
Title = "Float3",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Float3))),
Description = "Constant Float3",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 80),
@@ -504,6 +580,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 6,
Title = "Float4",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Float4))),
Description = "Constant Float4",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 100),
@@ -538,6 +615,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 7,
Title = "Color",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Color))),
Description = "RGBA color",
Flags = NodeFlags.AllGraphs,
Size = new Float2(70, 100),
@@ -644,6 +722,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 12,
Title = "Unsigned Integer",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Float3))),
Description = "Constant unsigned integer value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(170, 20),
@@ -700,6 +779,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 16,
Title = "Vector2",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Vector2))),
Description = "Constant Vector2",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 60),
@@ -720,6 +800,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 17,
Title = "Vector3",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Vector3))),
Description = "Constant Vector3",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 80),
@@ -742,6 +823,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 18,
Title = "Vector4",
+ Create = (id, context, arch, groupArch) => new ConstantNode(id, context, arch, groupArch, new ScriptType(typeof(Vector4))),
Description = "Constant Vector4",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 100),
diff --git a/Source/Editor/Surface/SurfaceParameter.cs b/Source/Editor/Surface/SurfaceParameter.cs
index 6eafdc2aa..e74b44eb9 100644
--- a/Source/Editor/Surface/SurfaceParameter.cs
+++ b/Source/Editor/Surface/SurfaceParameter.cs
@@ -56,7 +56,7 @@ namespace FlaxEditor.Surface
/// The type.
/// The name.
/// The created parameter.
- public static SurfaceParameter Create(ScriptType type, string name)
+ public static SurfaceParameter Create(ScriptType type, string name, object initValue = null)
{
return new SurfaceParameter
{
@@ -64,7 +64,7 @@ namespace FlaxEditor.Surface
IsPublic = true,
Name = name,
Type = type,
- Value = TypeUtils.GetDefaultValue(type),
+ Value = initValue ?? TypeUtils.GetDefaultValue(type),
};
}
}
diff --git a/Source/Editor/Surface/VisjectSurfaceWindow.cs b/Source/Editor/Surface/VisjectSurfaceWindow.cs
index 305121e11..e1d39083c 100644
--- a/Source/Editor/Surface/VisjectSurfaceWindow.cs
+++ b/Source/Editor/Surface/VisjectSurfaceWindow.cs
@@ -278,6 +278,11 @@ namespace FlaxEditor.Surface
///
public ScriptType Type;
+ ///
+ /// The value to initialize the parameter with. (Can be null)
+ ///
+ public object InitValue;
+
///
public string ActionString => IsAdd ? "Add parameter" : "Remove parameter";
@@ -304,7 +309,7 @@ namespace FlaxEditor.Surface
var type = Type;
if (IsAdd && type.Type == typeof(NormalMap))
type = new ScriptType(typeof(Texture));
- var param = SurfaceParameter.Create(type, Name);
+ var param = SurfaceParameter.Create(type, Name, InitValue);
if (IsAdd && Type.Type == typeof(NormalMap))
param.Value = FlaxEngine.Content.LoadAsyncInternal("Engine/Textures/NormalTexture");
Window.VisjectSurface.Parameters.Insert(Index, param);