Skip to main content
Version: 5.x
Supported on
Snapchat
Spectacles
Camera Kit

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 {"widget":"spinbox", "label":"My Int", "min":0, "max":25, "step":5}
//@input float myFloat {"widget":"spinbox", "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