diff --git a/Source/Editor/Content/Items/VisualScriptItem.cs b/Source/Editor/Content/Items/VisualScriptItem.cs
index 54133e6e2..c3953513f 100644
--- a/Source/Editor/Content/Items/VisualScriptItem.cs
+++ b/Source/Editor/Content/Items/VisualScriptItem.cs
@@ -112,6 +112,12 @@ namespace FlaxEditor.Content
throw new TargetException("Missing Visual Script asset.");
_type.Asset.SetScriptInstanceParameterValue(_parameter.Name, (Object)obj, value);
}
+
+ ///
+ public object Invoke(object obj, object[] parameters)
+ {
+ throw new NotSupportedException();
+ }
}
sealed class VisualScriptMethodInfo : IScriptMemberInfo
@@ -240,6 +246,14 @@ namespace FlaxEditor.Content
{
throw new NotSupportedException();
}
+
+ ///
+ public object Invoke(object obj, object[] parameters)
+ {
+ if (!_type.Asset)
+ throw new TargetException("Missing Visual Script asset.");
+ return _type.Asset.InvokeMethod(_index, obj, parameters);
+ }
}
///
diff --git a/Source/Editor/CustomEditors/CustomEditor.cs b/Source/Editor/CustomEditors/CustomEditor.cs
index 0d2be75cc..d5f6c5667 100644
--- a/Source/Editor/CustomEditors/CustomEditor.cs
+++ b/Source/Editor/CustomEditors/CustomEditor.cs
@@ -127,12 +127,41 @@ namespace FlaxEditor.CustomEditors
_isSetBlocked = true;
Initialize(layout);
+ ShowButtons();
Refresh();
_isSetBlocked = false;
CurrentCustomEditor = prev;
}
+ private void ShowButtons()
+ {
+ var values = Values;
+ if (values == null || values.HasDifferentTypes)
+ return;
+ var type = TypeUtils.GetObjectType(values[0]);
+ var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
+ foreach (var method in methods)
+ {
+ if (!method.HasAttribute(typeof(ButtonAttribute)) ||
+ method.ParametersCount != 0)
+ continue;
+ var attribute = method.GetAttribute();
+ var text = string.IsNullOrEmpty(attribute.Text) ? Utilities.Utils.GetPropertyNameUI(method.Name) : attribute.Text;
+ var tooltip = string.IsNullOrEmpty(attribute.Tooltip) ? Editor.Instance.CodeDocs.GetTooltip(method) : attribute.Tooltip;
+ var button = _layout.Button(text, tooltip);
+ button.Button.Tag = method;
+ button.Button.ButtonClicked += OnButtonClicked;
+ }
+ }
+
+ private void OnButtonClicked(Button button)
+ {
+ var method = (ScriptMemberInfo)button.Tag;
+ var obj = method.IsStatic ? null : Values[0];
+ method.Invoke(obj);
+ }
+
internal static CustomEditor CurrentCustomEditor;
internal void OnChildCreated(CustomEditor child)
diff --git a/Source/Editor/Scripting/ScriptType.Interfaces.cs b/Source/Editor/Scripting/ScriptType.Interfaces.cs
index 01a4755ec..34294fd60 100644
--- a/Source/Editor/Scripting/ScriptType.Interfaces.cs
+++ b/Source/Editor/Scripting/ScriptType.Interfaces.cs
@@ -293,6 +293,14 @@ namespace FlaxEditor.Scripting
/// The object whose member value will be modified.
/// The new member value.
void SetValue(object obj, object value);
+
+ ///
+ /// Invokes the method on a specific object (null if static) using the provided parameters.
+ ///
+ /// The instance of the object to invoke its method. Use null for static methods.
+ /// List of parameters to provide.
+ /// The value returned by the method.
+ object Invoke(object obj, object[] parameters);
}
///
diff --git a/Source/Editor/Scripting/ScriptType.cs b/Source/Editor/Scripting/ScriptType.cs
index ec3775b95..66c7a9b06 100644
--- a/Source/Editor/Scripting/ScriptType.cs
+++ b/Source/Editor/Scripting/ScriptType.cs
@@ -691,6 +691,23 @@ namespace FlaxEditor.Scripting
else
_custom.SetValue(obj, value);
}
+
+ ///
+ /// Invokes the method on a specific object (null if static) using the provided parameters.
+ ///
+ /// The instance of the object to invoke its method. Use null for static methods.
+ /// List of parameters to provide.
+ /// The value returned by the method.
+ public object Invoke(object obj = null, object[] parameters = null)
+ {
+ if (parameters == null)
+ parameters = Array.Empty