Skip to main content
Version: 5.x

Custom Script UI

Custom UI can be used to control how your script input fields appear in the Inspector panel. This is configured by adding a json string after your normal @input property declaration or a decorators in TypeScript.

Normal input declaration

//@input vec3 myColor

Input with custom UI

//@input vec3 myColor {"widget":"color"}

Default Values

Individual variables

//@input string myString = "default string"
//@input int myInt = 24
//@input bool myBool = true

Arrays

//@input string[] myStringArray  = {"My","default","strings"}
//@input int[] myIntArray = {24,1}
//@input bool[] myBoolArray = {true,false,false}

General UI Controls

These are optional controls that work on @input properties and @ui widgets.

Labels and Hints

  • "label" - Overrides the text label displayed
  • "hint" - Sets a hint message to appear on mouse hover
//@input string string1 = "hello" {"label":"String #1"}
//@input int number1 {"label":"Number (1.0)", "hint":"This is a number variable"}

ShowIf

  • "showIf" - Sets a property name to control the element's visibility

//@input bool useColor
//@input vec3 myColor {"widget":"color", "showIf":"useColor"}

ShowIfValue

  • "showIfValue" - Used with "showIf", sets a required value for the element to be visible (defaults to true)

//@input string inputMode {"widget":"combobox", "values":[{"label":"float", "value":"float"}, {"label":"vec3", "value":"vec3"}, {"label":"color", "value":"color"}]}
//@input float floatVal {"showIf":"inputMode", "showIfValue":"float"}
//@input vec3 vec3Val {"showIf":"inputMode", "showIfValue":"vec3"}
//@input vec4 colorVal {"widget":"color", "showIf":"inputMode", "showIfValue":"color"}

Input Widgets

Widgets can make dramatic changes to how @input properties are drawn. Each widget works with a certain set of property types, so make sure your property type is supported by the widget.

Color

A color picker for vec3 and vec4 properties.

// RGB (red, green, blue)
//@input vec3 myColor = {1,0,0} {"widget":"color"}
// RGBA (red, green, blue, alpha)
//@input vec4 colorWithAlpha = {1,1,1,.5} {"widget":"color"}

Spinbox

The default widget for int and float properties.

  • "min" - Minimum allowed value
  • "max" - Maximum allowed value
  • "step" - Amount added when clicking the up and down buttons
//@input int myInt {"label":"My Int", "min":0, "max":25, "step":5}
//@input float myFloat {"label":"My Float", "min":0.0, "max":1.0, "step":0.001}

Slider

Draws a draggable slider that interpolates between two values. This works with int and float properties.

  • "min" - Minimum allowed value
  • "max" - Maximum allowed value
  • "step" - Smallest increment allowed between min/max
//@input int intSlider {"widget":"slider", "min":0, "max":10, "step":1}
//@input float floatSlider = 0.5 {"widget":"slider", "min":0.0, "max":1.0, "step":0.01}

Combo Box

Shows a dropdown menu with a list of selectable options. This works with string, int, and float properties.

  • "values" - List of options in the combo box. Each option is a json object formatted as follows:
    • "label" - How this option appears in the drop down menu
    • "value" - The value returned in script if this option is selected
//@input int radius {"widget":"combobox", "values":[{"label":"one", "value":1}, {"label":"two", "value":2}]}
//@input string animalType {"widget":"combobox", "values":[{"label":"cat", "value":"cat"}, {"label":"dog", "value":"dog"}, {"label":"bird", "value":"bird"}]}

Here's a breakdown of the json strings being used in this example. Remember that each UI element is defined in a single line, so this expanded version is only for readability and won't work as is.

{
"widget": "combobox",
"values":
[
{"label": "one", "value": 1},
{"label": "two", "value": 2}
]
}
{
"widget": "combobox",
"values":
[
{"label": "cat", "value": "cat"},
{"label": "dog", "value": "dog"},
{"label": "bird", "value": "bird"}
]
}

Text Area

Create a multi-line string input field:

//@input string text {"widget" : "text_area"}

Custom Type Inputs

You may define your own custom input type and create arrays of custom objects:

/*
@typedef test
@property {vec3} a {"widget": "color"}
@property {vec4} b {"widget": "color"}
@property {int} c {"label":"My Int", "min":0, "max":25, "step":5}
@property {float} d {"label":"My Float", "min":0.0, "max":1.0, "step":0.001}
@property {int} e {"widget":"slider", "min":0, "max":10, "step":1}
@property {float} f {"widget":"slider", "min":0.0, "max":1.0, "step":0.01}
@property {int} g {"widget":"combobox", "values":[{"label":"one", "value":1}, {"label":"two", "value":2}]}
@property {string} h {"widget":"combobox", "values":[{"label":"cat", "value":"cat"}, {"label":"dog", "value":"dog"}, {"label":"bird", "value":"bird"}]}
*/

// @input test mystruct
// @input test[] mystruct2

Custom Type Inputs can also be nested multiple times within the custom type block:

/**
@typedef TestTypeDefJS
@property {vec3} a {"widget": "color"}
@property {int} b {"label":"My Int", "min":0, "max":25, "step":5}
@property {int} c {"widget":"slider", "min":0, "max":10, "step":1}
@property {int} d {"widget":"combobox", "values":[{"label":"one", "value":1}, {"label":"two", "value":2}]}
**/

/**
@typedef TestTypeDefJS_2
@property {TestTypeDefJS} testProperties;
@property {string} testString;
@property {int} testInt;
**/

// @input TestTypeDefJS_2 mystruct

UI Widgets

UI widgets are purely for visual organization and decoration, since unlike @input properties they won't provide values to your script. They are created by starting a line with //@ui. For example:

//@ui {"widget":"label", "label":"Hello"}

Label

Draws a line of text. Useful for titles, warnings and descriptions.

//@ui {"widget":"label", "label":"Color Controls"}
// Empty label, adds empty space
//@ui {"widget":"label"}

Separator

Draws a horizontal line for separating content.

//@ui {"widget":"label", "label":"Color Controls"}
// Empty label, adds empty space
//@ui {"widget":"separator"}
//@input vec3 myColor = (1,0,0) {"widget":"color"}

Group

Creates a collapsible group that hides or shows all content inside. Use a "group_start" widget to begin the group, and a "group_end" widget to end it. Any @input or @ui between the two will become part of the group.

//@ui {"widget":"group_start", "label":"My Group"}
// inner content...
//@ui {"widget":"group_end"}
Was this page helpful?
Yes
No

AI-Powered Search