# Dynamic Training Builder Nodes Manual

# Introduction

The Dynamic Training Builder represents the next-generation interaction definition system within the Training Builder, offering enhanced capabilities with more responses and events. It allows for the dynamic introduction of multiple node queries into a single system and the removal of these nodes during runtime, providing unparalleled flexibility. This advanced system is packed with exclusive features that elevate the overall user experience, making it a powerful tool for creating complex and responsive training simulations.

#### Accessing the Dynamic Training Builder

The Dynamic Training Builder is available in **SimLab Composer Mechanical and Ultimate Edition** as well as **VR Studio Pro Edition**.

To access it, simply run the Training Builder from the top workbench.

[![TB.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/tb.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/tb.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-08/scaled-1680-/CIJimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-08/CIJimage.png)

The Dynamic Training Builder menu is divided into four groups:

##### **Sources**

Source Nodes in the Training Builder define the elements that drive interactions, including objects, data types, animation sequences, and scene states. They act as key reference points that connect with events and responses, determining which elements are used within the interaction system. By configuring these sources, users ensure that events are triggered and responses are executed based on defined conditions, creating a dynamic and responsive interaction system.

##### **Events**

Events represent specific triggers or occurrences that initiate actions within the interaction system. They are used to define when particular conditions are met, such as an object entering a specific area or a user performing an action. Events connect Source Nodes to Responses, dictating how the system reacts to changes or interactions.

##### **Responses**

Responses are actions or outcomes triggered by Events. They dictate what happens when specific conditions are met, such as playing an animation, changing a scene, or altering an object’s state. Responses connect to Events to define the system's behavior and ensure the interaction system reacts dynamically to various triggers.

##### **States**

In the Training Builder, State Nodes represent ongoing conditions rather than single triggers. They include nodes for monitoring overlap, variable values, and object grabbing states, as well as logical operations like "and," "or," and "not." State Nodes can trigger responses similarly to events, but they reflect persistent states within the interaction system rather than instantaneous actions.

---

### Adding Nodes to the Diagram

To add nodes to the diagram simple click on one of the icons in the top bench or drag and drop them into the diagram

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-08/scaled-1680-/4O9image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-08/4O9image.png)

An additional method to create nodes is to use the **context menu** that appears when right clicking in an empty area of the diagram.

[![ContextMenu.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/contextmenu.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/contextmenu.jpg)

In the context menu you can navigate towards the nodes you want to create through a submenu system or you can type in the name of a node in the **filter** field to show only the related nodes.

***Note**: In addition to the nodes available in the nodes bench, the context menu features more advanced nodes that aren't listed there. Feel free to explore these additional options as well.*

---

#### Learn More

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="446" src="https://www.youtube.com/embed/1EtxHZ1tcBI" title="Introduction to the Dynamic Training Builder" width="793"></iframe>

To learn more about utilizing the Dynamic Training Builder you can visit our ever-expanding **SimLab Academy**, accessible from the bottom library in SimLab Composer and SimLab VR Studio, there you will find video tutorials with examples that would help you unleash the full potentials of the Dynamic Training Builder.

[![DynamicTBAcademy.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/dynamictbacademy.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/dynamictbacademy.jpg)

---

#### Organize your Dynamic Training Builder with Groups

<div id="bkmrk-vr-experiences-are-v">VR experiences are valuable assets that include custom logic created by users. As more users build advanced experiences—and as these experiences are shared and used over time by multiple creators—we’ve added colored groups and notes to help manage them better.</div><div id="bkmrk--9">  
</div><div id="bkmrk-these-features-make-">These features make it easier to organize related logic into groups and add clear descriptions for each section in the Training Builder, check this [tutorial](https://www.youtube.com/watch?v=p9SMynLbRQY).</div><div id="bkmrk--10"><iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/p9SMynLbRQY" width="560"></iframe>

</div><div id="bkmrk--11">---

</div>#### Feel free to reach out to us on our Discord!

##### [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) [SimLab Discord Community](https://www.simlab-soft.com/simlab-discord-community.aspx)

# Sources



# Boolean

### [![Boolean_black.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/ykLboolean-black.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/ykLboolean-black.png) Boolean

Generates a Boolean (True/False) value. [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/image.png)

# Expression

### [![Source_Expression_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/source-expression-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/source-expression-blk.png) Expression<span style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> </span>

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/image.png)

**Expressions** are used to generated values that can be used to trigger events through out the interactive VR experiences. They allow users to define logic related to interactions and can be categorized into Main Sources and Template Sources. For more details on expressions check this [tutorial](https://www.youtube.com/watch?v=6hIvMsl5obs&t=307s). <span style="font-size: 11.0pt; line-height: 107%; font-family: 'Calibri',sans-serif; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: Arial; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;">  
</span>You can find a list of all expressions viable in training builder at this [link](https://www.simlab-soft.com/3d-products/vr-expressions.aspx).

# Material

### [![Source_Material_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/source-material-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/source-material-blk.png) Material 

Select a material from Material Library to use as[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/S09image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/S09image.png)

an input in this source.

# Number

### [![Source_Number_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/C6usource-number-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/C6usource-number-blk.png) Number 

Input a number and use it as a source in your training builder logic

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/W1Bimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/W1Bimage.png)

# Scene Node

### [![Source_SceneNode_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/source-scenenode-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/source-scenenode-blk.png) Scene Node

# Scene Node Query

[![Source_SceneNodeQuery.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/source-scenenodequery.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)<span style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> Scene Node Query</span>

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/8Naimage.png)

The **SceneNode Query** enables the system to identify an object based on its attributes within the VR environment. This node enhances interactivity by allowing responses to be customized for individual objects, triggering specific actions based on **SceneNode attributes** as part of their virtual experience.

#### Example

In this example, the **SceneNode Query** is used to acquire specific attributes from specific objects, in order to perform specific response to them

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/njbimage.png)

Then when user triggers object named **Activate**, and the response connected to the node will be executed to the objects with attribute name **Color** and its value is **Yellow.**

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/9erimage.png)

# SceneState

### [![Source_SceneState_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/source-scenestate-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/source-scenestate-blk.png) SceneState

# Sequence

### [![Source_Sequence_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/source-sequence-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/source-sequence-blk.png) Sequence

# String

### [![Source_String_blk.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/source-string-blk.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/source-string-blk.png) String

# User Query

### [![Source_UserQuery.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/source-userquery.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) User Query

![CDvimage.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/cdvimage.png)

The **User Query node** enables the system to identify a user based on their attributes within the VR environment. This node enhances interactivity by allowing responses to be customized for individual users, triggering specific actions based on **user attributes** as part of their virtual experience.

#### Example

In this example, the **User Query node** is used to acquire specific attributes from specific users, in order to perform specific response to them

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/s7uimage.png)

Once the User enters the object named **Building**, their InBuilding attribute's value becomes **Yes,** then when user triggers object named **Activate**, the users with attribute name **InBuilding** and its value is **Yes** gets teleported to CameraNode named **Outside**'s location.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/VOKimage.png)

# Variable

### ![Source_Variable.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/source-variable.png) Variable

![CDvimage.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/oBkimage.png)

The **Variable** **node** represents the value of a specific variable within the scene and features a variable port that can be connected to nodes requiring variable assignment. This node simplifies complex setups by enabling consistent use of variables throughout the scene, ensuring streamlined connections between different elements in the training builder.

![TrainingBuilder_Variable.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/trainingbuilder-variable.png)

[![TrainingBuilder_Variable_01.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/trainingbuilder-variable-01.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/trainingbuilder-variable-01.png)

> [Tutorial about **Variable Sorting** on YouTube](https://www.youtube.com/watch?v=amnTY83rDjo "Tutorial about Variable Sorting on YouTube")

# Color

The Color node gives you a single color value that you can feed into any other node that needs a color.

#### What it does

This node provides a color you pick yourself. The node shows the color as a small swatch you can click to open a color picker — a color wheel with RGB, HSV, and HEX entry (HEX codes look like `#C81E1E`). Whatever color you choose becomes the value this node hands out.

It has no Execute flow and nothing needs to fire it — it simply supplies the color value, ready to read at any time. Connect its **Color** output into any node that accepts a color, such as **Set Material Color**.

#### Inputs

This node has no inputs. You don’t connect a color from another node — you choose it directly on the node itself by clicking its swatch to open the color picker.

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Color**</td><td style="white-space: nowrap;">Color</td><td>The color you picked on the node, shown as a small colored swatch. You can wire this into any node that accepts a color.</td></tr></tbody></table>

#### Example

<table id="bkmrk-color-output-%23c81e1e"><tbody><tr><td>**Color** output</td><td>`#C81E1E` (a warm red)</td></tr></tbody></table>

#### Tips

- One Color node can feed several nodes at once — wire the same **Color** output into as many color inputs as you like to keep them in sync.
- Connect this straight into a **Set Material Color** node to change the color of an object in your scene.

# Sources

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-08/iA9image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)<span style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> Expression</span>

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/image.png)

**Expressions** are used to generated values that can be used to trigger events throughtout the interactive VR experiences. They allow users to define logic related to interactions and can be categorized into Main Sources and Template Sources. For more details on expressions check this [tutorial](https://www.youtube.com/watch?v=6hIvMsl5obs&t=307s). <span style="font-size: 11.0pt; line-height: 107%; font-family: 'Calibri',sans-serif; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: Arial; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;">  
</span>You can find a list of all expressions viable in training builder at this [link](https://www.simlab-soft.com/3d-products/vr-expressions.aspx).

[![Source_SceneNodeQuery.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/source-scenenodequery.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)<span style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> SceneNode Query</span>

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/8Naimage.png)

The **SceneNode Query** enables the system to identify an object based on its attributes within the VR environment. This node enhances interactivity by allowing responses to be customized for individual objects, triggering specific actions based on **SceneNode attributes** as part of their virtual experience.

#### Example

In this example, the **SceneNode Query** is used to acquire specific attributes from specific objects, in order to perform specific response to them

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/njbimage.png)

Then when user triggers object named **Activate**, and the response connected to the node will be executed to the objects with attribute name **Color** and its value is **Yellow.**

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/9erimage.png)

---

### [![Source_UserQuery.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/source-userquery.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) User Query

![CDvimage.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/cdvimage.png)

The **User Query node** enables the system to identify a user based on their attributes within the VR environment. This node enhances interactivity by allowing responses to be customized for individual users, triggering specific actions based on **user attributes** as part of their virtual experience.

#### Example

In this example, the **User Query node** is used to acquire specific attributes from specific users, in order to perform specific response to them

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/s7uimage.png)

Once the User enters the object named **Building**, their InBuilding attribute's value becomes **Yes,** then when user triggers object named **Activate**, the users with attribute name **InBuilding** and its value is **Yes** gets teleported to CameraNode named **Outside**'s location.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/VOKimage.png)

---

### ![Source_Variable.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/source-variable.png) Variable

![CDvimage.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/oBkimage.png)

The **Variable** **node** represents the value of a specific variable within the scene and features a variable port that can be connected to nodes requiring variable assignment. This node simplifies complex setups by enabling consistent use of variables throughout the scene, ensuring streamlined connections between different elements in the training builder.

![TrainingBuilder_Variable.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/trainingbuilder-variable.png)

[![TrainingBuilder_Variable_01.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/trainingbuilder-variable-01.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/trainingbuilder-variable-01.png)

> [Tutorial about **Variable Sorting** on YouTube](https://www.youtube.com/watch?v=amnTY83rDjo "Tutorial about Variable Sorting on YouTube")

---

# Events



# AI Agent

### ![Event_AiAgent_StartTalk.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-aiagent-starttalk.png) AI Agent Start Talk

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/eqJimage.png)The **AI Agent Start Talk** node activates the exact moment an assigned AI Agent begins delivering its response.

### ![Event_AiAgent_EndTalk.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-aiagent-endtalk.png) AI Agent End Talk

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/6yzimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/6yzimage.png)

The **AI Agent End Talk** node activates as soon as the assigned AI Agent finishes delivering its response.

For more information, please watch the AI Start/End talk tutorial:

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/YEMeCS8QcFY" width="560"></iframe>

# SceneNode \ Dynamic Menu

### ![Event_DynamicMenu_Item_Triggered.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-dynamicmenu-item-triggered.png) Dynamic Menu Item Triggered

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/NdHimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/NdHimage.png)

The **Dynamic Menu Item Triggered** event node acts as a universal listener, activating the moment a user interacts with *any* dynamic menu button within the VR scene. Upon execution, it outputs the specific **SceneNode** the menu is attached to, the **ID** of the clicked button, and the **User** who triggered it.

### ![Event_DynamicMenu_Item_Triggered.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-dynamicmenu-item-triggered.png) Dynamic Menu Item Triggered(ID)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/pnVimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/pnVimage.png)

The **Dynamic Menu Item Triggered (ID)** event node activates only when a button with a specific **ID** is pressed. It ignores all other button interactions, allowing you to trigger a specific function

### ![Event_DynamicMenu_Item_Triggered.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-dynamicmenu-item-triggered.png) Dynamic Menu Item Triggered(Node + ID)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/rOEimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/rOEimage.png)

The **Dynamic Menu Item Triggered (Node + ID)** event node provides the most specific control by activating only when a button with a precise **ID** is pressed on a menu linked to a specific **SceneNode**. This prevents execution overlap by ensuring the logic only triggers for one unique button on one specific object.

**Example:**

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Osbimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Osbimage.png)

In this example, the **Dynamic Menu Item Triggered (Node + ID)** node is configured to act as a "Help" button. By setting the **SceneNode** to "Main Menu" and the **ID** to "3", the system listens exclusively for that exact button press on that specific menu object. Once the user clicks this button, the execution flow passes to a **Show/Hide** node configured to display an "Instructions Window" by setting its state to True. Immediately following this, the flow triggers a **Set Node Glow State** node, which applies a visual highlight to a designated "Hint Object" to guide the user.

### ![Event_DynamicMenu_Item_Triggered.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-dynamicmenu-item-triggered.png) Dynamic Menu Item Triggered(Node)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/KW5image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/KW5image.png)

The **Dynamic Menu Item Triggered (Node)** event node activates only when a button is pressed on a menu attached to a designated **SceneNode**. This node isolates interactions to a single object, ensuring that the logic only runs for the menus linked to that specific item in the scene.

Dynamic Menu Triggered nodes are used in the following add-ons:

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/8NtfNkBr_Z0" width="560"></iframe>

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/7Ct8UpF9ce4" width="560"></iframe>

# SceneNode \ Query

### ![Event_Query_NodeAdded.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-query-nodeadded.png) Node Added to Query

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Ye8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Ye8image.png)

The Node Added to Query event node constantly monitors the scene and triggers its Execute output whenever a 3D object's attributes are modified to match the specific conditions defined by a connected Scene Node Query. By plugging a query into the node's SceneNode input, it listens for any object that newly meets these criteria—essentially being "added" to the query's list of valid results—and subsequently passes both the execution signal and the specific SceneNode that triggered the event through their respective outputs, allowing for dynamic, attribute-driven logic without needing to manually target individual objects.

##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Wbgimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Wbgimage.png)

In this example, a Scene Node Query is configured to continuously look for any object that has an attribute named "Parts" with a value containing "Part\_". This query is connected directly to Node Added to Query event node. During the experience, whenever an object has its attributes updated to successfully meet this exact condition, the event node automatically triggers and passes that specific object through its SceneNode output into a Set Node Glow State node.

---

### ![Event_Query_NodeRemoved.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-query-noderemoved.png) Node Removed From Query

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/3MHimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/3MHimage.png)

The Node Removed From Query event node continuously monitors the scene and triggers its Execute output whenever a 3D object's attributes change so that they no longer match the conditions of a connected Scene Node Query. By connecting a query to the node's SceneNode input, it watches for any object that falls out of the query's criteria—essentially being "removed" from the list of valid results.

##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/8Iximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/8Iximage.png)

In this example, a Scene Node Query is configured to track any object that has an attribute named "Bullet\_Instance". This query is connected directly to the SceneNode input of the Node Removed From Query event node. During the experience, if an object's attributes are altered so it no longer possesses the "Bullet\_Instance" attribute (for example, if the attribute is removed after a collision), the event node automatically triggers and passes that specific object through its SceneNode output into a Delete SceneNode node.

# Scene Node \ Overlap

### [![Event_Node_EntersNode.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-entersnode.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/event-node-entersnode.png) Node Entered Node

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/LFQimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/LFQimage.png)

The **Node Enter Node** event is triggered when Scene Node A enters Scene Node B. Both nodes can be any nodes in the assembly tree — for example, Node A could be a screwdriver and Node B could be a screw.

---

### [![Event_Node_ExitsNode.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-exitsnode.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/event-node-exitsnode.png) Node Exited Node 

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/hJ3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/hJ3image.png)

The **Node Excited Node** event is triggered when Scene Node A exits Scene Node B. Both nodes can be any nodes in the assembly tree — for example, Node A could be a screwdriver and Node B could be a screw.

# SceneNode \ Triggered

### [![Event_Node_Triggered.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/event-node-triggered.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/event-node-triggered.png) Node Triggered 

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-12/scaled-1680-/Wjpimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-12/Wjpimage.png)**Node Triggered** event is executed when the selected Scene Node is triggered within VR environment.

### ![Events_SceneNode_Triggered_NodeTriggeredLocation.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/events-scenenode-triggered-nodetriggeredlocation.png) Node Triggered Location

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/Wk8image.png)The **Node Triggered Location** is used to capture the specific location or position of a triggered event within the VR environment. It enables tracking where a particular interaction occurred, which can be useful for dynamic object placement, analytics, or event-triggered responses based on spatial coordinates.

####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/oSEimage.png)

In this example, the **Node Triggered Location** is used to capture the location where the user triggers the target. When the target is hit, the node records the exact spot, and a bullet hole is placed using the **Set Node Location**. The **Make Node Copy** is used to enable the user to shoot more than one bullet, creating a new bullet hole at each triggered location. This setup allows for repeated interactions, with each shot creating a new bullet hole in the correct spot.

---

<div class="mt-1 flex gap-3 empty:hidden -ml-2" id="bkmrk--6"><div class="items-center justify-start rounded-xl p-1 flex"><div class="flex items-center"><button aria-label="Read Aloud" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="voice-play-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Copy" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="copy-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Regenerate" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="regenerate-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex"><button aria-label="Good response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="good-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Bad response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="bad-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button>  
</div><div class="flex items-center pb-0"><div class="[&_svg]:h-full [&_svg]:w-full icon-md h-4 w-4"><svg fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg>  
</div></div><button aria-expanded="false" aria-haspopup="menu" class="cursor-pointer h-[30px] rounded-md px-1 text-token-text-secondary hover:bg-token-main-surface-secondary" data-state="closed" id="bkmrk--8" type="button"></button></div></div></div><div class="pointer-container" id="bkmrk-%C2%A0-3"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>

# Controller

---

### [![Event_User_Grip_Pressed.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/event-user-grip-pressed.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Grip Pressed

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/EBFimage.png)

The **Grip Pressed node** enables the user to detect when the VR controller's grip is pressed. By connecting a response to this node, the specified action is executed each time the grip is pressed, allowing for interactive controls within the VR Experience.

####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/euiimage.png)

In this example, a **Grip Pressed node** is used to execute a response. Once the Grip press is triggered, the Grip Pressed node checks the boolean value. If the condition is met, the connected response executes, and the animation plays during the VR Experience.

---

### [![Event_User_Grip_Released.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/event-user-grip-released.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Grip Released

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/4kIimage.png)

The **Grip Released node** enables the user to detect when the VR controller's grip is released. By connecting a response to this node, the specified action is executed each time the grip is released, allowing for interactive controls within the VR Experience.

####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/kHOimage.png)

In this example, a **Grip Released node** is used to execute a response. Once the Grip released is triggered, the Grip Released node checks the boolean value. If the condition is met, the connected response executes, and the animation plays during the VR Experience.

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/y1Vimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/y1Vimage.png)Hand

<div id="bkmrk-hand-gestures-in-vr-">Hand gestures in VR are becoming more natural and intuitive than ever. No need for the user to fully close hand to grab objects — now, a drawer can be opened effortlessly using just two fingers, just like in real life.</div><div id="bkmrk--9">  
</div><div id="bkmrk-with-enhanced-gestur">With enhanced gesture control, users can interact with virtual world in a way that feels smooth, and precise, check this [tutorial](https://youtu.be/YkPAQTO5GKE).</div><div id="bkmrk--10"></div><div id="bkmrk--11"><iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/YkPAQTO5GKE" width="560"></iframe>

</div>

# Keyboard

<div id="bkmrk-adding-an-interactiv">Adding an interactive 3D menu in VR is simple, but using the same menu on a desktop can be challenging, as you have to adjust your view every time you want to make a change.</div><div id="bkmrk-">  
</div><div id="bkmrk-to-solve-this%2C-we%E2%80%99ve">To solve this, "**Key Press**" and "**Key Release**" events were introduced. By separating these events, designers now have more control when creating VR experiences.</div>### On Key Pressed

Right click in the Dynamic Training Builder and type in the

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/XMVimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/XMVimage.png)

"Keyboard" or look under "**Events**" to get this node. As the name implies when a keyboard key is pressed this event is triggered.

#### Example

<div id="bkmrk--1"></div>### On Key Released

Same as above node but when key is released.

Check this [tutorial ](https://youtu.be/ACQPYu1sdf0)to learn more about these events.  
![dLmimage.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/dlmimage.png)

<iframe allowfullscreen="allowfullscreen" height="295" src="https://www.youtube.com/embed/ACQPYu1sdf0" style="width: 526px; height: 295px;" width="526"></iframe>

# User

### ![Event_User_EntersNode.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-user-entersnode.png) User Entered Node

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/F48image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/F48image.png)

The **User Enter Node event node** continuously monitors the physical boundaries of a specific 3D object and activates the moment a user's avatar collides with or enters its volume. While enabled, it passes forward a reference to the specific User involved before continuing the logic flow. This functionality applies to all participants within multiplayer VR collaboration scenes.

---

### ![Event_User_ExitsNode.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-user-exitsnode.png) User Exited Node

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/6ogimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/6ogimage.png)

The **User Exited Node event node** tracks the physical boundaries of a specific 3D object and activates the exact moment a user's avatar stops colliding with or fully exits its volume. While enabled, the node watches the targeted SceneNode and triggers its output as soon as the user completely separates from the object, passing forward a reference to the specific User who left before continuing the execution logic. And like **User Enter Node**, it also applies to all participants within multiplayer VR collaboration scenes.

---

### User Joined

Runs part of your scene whenever someone new joins your shared collaborative session.

#### What it does

When several people share the same VR/3D session, this node watches for new arrivals. Each time another person joins, the node fires on its own — you don’t need to trigger it from anywhere. It also hands you the person who just joined, so you can greet them, show them a welcome message, or update a list of who’s present.

The node only reacts to people joining; it doesn’t change anything about the session or the new arrival on its own. Whatever happens next is up to the steps you wire after it.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and will react to people joining. Set it to false to switch the event off — for example, once your scene has finished its opening sequence. Leave it true to keep listening.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time someone new joins the session. Wire this to whatever you want to happen on a new arrival.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The person who just joined. Use this to greet them by name, give them a starting position, or add them to your list of participants.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-%E2%80%94-"><tbody><tr><td>**Enable** input</td><td>`true` — keep listening for new arrivals throughout the session</td></tr><tr><td>**Execute** output</td><td>Fires when a new person joins; wire it to a step that shows a “Welcome!” pop-up</td></tr><tr><td>**User** output</td><td>The person who joined — for example `<alice>`</td></tr></tbody></table>

#### Tips

- This node fires once per person each time someone joins. If three people join, it runs three separate times — once for each, with that person on the **User** output.
- Pair it with the matching “User Left” event to keep an up-to-date list of who is currently in the session.

---

### On QR Detected

Reacts the moment a QR code is spotted by the camera, and hands you the text stored inside it.

#### What it does

This node watches for QR codes in the scene’s view. As soon as one is detected, the node fires on its own — you don’t need to trigger it from another node. It then gives you the text that was encoded in the QR code, so you can react to it however you like (open a door, show a message, jump to another part of your training, and so on).

It keeps listening as long as it is switched on, firing again each time a QR code is read. It only reports what the code contains — it doesn’t change anything by itself.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches the event on or off. While this is `true` the node is actively watching for QR codes; set it to `false` to turn the event off so it stops reacting.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time a QR code is detected. Wire this to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**Message**</td><td style="white-space: nowrap;">Text</td><td>The text that was stored inside the detected QR code — for example a web address, a part number, or a station name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-me"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Message** output</td><td>`Station-04`</td></tr></tbody></table>

#### Tips

- Connect the **Message** text to a node that compares it against the codes you expect, so different QR codes can lead to different actions.
- Set **Enable** to `false` once you no longer need to scan, so the node stops reacting to stray codes in view.

The **User Exited Node event node** tracks the physical boundaries of a specific 3D object and activates the exact moment a user's avatar stops colliding with or fully exits its volume. While enabled, the node watches the targeted SceneNode and triggers its output as soon as the user completely separates from the object, passing forward a reference to the specific User who left before continuing the execution logic. And like **User Enter Node**, it also applies to all participants within multiplayer VR collaboration scenes.

# Variable

### ![Events_Variable_Change.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/events-variable-change.png) Variable Changed

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/yCFimage.png)The **Variable Changed** event activates when the value of a specified variable is modified. This event helps users detect real-time changes and trigger actions accordingly, enabling dynamic and responsive interactions within the VR Experience.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/VBwimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/VBwimage.png)

<div class="pointer-container" id="bkmrk-%C2%A0-0"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>In this example, the **Variable Changed** event is set to monitor changes in the variable **Door**. When the value of this variable is modified, the event triggers the **Play Animation Sequence** node, which activates the **Door Anim** animation sequence.

<div class="mb-2 flex gap-3 empty:hidden -ml-2" id="bkmrk--0"><div class="items-center justify-start rounded-xl p-1 flex"><div class="flex items-center"><button aria-label="Read aloud" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="voice-play-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Copy" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="copy-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex"><button aria-label="Good response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="good-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Bad response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="bad-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button>  
</div><button aria-label="Edit in canvas" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex items-center pb-0"><svg class="icon-md" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg>  
</div><button aria-expanded="false" aria-haspopup="menu" class="cursor-pointer h-[30px] rounded-md px-1 text-token-text-secondary hover:bg-token-main-surface-secondary" data-state="closed" id="bkmrk--2" type="button"></button></div></div></div>

# On Message Received

SimLab Composer 14 introduces WebSocket support, enabling seamless integration with external systems, allowing it to work with external hardware, co-simulation engines, and websites, unlocking numerous possibilities.

Use the node **On Message Received** to trigger an event when a message is received.  
  
The **On Message Received** node triggers an event when an unhandled message is received from the external connection. This node allows you to access the incoming message and take appropriate action based on its content. It is useful for responding to external data or commands and processing messages within the VR Experience.

This node is related to Open External Connection node

[![Screenshot 2025-02-02 161759.jpg](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/screenshot-2025-02-02-161759.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/screenshot-2025-02-02-161759.jpg)

**Input Ports:**

- Enable

**Output Ports:**

- Execute
- Message

  
The WebSocket nodes (Open External Connection, Send Message, and Receive Message) are exclusively available in the Ultimate Edition.

# Voice Command

### [![Response_Gadget_EquipToUser.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-gadget-equiptouser.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Voice Command Recognized 

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/ba6image.png)

The **Voice Command Recognized event** is used to activate a response when the user says a specific command. This event listens for predefined voice commands and triggers the associated actions or responses within the VR environment upon recognizing the command.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/Dkrimage.png)

In this example, a new voice command named "Door Open" is created by accessing the Voice Command section from the Interaction menu and adding the command in the Voice Commands window.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/QIFimage.png)

The **Voice Command Recognized** **event** is used to link the newly created "Door Open" command. When the user says "Open the door", the door open sequence is triggered and plays.

---

### Voice Command Test

Listens for a spoken voice command and reacts when someone in your scene says one.

#### What it does

This node waits and listens. Whenever a person in your VR scene speaks a voice command out loud, the node fires on its own — you don’t need anything to trigger it. Each time it fires, it tells you the exact words that were spoken and which user said them, so you can respond to what they asked for.

The node stays active only while its **Enable** input is true. Set **Enable** to false whenever you want to stop listening for voice commands.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the node is listening for voice commands; set it to false to switch the listening off. Leave it true to keep responding to spoken commands.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time a voice command is spoken. Wire this to whatever should happen in response.</td></tr><tr><td style="white-space: nowrap;">**Command**</td><td style="white-space: nowrap;">Text</td><td>The words that were spoken, as text. Use this to decide how to react to what was said.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The person who spoke the command, so you can respond to that specific user.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-co"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Command** output</td><td>`open the door`</td></tr><tr><td>**User** output</td><td>The trainee who spoke the command</td></tr></tbody></table>

#### Tips

- Connect the **Command** output to a node that compares text, so you can run different actions for different spoken phrases.
- If you want voice commands active only during a certain part of your scene, wire a true/false value into **Enable** and switch it off when that part is over.

# Execution

### [![Event_CustomEvent_Triggered.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-customevent-triggered.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/event-customevent-triggered.png) Custom Event 

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/0hbimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/0hbimage.png)

This event is activated manually by the user. It's useful when you want multiple different paths or actions to lead to the same response.

To set it up, use the [**Trigger Custom Event** response](https://simlab-soft.com/help/link/365#bkmrk-trigger-custom-actio) and assign it a unique ID (e.g., `path1`). You can place this trigger in as many locations as needed.

Whenever a **Trigger Custom Event** is called, it will execute the **Custom Event** that has a matching ID.

If you want to pass additional info, you can use the info field in **Trigger Custom Event** response, this data will be passed to the even in the info port

---

### [![Event_Scene_Start.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-scene-start.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/event-scene-start.png) Scene Start

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/2T1image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/2T1image.png)

This event is triggered automatically when the scene begins. Use it to initialize elements at startup, such as playing videos, running background animations, or any other setup tasks.

> **Note:** Since this event fires the moment the scene loads, it's recommended to add a small delay before making additional scene changes — this ensures all scene elements have fully initialized before anything else runs.

---

### ![Event_Ticker.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-ticker.png) Ticker

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/pYZimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/pYZimage.png)

The **Ticker** event node functions as a continuous, time-based loop that repeatedly activates subsequent nodes at a consistent rate. As long as its Enable input is set to *True*, the node constantly triggers its Execute output every time the duration specified in the numerical Interval input (measured in seconds) elapses. Once activated, it continually outputs this time value through the Period pin, allowing the logic flow to perform recurring actions or background checks for as long as the node remains enabled.

**Example:**

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/OfNimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/OfNimage.png)

In this example, we use the Ticker node to create a loop that randomly changes a material's color every 2.5 seconds:

1. A **Watch Boolean Expression** node continuously monitors the "speed1" variable and activates the **Ticker** node once the value equals 1.
2. While enabled, the **Ticker** node creates a continuous loop that triggers its execution output every 2.5 seconds.
3. The Ticker simultaneously executes three **Set Number Variable By Expression** nodes to generate random values using the `math.random()` function for the variables r1, g1, and b1.
4. These three random numbers are passed into an **RGB To Color** node, where they are combined to formulate a new color.
5. Finally, this new color is sent to a **Set Material Color** node, which immediately applies the randomly generated color to the target material.

---

### [![Event_Error.png](https://simlab-soft.com/help/uploads/images/gallery/2026-06/scaled-1680-/odqevent-error.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-06/odqevent-error.png) Error

Fires whenever an error happens while your experience is running, and hands you a message describing what went wrong.

#### What it does

This node is a safety net. Unlike most nodes, you do not trigger it from an earlier node — it listens on its own in the background while your experience runs. If an error occurs, its **Execute** output fires and its **Error Message** output gives you the text of that error. Instead of letting a problem pass unnoticed, you can respond to it — show the user a clear message, make a note of what happened, or move things to a safe state.

#### Turning it on and off

The **Enable** input controls whether the event is listening. It is **on by default**, so the node starts catching errors as soon as your experience begins. If you only want to catch errors during a certain part of your experience, connect a Yes/No value to **Enable** and switch it on and off as needed; while it is off, the event stays quiet and its **Execute** output will not fire.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>*Optional.* Whether the event is listening for errors. **On** by default — leave it on to catch errors the whole time, or connect a Yes/No value to switch it on and off.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires the moment an error occurs while the event is enabled. Wire it to whatever should happen in response.</td></tr><tr><td style="white-space: nowrap;">**Error Message**</td><td style="white-space: nowrap;">Text</td><td>A short description of the error that occurred.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-on-%28the"><tbody><tr><td style="white-space: nowrap;">**Enable** input</td><td>**On** (the default)</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires when an error happens</td></tr><tr><td style="white-space: nowrap;">**Error Message** output</td><td>`Could not load the requested file.` — the exact wording depends on what went wrong</td></tr></tbody></table>

#### Tips

- **Respond to the problem.** Wire **Execute** to something that handles it — show the user the **Error Message**, make a note of it, or move the scene to a safe state — rather than letting the error pass silently.
- **Show the message.** The **Error Message** output is plain text, so you can display it on a panel or pass it into another node.
- **Limit when it listens.** Leave **Enable** on to watch the whole time, or turn it off during parts of your experience where you would rather handle problems yourself.

# Snapping

### ![Event_Node_Snapping_CanSnap.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-snapping-cansnap.png) Node Ready To Snap

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/3Lvimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/3Lvimage.png)

The **Node Ready to Snap** event node activates the exact moment a designated SceneNode enters the valid snapping range of an eligible target. This node is highly useful for triggering immediate visual or audio feedback—such as highlighting a destination socket green or playing a hovering sound—letting the user know the object is ready to be released and snapped.

### ![Event_Node_Snapping_Snapped.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-snapping-snapped.png) Node Snapped

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/djHimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/djHimage.png)

The **Node Snapped** event node activates immediately after a SceneNode has successfully completed its snapping action onto a target socket. This event is typically used to seamlessly progress a sequence, such as locking the snapped part in place, playing a mechanical click sound, or advancing the user to the next step of an assembly training scenario.

# SceneNode \ Attributes

These event nodes watch an object and fire automatically the moment one of its **attributes** changes — so you can react when an attribute is added, edited, or removed without having to keep checking for it yourself. They pair naturally with the **Set Node Attribute** and **Remove Node Attribute** nodes, which are what usually make these events fire.

Each event watches the object you connect to its **SceneNode** input. When it fires, it hands you the object that changed along with the **Category** and **Name** of the attribute involved, so you know exactly what happened. Leave the **Enable** input on to keep watching, or turn it off to pause.

### ![Node_Attribute_Added.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-attribute-added.png) Node Attribute Added

Fires automatically the moment a brand-new attribute is added to an object.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/SPvimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/SPvimage.png)

#### What it does

The **Node Attribute Added** event node continuously monitors the targeted SceneNode and activates whenever a completely new attribute is attached to it. This event is typically used in conjunction with **Set Node Attribute nodes** to trigger subsequent actions. Once activated, it outputs the affected SceneNode along with the specific Category and Name of the newly created attribute.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Turns the watch on or off. It is on by default; set it to `false` to pause watching and back to `true` to resume.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to watch.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time a new attribute is added to the object. Wire the next node here to react — this is what starts the chain.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object the change happened on.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category the affected attribute belongs to.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the affected attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the-"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>fires when an attribute is added to the forklift</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Category** output</td><td>`Maintenance`</td></tr><tr><td style="white-space: nowrap;">**Name** output</td><td>`inspected`</td></tr></tbody></table>

---

### ![Node_Attribute_Changed.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-attribute-changed.png) Node Attribute Changed

Fires automatically whenever the value of one of an object’s attributes changes.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Ciwimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Ciwimage.png)

#### What it does

The **Node Attribute Changed** event node observes the targeted SceneNode and activates whenever the value of any of its existing attributes is modified. Once activated, the node outputs the affected SceneNode alongside the exact Category and Name of the altered attribute.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Turns the watch on or off. It is on by default; set it to `false` to pause watching and back to `true` to resume.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to watch.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time one of the object’s attributes changes value. Wire the next node here to react — this is what starts the chain.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object the change happened on.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category the affected attribute belongs to.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the affected attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--0"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>fires when one of the forklift’s attributes changes value</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Category** output</td><td>`Maintenance`</td></tr><tr><td style="white-space: nowrap;">**Name** output</td><td>`inspected`</td></tr></tbody></table>

---

### ![Node_Attribute_Removed.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/event-node-attribute-removed.png) Node Attribute Removed

Fires automatically the moment an attribute is removed from an object.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/0Lcimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/0Lcimage.png)

#### What it does

The **Node Attribute Removed** event node tracks the targeted SceneNode and activates the moment an existing attribute is deleted from the object. This event is typically used alongside the **Remove Node Attribute** node to initiate reactions to data clearance. Once activated, it outputs the affected SceneNode forward along with the specific Category and Name of the deleted attribute.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Turns the watch on or off. It is on by default; set it to `false` to pause watching and back to `true` to resume.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to watch.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time an attribute is removed from the object. Wire the next node here to react — this is what starts the chain.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object the change happened on.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category the affected attribute belongs to.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the affected attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--1"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>fires when an attribute is removed from the forklift</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Category** output</td><td>`Maintenance`</td></tr><tr><td style="white-space: nowrap;">**Name** output</td><td>`tempNote`</td></tr></tbody></table>

# SceneNode \ Assembly

These are **event** nodes for SimLab’s **VR assembly** system. Each one watches a single part and fires the moment something happens to that part in the assembly — for example the moment it becomes fully assembled, or the moment it becomes this part’s turn to be put on. You wire the event’s output to whatever should happen in response.

Unlike an action you run in a sequence, an event runs on its own — it has no Execute input. Every node on this page works the same way:

- **Enable** (true/false) switches the event on or off. It is on by default; set it to `false` to stop the event from firing.
- **SceneNode** (input) is the part to watch.
- **Execute** (output) fires once each time the event happens — wire it to what should happen next.
- **SceneNode** (output) hands the same part back, so you can act on it in your response.

In a VR assembly, parts go together and come apart in a set order, and a part can be **fully assembled** (in place and secured), **partially assembled** (seated but not yet secured), or **fully disassembled** (all the way out). These events let your scene react the instant a part reaches one of those points, or the instant it becomes — or stops being — the part that may be added or removed next.

To *read* or *set* a part’s assembly state on demand instead of reacting to it, see the **SceneNode \\ Assembly** page; to continuously *check* a part’s state as a true/false condition, see the **Assembly** page.

## What’s on this page

- **Node Assembled** — fires when a part becomes fully assembled.
- **Node Disassembled** — fires when a part becomes fully disassembled.
- **Node Can be Assembled** — fires when it becomes this part’s turn to be put on.
- **Node Can Not be Assembled** — fires when the part is no longer the one allowed to be put on next.
- **Node Can be Disassembled** — fires when it becomes this part’s turn to be taken off.
- **Node Can Not be Disassembled** — fires when the part is no longer the one allowed to be taken off next.

## When a part is fully assembled or fully taken apart

---

### Node Assembled

Fires the moment a part finishes being fully assembled into its place in an assembly.

#### What it does

This event keeps an eye on one part of your assembly. As soon as that part is put fully into place — seated and secured in its spot — the event fires on its own. It does not run as a step in a sequence; it simply watches and waits, then reacts.

When it fires, it hands the same part straight back out so you can act on it right away — for example, play a sound, show a “Step complete” message, or light up the next part to install. Watching a part this way doesn’t change it in any way.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches this event on or off. Leave it on (the default is `true`) to watch for the part being assembled. Set it to `false` to turn the event off — while off, it will not fire.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch. Connect the part from your assembly that should trigger this event when it is fully put into place.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once each time the watched part becomes fully assembled. Connect it to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same part you were watching, handed back so you can use it in the steps that follow.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-sc"><tbody><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>The `Front Wheel` part of your assembly</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires the instant the `Front Wheel` is fully assembled</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>Hands back the `Front Wheel` so you can highlight it or play a confirmation sound</td></tr></tbody></table>

#### Tips

- You don’t need to start this event from another node — it watches the part and fires by itself the moment the part is fully assembled.
- Connect the **SceneNode** output to the next action so it works on the exact part that was just put into place.

---

### Node Disassembled

Fires the moment a part in a VR assembly becomes fully taken apart — all the way out of place, not just loosened.

#### What it does

This node watches one part and waits for it to become **fully disassembled**. In SimLab’s assembly system a part moves through three stages — think of a screw: tightened down (fully assembled), dropped into place but not tightened (partially assembled), or all the way out (fully disassembled). The instant the part reaches that last stage — completely out of place — this node fires on its own.

It does not run as a step in a sequence and it never moves or changes the part — it only watches and reacts. When the part comes all the way out, the **Execute** output fires once and hands the same part back on its **SceneNode** output, so you can act on it in your response — for example mark a disassembly step complete or play a sound. You can switch the watching on or off with the **Enable** input.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches this event on or off. It is on by default (`true`), so you can leave it unconnected. Set it to `false` — or feed it a true/false value from elsewhere — when you want to stop the event from firing; while it is `false` the node ignores the part coming apart.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch — for example a `Bolt_01` object from your assembly. The node fires the moment this part becomes fully disassembled.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once each time the watched part becomes fully disassembled — the instant it comes all the way out of place. Wire this to whatever should happen next, such as marking the step done, playing a confirmation sound, or moving on to the next part.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>Hands back the same part you were watching, so you can act on it in your response — for example pass it on to a node that hides it or highlights it. It is the same object you connected to the input, unchanged.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true` — the event is watching (leave it unconnected for the same result)</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires the instant `Bolt_01` is backed all the way out — you could use it to mark the disassembly step complete and play a confirmation sound</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Bolt_01` — the same part, ready to pass on to whatever acts on it next</td></tr></tbody></table>

#### Tips

- This event fires once, at the moment the part comes fully out — not continuously while it stays out. If you instead need the current “is it fully out?” answer as a true/false value at any time, use the matching **Node Fully Disassembled** state node on the **Assembly** page.
- A part that is only loosened or seated but not all the way out does *not* fire this event — it fires only when the part is completely disassembled.
- Use the **Enable** input to turn the event off during parts of your scene where a part coming apart shouldn’t trigger anything.

## When a part becomes ready (or stops being ready)

---

### Node Can be Assembled

Fires on its own the moment a part in a VR assembly becomes ready to be put on next — that is, when it finally becomes this part’s turn in the assembly order.

#### What it does

In a VR assembly, parts go on in a set order, and some parts can only be added once the parts before them are already in place. This event keeps an eye on the one part you connect and waits for the moment it becomes ready — the instant everything that has to come before it is assembled, so it is now this part’s turn. The event does not run as part of a sequence; it watches quietly on its own and goes off by itself at that exact moment.

When that moment arrives, the event fires once and hands you back the same part you connected, so you can act on it right away — for example highlight it or show a hint that it is ready to be fitted next. It only watches and reacts; it never assembles the part or changes anything in your scene. You can switch the event off and on with the Enable input.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches the event on or off. It is on by default, so you can usually leave it alone. Connect a true/false value if you want to turn the event off at certain times — while it is `false`, the event will not fire even when the part becomes ready.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch — for example a `Bolt_01` object from your assembly. The event fires the moment this part becomes allowed to be assembled next.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once each time the part becomes ready to be assembled — the instant the last part that had to come before it is finally in place. Wire this to whatever should happen then, such as highlighting the part or showing a “fit this next” hint.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>Hands back the same part you connected, so you can act on it in whatever runs next — for example pass it straight into a node that highlights or selects it.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt-0"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true` — the event is watching (the default)</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires the instant the `Housing` and `Gear` that come before `Bolt_01` are in place — it is now the bolt’s turn, so you could highlight it to guide the trainee to fit it next</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>Hands back `Bolt_01` so you can highlight or select that exact part</td></tr></tbody></table>

#### Tips

- This event fires only at the moment the part *becomes* ready — not over and over while it stays ready. If the part is already ready when your scene starts, the event waits until the answer leaves and returns to ready before firing again.
- Leave **Enable** on for normal use. Connect a true/false value to it only when you want to silence the event during certain parts of your scene.
- This event only reacts to readiness — it never assembles the part. Combine it with your assembly steps to guide the trainee through the parts in the right order.

---

### Node Can Not be Assembled

Fires on its own the moment a part in a VR assembly is *not* allowed to be put on next — that is, when it is not yet this part’s turn in the assembly order.

#### What it does

In a VR assembly, parts go together in a set order, and a part can only be added once the parts that come before it are already in place. This event watches one part and waits for the moment it becomes **not** ready to be assembled — for example, an earlier part it depends on is still missing or has just been taken back off, so it is no longer this part’s turn. When that happens, the event fires once on its own and hands you back the same part so you can react.

You don’t run this event yourself and you don’t wire anything into it from an earlier step — it simply listens while your scene plays and fires the instant the part stops being allowed to go on next. It only watches; it never assembles the part or changes anything in your scene. Use the **Enable** input to switch the watching on or off, and connect the **Execute** output to whatever should happen at that moment, such as hiding a hint or dimming the part’s highlight.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches this event on or off. It is on by default, so the event watches the part and fires when the moment comes. Connect a true/false value to turn the watching off — while it is off (`false`), the event will not fire, no matter what happens to the part.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch — for example a `Bolt_01` object from your assembly. The event fires when this part becomes not allowed to be assembled next.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once each time the part becomes not allowed to be assembled next — the instant it stops being this part’s turn. Wire this to whatever should happen then, such as hiding a “fit this next” hint or turning off the part’s highlight.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>Hands back the same part you were watching, so you can act on it in response — for example pass it straight into a node that hides it or changes its color. The part itself is not changed.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-%E2%80%94-"><tbody><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true` — the event is watching (the default)</td></tr><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires the instant `Bolt_01` is no longer the part allowed to go on next — for example the `Gear` that has to come before it has just been taken back off. You could hide the “fit the bolt” hint until its turn comes around again.</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Bolt_01` — the same part, ready to send into the node that turns off its highlight</td></tr></tbody></table>

#### Tips

- This is the opposite of **Node Can be Assembled**: that event fires when it becomes the part’s turn to go on, and this one fires when it stops being its turn. Use the two together to highlight a part the moment it is ready and clear the highlight the moment it isn’t.
- Set **Enable** to `false` when you want to stop reacting — for example once a guided step is finished — so the event no longer fires.
- This event only reports; it never assembles the part or moves it. Pair it with your normal assembly steps to guide the trainee through the parts in the right order.

---

### Node Can be Disassembled

Fires on its own the moment a part in a VR assembly becomes the next one allowed to be taken off.

#### What it does

In a VR assembly, parts come apart in a set order — some parts can only be removed once the parts on top of them have already been taken off. This node keeps an eye on one part you choose and waits for the moment it becomes that part’s turn to be removed: when everything that had to come off before it is already off, the event fires.

It fires by itself the instant that happens — you don’t run it from another node. Each time it fires, it also hands you back the part it is watching, so you can act on that exact part in response (for example, highlight it to guide the trainee). It only watches and reacts — it never moves or takes apart the part itself.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches the event on or off. It is on (`true`) by default, so you can usually leave it alone. Set it to `false` when you want to ignore this event for a while — while it is off, the event will not fire.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch — for example a `Bolt_01` object from your assembly. The event fires when this part becomes the next one allowed to be taken off.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the moment it becomes this part’s turn to be taken off — that is, when the last part that had to come off before it is finally removed. Wire this to whatever should happen next, such as highlighting the part or showing a hint.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same part you connected on the way in, handed back so you can act on it right away — for example pass it into a node that highlights it or shows its name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt-1"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true` — the event is on and watching</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires the instant the `Cover` that sits over `Bolt_01` is removed — the bolt is now the next part allowed to come off, so you could highlight it to guide the trainee to remove it next</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Bolt_01` — handed back so you can highlight it or show its name</td></tr></tbody></table>

#### Tips

- This is an event — it fires on its own when the part’s turn comes. You don’t connect it after another node; instead you connect its **Execute** output to what should happen.
- Use the **SceneNode** output rather than naming the part again downstream — it is already the exact part the event watched.
- To pause this event for part of your scene, set **Enable** to `false`; set it back to `true` to start watching again.

---

### Node Can Not be Disassembled

Fires the moment a part stops being the one allowed to be taken off next in the assembly order.

#### What it does

In a SimLab assembly, parts come apart in a set order, and at any moment only certain parts are allowed to be removed. This event watches the part you connect and fires on its own the instant that part is no longer the one allowed to be taken off next — for example, when an earlier part that had to come off before it is put back, so it is no longer this part's turn to remove.

It does not watch for the user trying to remove the part, and it does not change anything in the scene. It simply notices the change in the order and hands you back the same part so you can react — show a hint, lock something, play a sound, or update a score.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Switches the event on or off. Leave it `true` (the default) to have it watch the part. Set it to `false` to turn the event off so it will not fire.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch — the assembly piece whose turn-to-be-removed you care about.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once each time the watched part stops being the one allowed to be taken off next. Wire it to whatever should happen in response.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>Hands back the same part you were watching, so you can act on it in your response.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-brak"><tbody><tr><td>**SceneNode** input</td><td>`Brake Caliper`</td></tr><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Execute** output</td><td>Fires the moment the Brake Caliper is no longer allowed to be taken off next — for instance, after the Mounting Bolt that comes off before it is put back on.</td></tr><tr><td>**SceneNode** output</td><td>`Brake Caliper` — ready to dim, lock, or show a “not yet” hint on.</td></tr></tbody></table>

#### Tips

- This is an automatic event — it fires on its own when the order changes. You do not need to trigger it from another node.
- Use it together with **Node Can be Disassembled** to react both when a part becomes allowed to be removed and when it stops being allowed.
- To pause this event during part of your scene, feed the **Enable** input a `false` value; switch it back to `true` to resume watching.

# SceneState

### SceneState Applied

Reacts the moment a saved scene state is switched on in your scene.

#### What it does

A scene state is a saved arrangement of your scene — which objects are shown or hidden, where they sit, the materials they use, and so on. This node watches for one of those saved states being applied, and fires the instant it happens. You can use it to start something automatically whenever the scene changes to a particular look — play a sound, show a message, move on to the next step, and so on.

If you connect a specific scene state to the **SceneState** input, the node only fires when that exact state is applied. Leave it empty to react to any scene state being applied. The node simply listens — it doesn’t apply or change any state itself, and it passes the applied state straight through so you can use it further down the line.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and will fire. Set it to false to switch the event off so it stops reacting.</td></tr><tr><td style="white-space: nowrap;">**SceneState**</td><td style="white-space: nowrap;">Scene state</td><td>The specific saved scene state to watch for. Connect one to react only when that state is applied. Leave it empty to react to any scene state being applied.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time a matching scene state is applied. Wire this to whatever you want to happen next.</td></tr><tr><td style="white-space: nowrap;">**SceneState**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state that was just applied, passed along so you can use it in the steps that follow.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-sc"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**SceneState** input</td><td>The saved state named `Doors Open`</td></tr><tr><td>**Execute** output</td><td>Fires the moment the `Doors Open` state is applied</td></tr><tr><td>**SceneState** output</td><td>Hands on the `Doors Open` state for the next node to use</td></tr></tbody></table>

#### Tips

- Leave the **SceneState** input empty if you want to react to every scene state change rather than one in particular.
- Turn the event off at any time by setting **Enable** to false — handy when you only want to listen during part of your experience.

# SceneNode \ Grab

These events fire when a user picks up or lets go of a scene object in VR. Use them to react the moment an object is grabbed or released — for example to highlight a tool when it is held, or reset it when it is put down. Each event also tells you which user did it.

## Grab events

### Node Grab Started

Reacts the moment a user picks up (grabs) a chosen object in your scene.

#### What it does

This is an event. It doesn’t wait for another node to start it — it watches a specific object in your scene and fires on its own the instant a user grabs that object. This is the ideal place to begin an action that should happen when someone first takes hold of something, like a tool, a handle, or a part to assemble.

Each time the grab happens, the node hands you the object that was grabbed and the user who grabbed it, so you can react to exactly who did what. It only watches while its **Enable** input is true — turn that off and the event stops listening.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and listening for the grab; set it to false to switch the event off. If you leave it unconnected it stays on.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene to watch. The event fires when a user grabs this object. (The viewer start position can’t be used here.)</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires when the chosen object is grabbed. Wire this onward to the action you want to start.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object that was grabbed — the same one you chose to watch.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user who grabbed the object, so you can tell who performed the action.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-wren"><tbody><tr><td>**SceneNode** input</td><td>`Wrench`</td></tr><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Execute** output</td><td>Fires the moment a user picks up the wrench</td></tr><tr><td>**SceneNode** output</td><td>`Wrench`</td></tr><tr><td>**User** output</td><td>`Trainee 1`</td></tr></tbody></table>

#### Tips

- Pair this with **Node Grab Ended** to know both when the user takes hold of the object and when they let go.
- Use the **User** output in a multi-user session to react only to the person who actually grabbed the object.

---

### Node Grab Ended

Reacts the moment someone lets go of an object they were holding in your scene.

#### What it does

This node watches a scene object and fires the instant a user releases their grip on it — the end of a grab. It runs on its own; you don’t wire it after another node. As long as its **Enable** input is true, the node stays on the lookout. Each time a grab on the watched object ends, the node fires and tells you which object was let go and which user let go of it.

Use it to react when a tool is set down, a part is dropped into place, or a handle is released — for example, snapping an object to a holder, playing a sound, or scoring a step in a training task. Watching for the release doesn’t change the object in any way; it simply notices the moment it happens.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Turns the watch on or off. While this is true the event is active; set it to false to switch the event off. Leave it true if you always want to react to releases.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene to watch. The node fires when a user lets go of this object. (The viewer’s start position can’t be used here.)</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time someone lets go of the watched object. Wire this to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object that was just released — the same object you were watching. Handy when the same logic watches more than one object.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The person who let go of the object, so you can react to who performed the action.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-sc"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**SceneNode** input</td><td>Your `Wrench` object</td></tr><tr><td>**Execute** output</td><td>Fires the moment the wrench is let go — wired to snap it back onto the tool rack</td></tr><tr><td>**SceneNode** output</td><td>The `Wrench` that was released</td></tr><tr><td>**User** output</td><td>The trainee who set the wrench down</td></tr></tbody></table>

#### Tips

- Pair this with **Node Grab Started** to handle both ends of an interaction — one reacts when an object is picked up, this one when it’s put down.
- To stop reacting to releases for a while (for example during a cutscene), feed **Enable** a false value, then set it back to true when you want the watch to resume.

# SceneNode \ Hover

These events fire when a user points at or moves away from a scene object in VR (without grabbing it). Use them to react as an object is hovered — for example to highlight it, show a label, or hide that hint again when the user looks elsewhere. Each event also tells you which user did it.

## Hover events

### Node Hover Started

Reacts the moment a user begins pointing at (hovering over) a chosen object in your scene.

#### What it does

This event fires the instant a user’s pointer or gaze starts resting on the object you connect to it — for example when someone aims their VR controller at a machine part or moves their cursor onto it. It fires once at the start of each hover; it does not keep firing while the pointer stays on the object.

When it fires, it hands you the object that was hovered and the user who started the hover, so you can light up the object, show a label, or play a sound. It only watches for hovers while its **Enable** input is true, and it never changes the object itself.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and watches for hovers; set it to false to switch the event off. Defaults to true, so you can leave it unconnected to keep it always on.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene you want to watch. The event fires when a user starts hovering over this object. (A viewer start position cannot be used here.)</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires when a user starts hovering over the object. Wire this to whatever should happen next, such as highlighting the object or showing a tooltip.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object that was hovered over. Handy when one event watches several objects and you want to know which one was pointed at.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user who started the hover. Useful in shared sessions where more than one person can point at objects.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-sc"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**SceneNode** input</td><td>The `Control Panel Button` object</td></tr><tr><td>**Execute** output</td><td>Fires the moment the user aims at the button</td></tr><tr><td>**SceneNode** output</td><td>The `Control Panel Button` object</td></tr><tr><td>**User** output</td><td>The user who pointed at it, e.g. `Trainee 1`</td></tr></tbody></table>

#### Tips

- Pair this with a “Node Hover Ended” event to turn a highlight on when the hover starts and off again when it stops.
- Set **Enable** to false to pause the hover reaction during parts of your scene where it should be ignored.

---

### Node Hover Ended

Reacts the moment a user stops pointing at (or looking at) a particular object in your scene.

#### What it does

This node watches one object you choose. While it is switched on, it fires the instant a user’s hover leaves that object — for example when they move their controller, gaze, or cursor away from it after hovering over it. It’s the natural partner to a hover-start event, letting you undo a highlight, hide a tooltip, or reset an object once the user looks elsewhere.

Each time it fires, it hands you the object the user stopped hovering over and the user who did it, so you can respond to exactly the right thing. It only watches and reports — it doesn’t change the object in any way.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and watching. Set it to false to switch the event off so it stops firing.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene to watch. The event fires when a user stops hovering over this object. (The viewer start position cannot be used here.)</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires when the user stops hovering over the chosen object. Wire this to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object the user stopped hovering over — handy when you want to act on that same object.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user whose hover just left the object. Useful in shared sessions to tell who did it.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-sc-0"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**SceneNode** input</td><td>The `Control Panel Button` object in your scene</td></tr><tr><td>**Execute** output</td><td>Fires when the user moves their pointer off the button — wire it to a node that removes the button’s highlight</td></tr><tr><td>**SceneNode** output</td><td>`Control Panel Button`</td></tr><tr><td>**User** output</td><td>The user who was hovering, e.g. `Trainee 1`</td></tr></tbody></table>

#### Tips

- Pair this with a hover-start event on the same object: start the highlight when hovering begins, and use this node to remove it when hovering ends.
- To stop watching at any time, feed a false value into **Enable** — the event will go quiet until you switch it back on.

# Sequence

These events fire in response to what a playing sequence does, so you can react automatically when a sequence reaches a key moment — without having to start the check yourself.

## Sequence events

### Sequence Ended

This node lets your scene react the moment a sequence finishes playing.

#### What it does

This is an event node, so it runs on its own — you don’t wire anything into it to start it. It watches the sequence you give it, and the moment that sequence reaches its end, the node fires. You can use it to start the next thing in your scene, show a message, or move on to another step once the animation or playback has completed.

It only watches; it doesn’t change the sequence in any way. While its **Enable** input is true the event is active and listening; turn that off and the node simply stops reacting until you switch it back on.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and watching the sequence; set it to false to switch the event off. If you leave it unconnected it stays on.</td></tr><tr><td style="white-space: nowrap;">**Sequence**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence you want to watch. The node fires once this sequence finishes playing.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time the watched sequence ends. Wire this to whatever you want to happen next.</td></tr><tr><td style="white-space: nowrap;">**Sequence**</td><td style="white-space: nowrap;">Sequence</td><td>The same sequence that just ended, passed along so you can use it in the steps that follow.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-se"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Sequence** input</td><td>Your `Door Opening` sequence</td></tr><tr><td>**Execute** output</td><td>Fires the moment the door has finished opening — connect it to play a sound or reveal the next instruction.</td></tr><tr><td>**Sequence** output</td><td>The `Door Opening` sequence, handed on to the next node.</td></tr></tbody></table>

#### Tips

- Use the **Enable** input to turn this event on only when it matters — for example, switch it off during an intro so an early sequence ending doesn’t trigger your next step too soon.

# Boolean

These events watch a true/false value and fire the moment it changes — so you can start something the instant a condition becomes true, becomes false, or simply flips either way. They never change the value they are watching; they only react to it.

## Boolean events

### On True

Watches a true/false value and fires the moment it turns true.

#### What it does

Connect any true/false value to this node, and it keeps an eye on it. Each time that value changes from false to true, the node fires — letting you start whatever should happen at that moment. For example, you can use it to react the instant a door becomes open, a switch is flipped on, or a task is marked complete.

The node only watches and reacts; it never changes the value it is watching. It stays active as long as its **Enable** input is true, so you can switch the whole watch on or off whenever you like.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and watching. Set it to false to switch the event off. It is on by default.</td></tr><tr><td style="white-space: nowrap;">**Boolean State**</td><td style="white-space: nowrap;">True / false</td><td>The true/false value to watch. The node fires each time this value turns true.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time the watched value turns true. Wire this to whatever you want to happen at that moment.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-bo"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Boolean State** input</td><td>The “door is open” value from a door sensor</td></tr><tr><td>**Execute** output</td><td>Fires the instant the door becomes open — for example, to play a sound or show a message</td></tr></tbody></table>

#### Tips

- This node reacts only when the value *changes* to true, not for the whole time it stays true. If you need something to keep running while the value is true, use a node that checks the ongoing state instead.
- To pause watching without removing the node, set **Enable** to false.

---

### On False

This event runs part of your scene whenever a true/false value turns false.

#### What it does

On False watches a true/false value you give it. The moment that value changes to false, this event fires and runs whatever you have connected to its output. It only watches while it is switched on, so you can turn it off when you don’t need it.

Use it to react to something turning off — for example a light switching off, a door closing, or a checkbox being cleared. It only reacts to the value becoming false; it doesn’t change the value it is watching.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and will react when the watched value turns false. Set it to false to switch the event off. It is on by default.</td></tr><tr><td style="white-space: nowrap;">**Boolean State**</td><td style="white-space: nowrap;">True / false</td><td>The true/false value to watch. The event fires when this value becomes false.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires each time the watched value turns false. Connect this to whatever you want to run at that moment.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-bo-0"><tbody><tr><td>**Enable** input</td><td>`true`</td></tr><tr><td>**Boolean State** input</td><td>Wired from a “Light is on” value — when the light is switched off this becomes `false`</td></tr><tr><td>**Execute** output</td><td>Fires the moment the light turns off — for example to play a “lights out” sound</td></tr></tbody></table>

#### Tips

- On False reacts only when the value *changes* to false. If the value is already false when the event becomes active, it waits for the next time it turns false again.
- Pair it with On True if you want to react both when something turns on and when it turns off.

---

### On Change

Watches a true/false value and reacts the moment it flips from true to false or from false to true.

#### What it does

This is an event — it doesn’t wait for another node to start it. As long as it’s switched on, it keeps an eye on the true/false value you feed into it. Each time that value *changes* (true becomes false, or false becomes true), the node fires once.

It only reacts to a change, not to the value simply staying the same. So if the value is true and stays true, nothing happens; the node only acts at the moment of the switch. It doesn’t alter the value it’s watching — it just notices when it moves and lets the next part of your scene run.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>While this is true the event is active and watching for changes; set it to false to switch the event off. It starts switched on.</td></tr><tr><td style="white-space: nowrap;">**Boolean State**</td><td style="white-space: nowrap;">True / false</td><td>The true/false value you want to keep an eye on — for example whether a door is open, whether a switch is flipped, or whether the trainee is inside a zone. The node fires whenever this value changes.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once each time the watched value changes. Wire this into whatever should happen in response.</td></tr></tbody></table>

#### Example

<table id="bkmrk-enable-input-true-%E2%80%94-"><tbody><tr><td>**Enable** input</td><td>`true` — keep watching the whole time</td></tr><tr><td>**Boolean State** input</td><td>Whether the safety valve is open (a true/false value from the scene)</td></tr><tr><td>**Execute** output</td><td>Fires the moment the valve opens or closes — for example to play a sound or show a message</td></tr></tbody></table>

#### Tips

- This node reacts to *both* directions of change — on becoming true and on becoming false. If you only care about one direction, add a check after it for the current value.
- Turn the watching off at any time by feeding `false` into **Enable**, then back on with `true`.

# Responses



# AI Agent

### [![Response_AiAgent_Reset.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/5Y3response-aiagent-reset.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-03/5Y3response-aiagent-reset.png)AI Agent Reset Chat History

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/FTTimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/FTTimage.png)The **AI Agent Reset Chat History** node enables the system to clear and reset the ongoing conversation history for a specific AI Agent. It is typically used when you want the AI to start a completely fresh interaction or switch to a new scenario without being influenced by the context of any prior messages.

### ![Response_AiAgent_SendMessage.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-aiagent-sendmessage.png) AI Agent Send Message

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/jCDimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/jCDimage.png)

The **AI Agent Send Message** node enables the system to send a specific text message to an assigned AI Agent for processing. The **Output Voice?** boolean parameter that dictates how the AI agent will deliver its response:

- **False:** The AI agent will respond with text.
- **True:** The AI agent will process the text message and respond with generated voice audio.

### AI Agent Send Voice Message

Has one of your scene’s AI agents deliver a pre-recorded voice file to a user.

#### What it does

This node tells the AI agent you name to play a voice file for a user. You choose which agent speaks, who hears it, and which sound file to use. It’s a handy way to have an agent greet someone, give an instruction, or read out a scripted message without typing live text.

The node only sends the message — it doesn’t change the agent, the user, or the voice file in any way. Every value you feed in is also handed straight back out, so you can pass the same agent, user, or file along to the next node in your sequence.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**AI Agent Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the AI agent that should speak. Pick one of the agents set up in your scene.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The person who should hear the message. Leave it on **Host Only** to send it just to the host, or connect a user to target someone specific.</td></tr><tr><td style="white-space: nowrap;">**Voice File**</td><td style="white-space: nowrap;">Text</td><td>The name of the voice file the agent should play.</td></tr><tr><td style="white-space: nowrap;">**Output Voice?**</td><td style="white-space: nowrap;">True / false</td><td>Set to `true` to have the message played aloud as voice, or `false` to send it without sound. Defaults to `true`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**AI Agent Name**</td><td style="white-space: nowrap;">Text</td><td>The same agent name you connected, passed along so you can reuse it.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed along unchanged.</td></tr><tr><td style="white-space: nowrap;">**Voice File**</td><td style="white-space: nowrap;">Text</td><td>The same voice file name you connected, passed along unchanged.</td></tr><tr><td style="white-space: nowrap;">**Output Voice?**</td><td style="white-space: nowrap;">True / false</td><td>The same true/false setting you connected, passed along unchanged.</td></tr></tbody></table>

#### Example

<table id="bkmrk-ai-agent-name-input-"><tbody><tr><td>**AI Agent Name** input</td><td>`Guide`</td></tr><tr><td>**User** input</td><td>Host Only</td></tr><tr><td>**Voice File** input</td><td>`welcome_message.wav`</td></tr><tr><td>**Output Voice?** input</td><td>`true`</td></tr><tr><td>**Voice File** output</td><td>`welcome_message.wav`</td></tr></tbody></table>


### [![Response_AiAgent_StartListen.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-aiagent-startlisten.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) AI Agent Start Listen

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/E5cimage.png)

The **AI Agent Start Listen node** is used to make the AI start listening to the user. When activated, this node enables the AI to process and listen to spoken input from the user, allowing for interactive conversations and commands within the VR environment.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/UjYimage.png)

In this example, an AI Doctor is set up in the AI Agents window. This window can be accessed by clicking the Interaction icon in the viewport menu, then select the AI Agents, and then add the AI name with the desired instructions in the Instructions field. A variable is created to store the AI's responses.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/2wtimage.png)

The **AI Agent Start Listen node** is used to make the AI Agent named Doctor start listening to the user when the object named "Start" is triggered. This setup enables the AI to process and listen to user input as soon as the trigger event is activated.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/TdABZrHXY2g" width="560"></iframe>

---

<div class="pointer-container" id="bkmrk-%C2%A0-8"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>### [![Response_AiAgent_StopListen.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-aiagent-stoplisten.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) AI Agent Stop Listen

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/Iwwimage.png)

The **AI Agent Stop Listen node** is used to make the AI stop listening to the user. When activated, this node halts the AI’s ability to process further user input, allowing the AI to respond based on the information gathered up to that point.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/UjYimage.png)

In this example, an AI Doctor is set up in AI Agents window. This window can be accessed by clicking the Interaction icon in the viewport menu, then select the AI Agents, and then add the AI name with the desired instructions in the Instructions field. A variable is created to store the AI's responses.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/3UZimage.png)

The **AI Agent Stop Listen node** is used to stop the AI Agent from listening to the user when the "Stop" trigger event occurs. This allows the AI agent named Doctor to respond based on the input received before listening was stopped.

### [![Response_AiAgent_StopListen.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-aiagent-stoplisten.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) AI Agent Stop Listen (Text)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Gldimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Gldimage.png)

The **AI Agent Stop Listen (Text) node** is used to make the AI stop listening to the user. When activated, this node halts the AI’s ability to process further user input, allowing the AI to respond based on the information gathered up to that point.

This node has an extra output "Spoken Text", when the node is activated, it outputs the input audio in text format.

---

<div class="pointer-container" id="bkmrk-%C2%A0-12"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>### [![Response_Ai_Valid_Key.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/response-ai-valid-key.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Has Valid AI Key

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/2Xximage.png)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--33"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8">  
</div></div></div></div></div>The **Has Valid AI Key** node checks whether a valid AI key is available for AI-related features in Sim Lab Composer. This node ensures that AI functionalities can operate properly by verifying the presence of an active and valid AI key.

#### Example

[![AI has key.JPG](https://simlab-soft.com/help/uploads/images/gallery/2025-03/ai-has-key.JPG)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/lXbimage.png)

In this example, the **Has Valid AI Key** node is used at the start of the scene to check if the user has an activated AI key. The node is connected to a **Branch** node, where the **False** output (indicating no valid AI key) triggers a message in front of the user, informing them that the AI key must be activated.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/YEMeCS8QcFY" width="560"></iframe>

---

### ![Response_AiKey_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2025-07/response-aikey-set.png) Set AI Key

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-07/scaled-1680-/image.png)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--40"><div><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8">  
</div></div></div>The **Set AI Key** node allows you to assign an AI API key to a VR experience directly from the Training Builder. This lets the experience use AI features without requiring the user to manually activate an API key in the viewer. You can select the provider (OpenAI, Gemini, or OpenRouter) and embed the corresponding API key into the experience.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-07/scaled-1680-/VH8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-07/VH8image.png)

In this example, the **Set AI Key** node is connected to a **Scene Start** event to initialize the AI provider as soon as the experience begins. After adding the node and selecting the provider, the API key is pasted into the node’s field. The key is then activated when the scene starts, allowing the AI agent to respond without the user needing their own key. If the embedded key is not active or reaches its usage limit, the experience automatically switches to the user’s API key in the viewer if one is available.

Check this **[tutorial](http://youtube.com/watch?v=qzqNtXBTGY4)** for more about this node.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/qzqNtXBTGY4" width="560"></iframe>

---

### ![Response_AiModel_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2025-07/response-aimodel-set.png) **Set AI Agent Model**

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-07/scaled-1680-/R5Nimage.png)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--47"><div><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8">  
</div></div></div>The **Set AI Agent Model** node is used to assign a specific AI provider and model to an AI agent in your VR experience. This ensures the AI agent will operate using the selected provider and model for any interactions that occur in the scene. You can choose the AI agent you have created, specify the provider (OpenAI, Gemini, or OpenRouter), and define the model name.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-07/scaled-1680-/XCzimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-07/XCzimage.png)

In this example, the **Set AI Agent Model** node is triggered by pressing a button in the VR scene. When the button is clicked, the node assigns the “Patient” AI agent to the OpenAI provider and sets the model to GPT‑4. This setup allows the AI agent to function with the defined provider and model as soon as the event is triggered.

Check this **[tutorial](http://youtube.com/watch?v=qzqNtXBTGY4)** for more about this node.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/qzqNtXBTGY4" width="560"></iframe>

---

###  Using AI Providers and API Keys in SimLab Composer

SimLab Composer now supports **OpenAI, Google Gemini, and OpenRouter** for integrating AI into your VR experiences. With the new **Set AI Key** and **Set AI Agent Model** nodes, you can connect your experience to these providers .

 **Providers and Models:**

**1️⃣ OpenAI**

- **Provider URL:** `https://api.openai.com/v1/chat/completions`
- **Models:**
    
    
    - gpt‑4.1
    - gpt‑4
    - gpt‑3.5‑turbo

**2️⃣ Google Gemini** (OpenAI‑compatible endpoint)

- **Provider URL:** `https://generativelanguage.googleapis.com/v1beta/openai/chat/completions`
- **Models:**
    
    
    - gemini‑2.0‑flash

**3️⃣ OpenRouter**

- **Provider URL:** `https://openrouter.ai/api/v1/chat/completions`
- **Models:**
    
    
    - openrouter/cypher‑alpha:free
    - nvidia/llama‑3.3‑nemotron‑super‑49b‑v1:free
        
        
        - **OpenAI keys** work with **Chat, Text‑to‑Speech, and Speech‑to‑Text**.
        - **Gemini and OpenRouter keys** work with **Text only.**

<div class="mb-2 flex gap-3 empty:hidden -ml-2" id="bkmrk--53"><div class="items-center justify-start rounded-xl p-1 flex"><div class="flex items-center"><div class="flex"><button aria-label="Good response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="good-response-turn-action-button"></button><button aria-label="Bad response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="bad-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button>  
</div><button aria-label="Edit in canvas" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex items-center pb-0"><svg class="icon-md" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg>  
</div><button aria-expanded="false" aria-haspopup="menu" class="cursor-pointer h-[30px] rounded-md px-1 text-token-text-secondary hover:bg-token-main-surface-secondary" data-state="closed" id="bkmrk--58" type="button"></button></div></div></div>

# New Page



# Scene



# Scene

<div id="bkmrk-"></div>### [![Response_Node_Capture_Picture.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-node-capture-picture.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Capture Picture

[![aM3image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/N18am3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/N18am3image.png)

The **Capture Picture node** is used to capture an image from a camera within the scene, and the captured image can then be displayed on a 3D object within the scene. This allows the user to take snapshots and show them in the VR environment, such as displaying a captured image on a screen or other surface.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/5wEimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/Xn9image.png)

A **Surveillance Monitor** is first created to display the captured images. This monitor is then attached to the VR camera.

[![Add_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/cT8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

<div class="pointer-container" id="bkmrk-%C2%A0-0"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>In this example, the **Capture Picture Node** is used to capture an image on a picture frame model when the user triggers the Activate event. Before that, the Cast SceneNode is used to identify the picture frame as a 3D object, as the Capture Picture Node only works with 3D objects.

# New Page



# User \ Controller

# User \\ Transform

<div id="bkmrk-">  
</div>### [![Response_User_TeleportToCamera.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-user-teleporttocamera.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Teleport To Camera

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/utpimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Teleport To Camera** node enables the user to teleport to a new location by assigning a camera in the **CameraNode** field. Once the teleportation is executed, the user is moved to the position and orientation defined by the specified camera.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/A1Fimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/A1Fimage.png)

In this example, a **Teleport To Camera** response is used to move the user to a new location once the object named Activate is triggered. When triggered, the sound named Teleport\_Sound will play, and the user will be teleported to the location of the camera assigned in the Teleport To Camera node.

# Data Types\Number\Operations

---

#### [![Response_Value_Number_Add.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/response-value-number-add.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Add

[![Add_Node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/add-node.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Add** response enables user to add two values by either typing in a numerical value in Number A and Number B field or by attaching a value or a variable node to those ports, then once the response is executed the resulting value can be acquired through the **Result** port.

#### Example

[![Add_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example2.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this Example an **Add Response** is used to add the values of 5 to the value of Variable1 once the user triggers the object named Activate, and the result of the addition is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Value_Number_ceiling.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-ceiling.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Ceiling

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/ceiling-node.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Ceiling** response enables the user to round up a value by either typing in a numerical value in the Number A field or by attaching a value or a variable node to that port. Then once the response is executed, the smallest integral value greater than or equal to the input value can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/vFhimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/vFhimage.png)

In this example, a **Ceiling Response** is used to round up the value of Variable1 to the smallest integral value greater than or equal to it once the user triggers the object named Activate. The result of the ceiling operation is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Value_Number_divide.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-divide.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Divide

[![Divide_node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/divide-node.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Divide** response enables user to divide a value by another value, by either typing in a numerical value in Number A and Number B field or by attaching a value or a variable node to those ports, then once the response is executed the resulting value can be acquired through the **Result** port.

#### Example

[![Divide_Example.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/divide-example.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this Example a **Divide Response** is used to divide the number 25 by the value of the variable named "Variable1" and the result of the division is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Value_Number_Floor.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-floor.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Floor

  
[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/SF2image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Floor** response enables the user to round down a value by either typing in a numerical value in the Number A field or by attaching a value or a variable node to that port. Then once the response is executed, the largest integral value less than or equal to the input value can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/VmLimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/VmLimage.png)

In this example, a **Floor Response** is used to round down the value of Variable1 to the largest integral value less than or equal to it once the user triggers the object named Activate. The result of the floor operation is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

[![Response_Value_Number_modulo.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-modulo.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)<span data-darkreader-inline-color="" style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> Modulo</span>

  
[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/E5Pimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Modulo** response enables the user to find the remainder of a division by either typing in numerical values in the Number A and Number B fields or by attaching values or variable nodes to those ports. Then once the response is executed, the modulus of the input value with respect to the divisor can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/sptimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/sptimage.png)

In this example, a **Modulo Response** is used to calculate the remainder when the value of the variable named Variable1 is divided by the value of Variable2, once the user triggers the object named Activate. The result of the modulo operation is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Value_Number_Multiply.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-multiply.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Multiply

[![Multiply_Node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/multiply-node.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Multiply** response enables user to multiply two values by either typing in a numerical value in Number A and Number B field or by attaching a value or a variable node to those ports, then once the response is executed the resulting value can be acquired through the **Result** port.

#### Example

[![Multiply_Node3.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/multiply-node3.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this Example a **Subtract Response** is used to subtract the value of Variable1 from the value of the Variable2, then a **Multiply Response** is used to multiply the subtraction result by 3 once the user triggers the object named Activate, and the result of the multiplication is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Value_Number_SquareRoot.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-squareroot.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Square Root

  
[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/OdMimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Square Root** response enables the user to calculate the square root of a value by either typing in a numerical value in the Number field or by attaching a value or a variable node to that port. Then once the response is executed, the square root of the input value can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/hUtimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/hUtimage.png)


In this example, a **Square Root** response is used to calculate the square root of the value of Variable1 once the user triggers the object named Activate. The result of the square root operation is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Value_Number_subtract.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-subtract.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Subtract

[![Subtract_Node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/subtract-node.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Subtract** response enables user to subtract a value from another by either typing in a numerical value in Number A and Number B field or by attaching a value or a variable node to those ports, then once the response is executed the resulting value can be acquired through the **Result** port.

#### Example

[![Subtract_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/subtract-example2.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this Example a **Subtract Response** is used to subtract the value of Variable1 from the value of the variable named Variable2, once the user triggers the object named Activate, and the result of the subtraction is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

# Data Types\Number\ Variable

---

## [![SET.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/set.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Set

Has two options:

### [![SET.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/set.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)Set Number Variable By Expression[![Add_Node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Wp1image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Set number variable** response enables user to set a value by either typing in a numerical value in the value field or by attaching a value or a variable node to that port. Then once the response is executed, the variable value can be acquired through the **Value** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Bdhimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/Bdhimage.png)

In this example, a **Set number variable** is used to assign the value of Variable1 once the user triggers the object named Activate, and the new value is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

### [![SET.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/set.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)Set Number Variable By Expression

[![Add_Node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/6gRimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Set number variable by expression** response enables user to set a value by either typing in an expression in the expression field or by attaching a value or a variable node to that port. Then once the response is executed, the variable value can be acquired through the **Value** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/sGSimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/Bdhimage.png)

In this example, a **Set Number Variable By Expression** is used to set the result of the sum of Variable1 and Variable2 once the user triggers the object named Activate. The new value is then written in the Result variable, which can be connected to a variable writer to be displayed during the VR Experience.

---

### [![Response_Variable_NumberDecrement.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-variable-numberdecrement.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Decrement Number Variable

  
[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/UoLimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Decrement Number Variable** response enables the user to decrease a variable's value by 1 each time the event connected to it is triggered. Once the response is executed, the updated value can be acquired through the **Value** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/bbzimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/hUtimage.png)


In this example, a **Decrement Number Variable** response is used to decrease the value of Variable1 by 1 once the user triggers the object named Activate. The result of the decrease number variable operation is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

[![Response_Variable_NumberIncrement.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-variable-numberincrement.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)<span data-darkreader-inline-color="" style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> Increment Number Variable</span>

  
[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/0Eyimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Increment Number Variable** response enables the user to increase a variable's value by 1 each time the event connected to it is triggered. Once the response is executed, the updated value can be acquired through the **Value** port.

#### Example

[![Increment.JPG](https://simlab-soft.com/help/uploads/images/gallery/2025-03/increment.JPG)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/hUtimage.png)


In this example, a **Increment Number Variable** response is used to increase the value of Variable1 by 1 once the user triggers the object named Activate. The result of the decrease number variable operation is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

[![Response_Variable_NumberGet.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-variable-numberget.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)<span data-darkreader-inline-color="" style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> Get </span>

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/FbIimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Number Variable Value** response enables the user to get a variable's value each time the event connected to it is triggered. Once the response is executed, the updated value can be acquired through the **Value** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/o5himage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/o5himage.png)


In this example, a **Number Variable Value** response is used to get the new value for Variable1 after it was changed by **Set Number Variable By Expression** once the user triggers the object named GetValueButton. The value of the number variable is then written in a variable named Result, which can then be connected to a variable writer to be displayed during the VR Experience.

---

# Data Types\Number\ Compare

### [![Responses_DataTypes_Numbers_Compare_Equals.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-datatypes-numbers-compare-equals.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Equal (Number)

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Agnimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

<div class="pointer-container" id="bkmrk-%C2%A0"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>The **Equal (Number)** response enables the user to compare two values by either typing in a numerical value in the Number A and Number B fields or by attaching a value or a variable node to those ports. Then once the response is executed, the result of the comparison can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/S2himage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/S2himage.png)

<div class="pointer-container" id="bkmrk-%C2%A0-1"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>In this example, an **Equal Response** response is used to compare the value of Variable1 with the value of Variable2 once the user triggers the object named Activate. The result of the comparison can be acquired through the **Result** port. We have connected this Result port to the **Branch** node, and if the result of the branch is True, the TrueBox will show; if the result is False, the FalseBox will show.

---

### [![Responses_DataTypes_Numbers_Compare_Greater.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-datatypes-numbers-compare-greater.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Greater (Number)

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/hBOimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

<div class="pointer-container" id="bkmrk-%C2%A0-4"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>The **Greater** response enables the user to compare two values to determine if one is greater than the other by either typing in a numerical value in the Number A and Number B fields or by attaching a value or a variable node to those ports. Then once the response is executed, the result of the comparison can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/gMmimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/gMmimage.png)

<div class="pointer-container" id="bkmrk-%C2%A0-7"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>In this example, a **Greater Response** is used to compare the value of Variable1 with the value of Variable2 once the user triggers the object named Activate. The result of the comparison can be acquired through the Result port. We have connected this Result port to the Branch node, and if the result of the branch is True, the TrueBox will show; if the result is False, the FalseBox will show.

---

### [![Responses_DataTypes_Numbers_Compare_GreaterOrEqual.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-datatypes-numbers-compare-greaterorequal.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Greater Or Equal (Number) 

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/hI8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Greater Or Equal** response enables the user to compare two values to determine if one is greater than or equal to the other by either typing in a numerical value in the Number A and Number B fields or by attaching a value or a variable node to those ports. Then once the response is executed, the result of the comparison can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/dmcimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/dmcimage.png)

In this example, a **Greater Or Equal Response** is used to compare the value of Variable1 with the value of Variable2 once the user triggers the object named Activate. The result of the comparison can be acquired through the Result port. We have connected this Result port to the Branch node, and if the result of the branch is True, the TrueBox will show; if the result is False, the FalseBox will show.

---

### [![Responses_DataTypes_Numbers_Compare_Less.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-datatypes-numbers-compare-less.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Less (Number)

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/ye5image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Less** response enables the user to compare two values to determine if one is less than the other by either typing in a numerical value in the Number A and Number B fields or by attaching a value or a variable node to those ports. Then once the response is executed, the result of the comparison can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/fxoimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/fxoimage.png)

In this example, a **Less** is used to compare the value of Variable1 with the value of Variable2 once the user triggers the object named Activate. The result of the comparison can be acquired through the Result port. We have connected this Result port to the Branch node, and if the result of the branch is True, the TrueBox will show; if the result is False, the FalseBox will show.

---

### [![Responses_DataTypes_Numbers_Compare_LessOrEqual.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-datatypes-numbers-compare-lessorequal.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Less Or Equal (Number)

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/q9simage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Less Or Equal** response enables the user to compare two values to determine if one is less than or equal to the other by either typing in a numerical value in the Number A and Number B fields or by attaching a value or a variable node to those ports. Then once the response is executed, the result of the comparison can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/V5nimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/V5nimage.png)

In this example, a **Less** is used to compare the value of Variable1 with the value of Variable2 once the user triggers the object named Activate. The result of the comparison can be acquired through the Result port. We have connected this Result port to the Branch node, and if the result of the branch is True, the TrueBox will show; if the result is False, the FalseBox will show.

---


### [![Responses_DataTypes_Numbers_Compare_NotEqual.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-datatypes-numbers-compare-notequal.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Not Equal (Number)

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/3bBimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk-%C2%A0-15"><div class="flex-shrink-0 flex flex-col relative items-end"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8"><div class="pointer-container" id="bkmrk-%C2%A0-19"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div></div></div></div></div></div>The **Not Equal** response enables the user to compare two values to determine if they are different by either typing in a numerical value in the Number A and Number B fields or by attaching a value or a variable node to those ports. Then once the response is executed, the result of the comparison can be acquired through the **Result** port.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/SiNimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/SiNimage.png)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk-%C2%A0-16"><div class="flex-shrink-0 flex flex-col relative items-end"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8"><div class="pointer-container" id="bkmrk-%C2%A0-20"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div></div></div></div></div></div>In this example, a **Not Equal** is used to compare the value of Variable1 with the value of Variable2 once the user triggers the object named Activate. The result of the comparison can be acquired through the Result port. We have connected this Result port to the Branch node, and if the result of the branch is True, the TrueBox will show; if the result is False, the FalseBox will show.

---

# Data Types\Number\ Conversion

<div id="bkmrk-" style="clear: left;">  
</div>### [![Response_Value_NumberToString.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-numbertostring.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Number To String  
  


[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Wu3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

  
The **Number to String** node enables the user to convert a numerical value to a string by either typing in a numerical value in the Number field or by attaching a value or a variable node to that port. Then once the conversion is executed, the resulting string can be acquired through the **String** port.


---

### String To Number

Turns a piece of text into a number you can do math with or compare.

#### What it does

This node reads the text you give it and hands back the matching number. For example, the text `“42”` comes back as the number `42`, and `“3.14”` comes back as `3.14`. Negative values like `“-7”` work too. This is handy when a value arrives as text—say from something the user typed—but you need it as a real number for calculations or comparisons.

The conversion only works when the text actually looks like a number. If you pass in something that isn’t a number, such as `“hello”`, you get no number back (an empty result). The original text is never changed—you simply get a new number value. This node is the reverse of the “Number To String” node on the same page.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**String**</td><td style="white-space: nowrap;">Text</td><td>The text you want turned into a number, such as `“42”` or `“3.14”`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Number**</td><td style="white-space: nowrap;">Number</td><td>The number that matches the text. If the text isn’t a number, you get an empty result.</td></tr></tbody></table>

#### Example

<table id="bkmrk-string-input-%E2%80%9C3.14%E2%80%9D-"><tbody><tr><td>**String** input</td><td>`“3.14”`</td></tr><tr><td>**Number** output</td><td>`3.14`</td></tr></tbody></table>

#### Tips

- Make sure the text really is a number. Extra characters like spaces or a currency sign can leave you with an empty result.
- If a value reaches you as text but you need to add, subtract, or compare it, run it through this node first.

# Data Types\Number\ Expression

This node can evaluate an expression, then[![komeeqn57image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/hulkomeeqn57image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/hulkomeeqn57image.png)

the result of this evaluation can be used to activate other responses.

####   


#### Example

In the example below when the "**Import\_UPS**" geometry is clicked "**Evaluate Number Expression**" is executed. The expression is simple math.sqrt(16), and the result is linked to the "**Set Number Variable**" node, in "**result**" variable. This variable is then linked to a "Variable Writer" to display it.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/7ynimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/7ynimage.png)

# Data Types \ Json \ JsonObject

A JSON object is a collection of named fields — for example `{"name": "Sam", "age": 42}`. Each field has a name (sometimes called a *key*) and a value. The nodes on this page let you build objects, set or read fields by name, inspect them, and turn them into plain text you can store, send, or print.

## What's on this page

- **Create** — start a brand-new object, either empty or from a piece of text.
- **Set a field** — add or change a named field on an object (one node per value type).
- **Read a field** — pull the value of a named field back out (one node per value type).
- **Inspect** — list every field's name, or find out what kind of value a field holds.
- **Convert** — turn the whole object into a single piece of text.

**About fields:** field names are case-sensitive — `"Name"` and `"name"` are different. Setting a value on a field that already exists replaces the old value; setting one with a new name adds the field.

---

## Create

### Create Json Object

Makes a fresh, empty JSON object. Use this as the starting point when you want to build a record from scratch.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/39" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

This node produces a brand-new JSON object with nothing in it: `{}`. From there you'd typically wire it into one or more **Set Json Object Field** nodes to fill it with named fields.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output. The node only runs when triggered.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes. Wire it into whatever should run next.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>A new, empty object `{}`.</td></tr></tbody></table>

#### Tips

- **Chain it.** Wire this node's **JsonObject** output into the **JsonObject** input of a **Set Json Object Field** node to add the first field.
- **Or start from text.** If you already have your data as a string like `{"name": "Sam"}`, use **Create Json Object From String** instead.

### Create Json Object From String

Reads a piece of text written in JSON object form and turns it into a real JSON object you can work with.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/51" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Useful when the data arrived as text — for example from a file you read, a message someone sent, or a value pasted into a configuration. The node parses the text and gives you back a proper JSON object that the other JSON nodes can use.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**String**</td><td style="white-space: nowrap;">Text</td><td>The text to parse. It must look like a JSON object — that is, start with `{` and end with `}`, with comma-separated `"name": value` pairs.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**String**</td><td style="white-space: nowrap;">Text</td><td>The same text you passed in (in case the next node needs it as well).</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The parsed object.</td></tr></tbody></table>

#### Example

<table id="bkmrk-string-input-%7B%22name%22"><tbody><tr><td style="white-space: nowrap;">**String** input</td><td>`{"name": "Sam", "age": 42}`</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"name": "Sam", "age": 42}` — now a real JSON object</td></tr></tbody></table>

#### Tips

- **Match the format.** If the text is malformed (a missing brace, unquoted field name, extra comma, etc.) the node won't be able to parse it.
- **Reverse direction.** To go the other way and turn an object *into* text, see **Json Object To String** further down this page.

---

## Set a field

These seven nodes all do the same thing — set a named field on a JSON object — but each one accepts a different kind of value. Pick the one that matches what you're storing.

If the field already exists on the object, its value is replaced. If it doesn't exist, the field is added. The original object isn't modified; what comes out is a new object with the change applied.

### Set Json Object Field (String)

Sets a text field on a JSON object.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/45" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

This node takes a JSON object, a field name, and a piece of text, and gives you back a new object with that field set to the text.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to update. Often comes from a **Create Json Object** node or from a previous step.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set. If the field already exists its value is replaced; if not, it's added.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text to store under that name.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated object with your field set.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The same text you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22n"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"name": "Sam", "age": 42}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"city"`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`"Portland"`</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"name": "Sam", "age": 42, "city": "Portland"}`</td></tr></tbody></table>

### Set Json Object Field (Number)

Sets a numeric field on a JSON object.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/44" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Same as the text version, but the value being stored is a number. Works with whole numbers and decimals; positive or negative.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to update.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number to store under that name.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated object with your field set.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The same number you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22w"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"width": 800, "height": 600}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"depth"`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`24`</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"width": 800, "height": 600, "depth": 24}`</td></tr></tbody></table>

### Set Json Object Field (Boolean)

Sets a true/false field on a JSON object.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/47" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Same idea as the other Set variants, but the value being stored is a true/false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to update.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Boolean (true/false)</td><td>The value to store under that name.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated object with your field set.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Boolean</td><td>The same value you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22n-0"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"name": "Crate", "locked": true}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"visible"`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`false`</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"name": "Crate", "locked": true, "visible": false}`</td></tr></tbody></table>

### Set Json Object Field (JsonObject)

Sets a field whose value is another JSON object.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/42" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Stores a JSON object as the value of a named field — useful for grouping related sub-fields together. The original outer object isn't modified; you get a new object with the nested one attached under your chosen name.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The outer object to update.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>The inner object to store under that name.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated outer object with the inner object nested under your field name.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>The same inner object you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22u"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"user": {"id": 7}}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"config"`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`{"dark": true}`</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"user": {"id": 7}, "config": {"dark": true}}`</td></tr></tbody></table>

### Set Json Object Field (JsonArray)

Sets a field whose value is a JSON array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/41" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Stores a JSON array (a list) as the value of a named field — useful for fields that hold a collection of related items, like tags, scores, or coordinates.

#### Inputs

<table id="bkmrk-port-type-what-to-co-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to update.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON array</td><td>The array to store under that name. See the **JSON Arrays** page for nodes that build one.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated object with the array stored under your field name.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22t"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"title": "Project", "priority": 1}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"tags"`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`["urgent", "review"]`</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"title": "Project", "priority": 1, "tags": ["urgent", "review"]}`</td></tr></tbody></table>

### Set Json Object Field (SceneNode)

Sets a field whose value is a scene node — an object in your SimLab scene like a robot, a part, or a marker.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/43" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Stores a reference to a scene node under a named field. The reference points to the live object — not a copy — so other nodes that read this field later receive the actual scene node.

#### Inputs

<table id="bkmrk-port-type-what-to-co-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to update.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node to reference under that name. Comes from a node like **Get Scene Node** or a previous step that produced one.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated object with the scene node reference attached.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same scene node you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22l"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"label": "Robot Arm", "active": true}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"target"`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>&lt;Robot&gt; — a scene-node reference</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"label": "Robot Arm", "active": true, "target": <Robot>}`</td></tr></tbody></table>

### Set Json Object Field (User)

Sets a field whose value is a User — a participant in a VR/AR session.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/46" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Stores a reference to a User under a named field. The reference points to the live participant; other nodes that read this field later receive the actual User.

#### Inputs

<table id="bkmrk-port-type-what-to-co-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to update.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the field to set.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The User to reference under that name.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The updated object with the User reference attached.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you passed in.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same User you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22p"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"project": "Atlas", "role": "admin"}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"owner"`</td></tr><tr><td style="white-space: nowrap;">**User** input</td><td>&lt;alice&gt; — a User reference</td></tr><tr><td style="white-space: nowrap;">**JsonObject** output</td><td>`{"project": "Atlas", "role": "admin", "owner": <alice>}`</td></tr></tbody></table>

---

## Read a field

These five nodes all pull the value of a single field back out of a JSON object. You pick the field by its name. Each variant returns the value as a specific type — pick the one that matches what you stored.

The object isn't modified — the value is read out, the object stays the same.

### Get Json Object Field (String)

Reads one field from a JSON object as text.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/50" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the value of the field with the given name. Use this when that field's value is a piece of text.

#### Inputs

<table id="bkmrk-port-type-what-to-co-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>Which field to read. Names are case-sensitive.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The value stored under that name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22n-1"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"name": "Sam", "age": 42, "city": "Portland"}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"city"`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`"Portland"`</td></tr></tbody></table>

### Get Json Object Field (Number)

Reads one field from a JSON object as a number.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/52" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the value of the field with the given name. Use this when that field's value is a number.

#### Inputs

<table id="bkmrk-port-type-what-to-co-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>Which field to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number stored under that name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22w-0"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"width": 1920, "height": 1080, "fps": 60}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"height"`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`1080`</td></tr></tbody></table>

### Get Json Object Field (Boolean)

Reads one field from a JSON object as a true/false value.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/38" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the value of the field with the given name. Use this when that field's value is a true/false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>Which field to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Boolean</td><td>The true/false value stored under that name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22v"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"visible": true, "locked": false, "active": true}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"locked"`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`false`</td></tr></tbody></table>

### Get Json Object Field (JsonObject)

Reads one field from a JSON object as another JSON object (a nested object).

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/53" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the value of the field with the given name. Use this when that field's value is itself a JSON object — for example a sub-section like `"config"` or `"user"`. Once you have the nested object, the other Read-a-field nodes can read its individual fields.

#### Inputs

<table id="bkmrk-port-type-what-to-co-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The outer object to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>Which field to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same outer object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>The inner object stored under that name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22u-0"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"user": {"id": 7}, "config": {"dark": true}}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"config"`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`{"dark": true}`</td></tr></tbody></table>

### Get Json Object Field (JsonArray)

Reads one field from a JSON object as a JSON array (a list).

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/48" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the value of the field with the given name. Use this when that field's value is a JSON array.

#### Inputs

<table id="bkmrk-port-type-what-to-co-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>Which field to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON array</td><td>The array stored under that name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22s"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"sizes": [10, 20], "colors": ["red", "blue"]}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"colors"`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`["red", "blue"]`</td></tr></tbody></table>

---

## Inspect

These two nodes don't read a specific field — they tell you *about* the object's structure. Use them when you don't know in advance what fields the object contains, or when you need to find out what type of value a field holds before reading it.

### Get Json Object Names

Gives you the list of field names in the object.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/49" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns each field name in the object, one after another. Handy when you want to step through every field using a loop construct or for-each pattern, or when you don't know what's in the object up front.

#### Inputs

<table id="bkmrk-port-type-what-to-co-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object whose field names you want.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Names**</td><td style="white-space: nowrap;">Text</td><td>Each field name in turn.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22n-2"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"name": "Sam", "age": 42, "city": "Portland"}`</td></tr><tr><td style="white-space: nowrap;">**Names** output</td><td>`"name", "age", "city"`</td></tr></tbody></table>

#### Tips

- **Use with Get.** Pair this with one of the **Get Json Object Field** nodes (or with **Get Json Field Type**) to inspect every field in turn.
- **Empty objects.** If the object has no fields, no names are produced.

### Get Json Field Type

Tells you what kind of value a named field holds.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/40" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the type of the field's value as a short piece of text: `"String"`, `"Number"`, `"Boolean"`, `"JsonObject"`, or `"JsonArray"`. Use this when an object's fields can hold different kinds of values and you need to decide which **Get** node to use.

#### Inputs

<table id="bkmrk-port-type-what-to-co-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object containing the field. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>Which field to check.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you asked for.</td></tr><tr><td style="white-space: nowrap;">**Type**</td><td style="white-space: nowrap;">Text</td><td>The type of the field's value, as a short name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22n-3"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"name": "Sam", "age": 42, "active": true}`</td></tr><tr><td style="white-space: nowrap;">**Name** input</td><td>`"age"`</td></tr><tr><td style="white-space: nowrap;">**Type** output</td><td>`"Number"`</td></tr></tbody></table>

---

## Convert

### Json Object To String

Turns the entire object into a single piece of text.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/54" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Produces a text representation of the whole object, written in JSON form. Useful when you need to save the object to a file, send it to another system, or put it somewhere that only accepts text.

The original object isn't modified — you get the same object back plus a text version.

#### Inputs

<table id="bkmrk-port-type-what-to-co-15"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The object to convert.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-15"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonObject**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text version of the object.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonobject-input-%7B%22n-4"><tbody><tr><td style="white-space: nowrap;">**JsonObject** input</td><td>`{"name": "Alice", "score": 95}`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`'{"name": "Alice", "score": 95}'`</td></tr></tbody></table>

#### Tips

- **Reverse direction.** To go back from text to an object, use **Create Json Object From String** at the top of this page.

---

## Related

- **JSON Arrays** — the matching page for working with ordered lists of items.

# Data Types \ Json \  JsonArray

A JSON array is an ordered list of items — for example `["apple", "cherry", "banana"]`. The nodes on this page let you build arrays, add to them, read items back out, inspect them, and turn them into plain text you can store, send, or print.

## What's on this page

- **Create** — start a brand-new array, either empty or from a piece of text.
- **Add a value** — append an item to the end of an existing array (one node per item type).
- **Read an element** — pull an item back out by its position (one node per item type).
- **Inspect** — find out the size, the valid positions, or the type of an item.
- **Convert** — turn the whole array into a single piece of text.

**About indexes:** positions in a JSON array start at **1**, not 0. The first item is at index 1, the second at index 2, and so on.

---

## Create

### Create Json Array

Makes a fresh, empty JSON array. Use this as the starting point when you want to build a list from scratch.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/36" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

This node produces a brand-new JSON array with nothing in it: `[]`. From there you'd typically wire it into one or more **Add Json Array Value** nodes to fill it with items.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output. The node only runs when triggered.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes. Wire it into whatever should run next.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>A new, empty array `[]`.</td></tr></tbody></table>

#### Tips

- **Chain it.** Wire this node's **JsonArray** output into the **JsonArray** input of an **Add Json Array Value** node to put the first item in.
- **Or start from text.** If you already have your data as a string like `[1, 2, 3]`, use **Create Json Array From String** instead.

### Create Json Array From String

Reads a piece of text written in JSON array form and turns it into a real JSON array you can work with.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/31" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Useful when the data arrived as text — for example from a file you read, a message someone sent, or a value pasted into a configuration. The node parses the text and gives you back a proper JSON array that the other JSON nodes can use.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**String**</td><td style="white-space: nowrap;">Text</td><td>The text to parse. It must look like a JSON array — that is, start with `[` and end with `]`, with items separated by commas.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**String**</td><td style="white-space: nowrap;">Text</td><td>The same text you passed in (in case the next node needs it as well).</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The parsed array.</td></tr></tbody></table>

#### Example

<table id="bkmrk-string-input-%5B1%2C-2%2C-"><tbody><tr><td style="white-space: nowrap;">**String** input</td><td>`[1, 2, 3]`</td></tr><tr><td style="white-space: nowrap;">**JsonArray** output</td><td>`[1, 2, 3]` — now a real JSON array</td></tr></tbody></table>

#### Tips

- **Match the format.** If the text is malformed (a missing bracket, an extra comma, etc.) the node won't be able to parse it.
- **Reverse direction.** To go the other way and turn an array *into* text, see **Json Array To String** further down this page.

## Add a value

These five nodes all do the same thing — add a value to the end of a JSON array — but each one accepts a different kind of value. Pick the one that matches what you're adding.

None of them modify the original array. What comes out is a new array with the extra item on the end.

### Add Json Array Value (String)

Adds a piece of text to the end of a JSON array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/25" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

This node takes a JSON array and a piece of text, and gives you back a new array with the text added on the end.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The list you want to add to. Often comes from a **Create Json Array** node or from a previous step.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The piece of text you want to append.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The updated array with your text added at the end.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The same text you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%22ap"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`["apple", "cherry"]`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`"banana"`</td></tr><tr><td style="white-space: nowrap;">**JsonArray** output</td><td>`["apple", "cherry", "banana"]`</td></tr></tbody></table>

### Add Json Array Value (Number)

Adds a number to the end of a JSON array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/21" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Same as the text version, but for numbers. Works with whole numbers and decimals; positive or negative.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The list you want to add to.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number you want to append.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The updated array with your number added at the end.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The same number you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B20%2C"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[20, -5]`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`3`</td></tr><tr><td style="white-space: nowrap;">**JsonArray** output</td><td>`[20, -5, 3]`</td></tr></tbody></table>

### Add Json Array Value (Boolean)

Adds a true/false value to the end of a JSON array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/35" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Same idea as the other Add variants, but the value being appended is a true/false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The list you want to add to.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Boolean (true/false)</td><td>The value you want to append.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The updated array with the true/false added at the end.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Boolean</td><td>The same value you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5Btru"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[true, false]`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**JsonArray** output</td><td>`[true, false, true]`</td></tr></tbody></table>

### Add Json Array Value (JsonObject)

Adds a JSON object to the end of a JSON array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/19" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Useful for building a list of records — for example a list of scores, settings, or scene items, where each entry has several named fields.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The list you want to add to.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>The object you want to append. See the **JSON Objects** page for nodes that build one.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The updated array with the object added at the end.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>The same object you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%7B%22s"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[{"score": 10}]`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`{"score": 8}`</td></tr><tr><td style="white-space: nowrap;">**JsonArray** output</td><td>`[{"score": 10}, {"score": 8}]`</td></tr></tbody></table>

### Add Json Array Value (JsonArray)

Adds another JSON array as a single entry — producing a nested list.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/33" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

The inner array is added as *one* item. The outer array's size grows by one regardless of how many items are inside the array you're adding. This is how you build grids, rows-of-rows, or any nested structure.

#### Inputs

<table id="bkmrk-port-type-what-to-co-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The outer list you want to add to.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON array</td><td>The array to add as one entry inside the outer one.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The updated outer array with the inner array added at the end.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON array</td><td>The same inner array you passed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%5B7%2C"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[[7, 4]]`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`[9, 2]`</td></tr><tr><td style="white-space: nowrap;">**JsonArray** output</td><td>`[[7, 4], [9, 2]]`</td></tr></tbody></table>

---

## Read an element

These five nodes all pull a single item back out of a JSON array. You pick the item by its position (its **Index**). Each variant returns the value as a specific type — pick the one that matches what you stored.

The array isn't modified — the value is read out, the array stays the same.

### Get Json Array Element (String)

Reads one item from a JSON array as text.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/24" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the item at the position you specify. Use this when the item at that position is a piece of text.

#### Inputs

<table id="bkmrk-port-type-what-to-co-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>Which position to read. The first item is at `1`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>The same position you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The item at that position.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%22ap-0"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`["apple", "banana", "cherry", "avocado"]`</td></tr><tr><td style="white-space: nowrap;">**Index** input</td><td>`3`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`"cherry"`</td></tr></tbody></table>

### Get Json Array Element (Number)

Reads one item from a JSON array as a number.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/22" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the item at the position you specify. Use this when the item at that position is a number.

#### Inputs

<table id="bkmrk-port-type-what-to-co-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>Which position to read. Starts at 1.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>The same position you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number at that position.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B12%2C"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[12, 47, 88, 103, 256, 411]`</td></tr><tr><td style="white-space: nowrap;">**Index** input</td><td>`5`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`256`</td></tr></tbody></table>

### Get Json Array Element (Boolean)

Reads one item from a JSON array as a true/false value.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/30" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the item at the position you specify. Use this when the item at that position is a true/false value.

#### Inputs

<table id="bkmrk-port-type-what-to-co-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>Which position to read. Starts at 1.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>The same position you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Boolean</td><td>The true/false value at that position.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5Btru-0"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[true, false, true, true, false, false, true]`</td></tr><tr><td style="white-space: nowrap;">**Index** input</td><td>`6`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`false`</td></tr></tbody></table>

### Get Json Array Element (JsonObject)

Reads one item from a JSON array as a JSON object.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/20" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the item at the position you specify. Use this when each item in the array is a JSON object (a record with named fields). Once you have the object, the nodes on the **JSON Objects** page can read individual fields.

#### Inputs

<table id="bkmrk-port-type-what-to-co-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>Which position to read. Starts at 1.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>The same position you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>The object at that position.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%7B%22i"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[{"id": 101}, {"id": 102}, {"id": 103}, {"id": 104}, {"id": 105}]`</td></tr><tr><td style="white-space: nowrap;">**Index** input</td><td>`4`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`{"id": 104}`</td></tr></tbody></table>

### Get Json Array Element (JsonArray)

Reads one item from a JSON array as another JSON array (a nested array).

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/34" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the item at the position you specify. Use this when each item in the outer array is itself an array — for example a grid or a list of points.

#### Inputs

<table id="bkmrk-port-type-what-to-co-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The outer array to read from. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>Which position to read. Starts at 1.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same outer array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>The same position you asked for.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON array</td><td>The inner array at that position.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%5B10"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[[10, 20], [30, 40], [50, 60], [70, 80], [90, 100]]`</td></tr><tr><td style="white-space: nowrap;">**Index** input</td><td>`4`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`[70, 80]`</td></tr></tbody></table>

---

## Inspect

These three nodes don't read items out of the array — they tell you *about* it. Use them when you need to know how big the array is, what positions are valid, or what kind of item is at a given position.

### Get Json Array Size

Tells you how many items are in the array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/23" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the total number of items as a number. An empty array returns `0`.

#### Inputs

<table id="bkmrk-port-type-what-to-co-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array to measure.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Size**</td><td style="white-space: nowrap;">Number</td><td>How many items the array contains.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%22re"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`["red", "green", "blue"]`</td></tr><tr><td style="white-space: nowrap;">**Size** output</td><td>`3`</td></tr></tbody></table>

### Get Json Array Indices

Gives you the list of valid positions in the array.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/37" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns each valid index in the array, one after another — `1, 2, 3, …` up to the array's size. Handy when you want to step through every item using a loop construct or for-each pattern.

#### Inputs

<table id="bkmrk-port-type-what-to-co-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array whose positions you want.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Indices**</td><td style="white-space: nowrap;">Integer</td><td>Each valid position in turn (`1`, then `2`, then `3`, …).</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%22re-0"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`["red", "green", "blue"]`</td></tr><tr><td style="white-space: nowrap;">**Indices** output</td><td>`1, 2, 3`</td></tr></tbody></table>

#### Tips

- **Use with Get.** Pair this with one of the **Get Json Array Element** nodes to read every item in turn.
- **Empty arrays.** If the array is empty, no indices are produced.

### Get Json Array Element Type

Tells you what kind of item is stored at a given position.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/26" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Returns the type of the item at the position you specify, as a short piece of text: `"String"`, `"Number"`, `"Boolean"`, `"JsonObject"`, or `"JsonArray"`. Use this when an array can hold different kinds of items and you need to decide which **Get** node to use.

#### Inputs

<table id="bkmrk-port-type-what-to-co-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array containing the item. Must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>Which position to check. Starts at 1.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Index**</td><td style="white-space: nowrap;">Integer</td><td>The same position you asked for.</td></tr><tr><td style="white-space: nowrap;">**Type**</td><td style="white-space: nowrap;">Text</td><td>The type of the item at that position, as a short name.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B3.1"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`[3.14, 2.71, 1.41, 1.62, 0.57, 6.28]`</td></tr><tr><td style="white-space: nowrap;">**Index** input</td><td>`5`</td></tr><tr><td style="white-space: nowrap;">**Type** output</td><td>`"Number"`</td></tr></tbody></table>

---

## Convert

### Json Array To String

Turns the entire array into a single piece of text.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/27" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Produces a text representation of the whole array, written in JSON form. Useful when you need to save the array to a file, send it to another system, or put it somewhere that only accepts text.

The original array isn't modified — you get the same array back plus a text version.

#### Inputs

<table id="bkmrk-port-type-what-to-co-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The array to convert.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**JsonArray**</td><td style="white-space: nowrap;">JSON array</td><td>The same array you passed in.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text version of the array.</td></tr></tbody></table>

#### Example

<table id="bkmrk-jsonarray-input-%5B%22re-1"><tbody><tr><td style="white-space: nowrap;">**JsonArray** input</td><td>`["red", "green", "blue"]`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`'["red", "green", "blue"]'`</td></tr></tbody></table>

#### Tips

- **Reverse direction.** To go back from text to an array, use **Create Json Array From String** at the top of this page.

---

## Related

- **JSON Objects** — the matching page for working with records that have named fields.

# Data Types \ String \ Operations

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/qObimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/qObimage.png) Add String 

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/LKmimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/LKmimage.png)

This node can be used to add two strings to each other.

In the below example a **Score** string variable is input to this node, along with **My Score is** string filled in. The result is input to a Set String Variable node, into another string variable name **MyScore** which is linked to a Variable Writer in the scene to be displayed.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/EsXimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/EsXimage.png)

---

### [![Response_Value_Number_Add.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/response-value-number-add.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Find

[![Add_Node.jpg](https://simlab-soft.com/help/uploads/images/gallery/2025-04/scaled-1680-/5iZimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The "**Find**" node is used to search for a specific word, group of letters, or substring within a larger sentence or string value. If the specified text is found, the node returns the number of characters from the beginning of the string to the start of the found text. If the specified text is not found, the node returns -1. This allows users to detect and locate specific content inside a string.

#### Example

[![Add_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2025-04/scaled-1680-/852image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this example, the **Find node** is used to search for the word "apple" in a string variable with the initial value "I like apple pie." When the user triggers the object, the Variable with Initial node retrieves the string, and the Find node looks for the word "apple." The resulting index is then stored in a number variable named "Value" using the Set Number Variable node, which can then be connected to a Variable Writer to display the result during the VR experience. If "apple" is found, the Value variable stores the position where "apple" starts in the sentence. If not found, the Value variable is set to -1.

---

### [![Response_Value_String_LowerCase.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/response-value-string-lowercase.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/response-value-string-lowercase.png)Lower Case

The "**Lower Case**" can be used to ![EI7image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/ei7image.png)covert an upper case string to lower case, as shown in the example below.

In this example the string "SIMLAB SOFT" is input inside this node, which is executed when **Activate** scene node is triggered. This will result in updating the valued of LowerCaseName string variable to be simlab soft.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/iz7image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/iz7image.png)

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/pIoimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/pIoimage.png)Replace

**Replace** node can be used to replace specific **Target[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/2yoimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/2yoimage.png)** text string from a **Source** text string with the **Replacement** string.

In the below example the node is executed upon clicking **Activate** node, and has three string inputs. Source which is main string "Hello Name". Target string which is "Name", and Replacement string which is Samia.

The Result greeting from this will be "Hello Samia".

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/QeXimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/QeXimage.png)

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/BDvimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/BDvimage.png)String Length 

This node returns the length of a given string.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/F4simage.png)

In the example below the node is triggered by

clicking **Activate** geometry, and it's filled with a long paragraph string. The length result is stored in variable **Result** in the **Set Number Variable** node.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/1rQimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/1rQimage.png)


---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/SKCimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/SKCimage.png)[ ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/BDvimage.png)Upper Case

Contrary to the "**Lower Case**" node this node coverts a loser case string to upper case, as shown in the example below.[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/8F5image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/8F5image.png)

In this example the string "simlab soft" is input inside this node, which is executed when **Activate** scene node is triggered. This will result in updating the valued of UpperCaseName string variable to be SIMLAB SOFT.

####   


#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/t3Wimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/t3Wimage.png)

# Data Types \ String \ Compare

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/SM6image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/SM6image.png) Equal (String) 

A compare node that takes two input strings and compares them if equal or not. [![jxPimage.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/jxpimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/jxpimage.png)

####   


####   


####   


#### Example

In the example below, two not equal strings has been input to this node, thus the output result would be false. The output is used as an input to Show/Hide node for a sphere, that won't be shown in this case.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/asNimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/asNimage.png)


---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/ycFimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/ycFimage.png)Not Equal

Contrary to the previous node this one compares

two input strings for not being equal.[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/uhbimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/uhbimage.png)

#### Example

In the example below, two equal strings has been input to this node, thus the output result would be false. The output is used as an input to Show/Hide node for a sphere. In this case the sphere will be shown.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Renimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Renimage.png)

# Data Types \ String \ Variable

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/xa2image.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/xa2image.png)Set

With this string variable node a user can set a string variable by Value or Expression.

#### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/N7himage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/N7himage.png)Set String Variable

Using this node a string variable is set by value, as shown in the example below. The **Greeting** variable is set using string input node with "**Good day sir!**"

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/berimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/berimage.png)

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/993image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/993image.png)


#### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/U5mimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/U5mimage.png)Set String Variable By Expression 

Using this node a string variable is set by expression, as shown in the example below. The **Name** variable is set using an expression input node with string.lower() expression.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/vizimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/vizimage.png)

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/ihsimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/ihsimage.png)


---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/WWvimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/WWvimage.png)Get 

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Ro1image.png)This node is used to get a string variable value. As shown in the example below, the string variable **Greeting** is gotten as input to this node.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Ljeimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Ljeimage.png)

# Data Types \ String \ Expression

---

### ![Response_Expression_String.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-expression-string.png) Evaluate String Expression

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/ncjimage.png)The **Evaluate String Expression** response enables the system to implement an expression in Lua language. Supported expressions can be found at this **[link](https://devdocs.io/lua~5.4/)**. Once the response is executed, the expression result can be acquired through the Result port.

####   


#### Example

In this example, an **Evaluate String Expression** response enables the system to execute a Lua expression. Once the response is executed, the result of the expression can be retrieved through the **Result** port and can be displayed using a variable writer during the VR Experience.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/rykimage.png)


---

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--4"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8"><svg class="icon-md" fill="none" height="41" role="img" viewbox="0 0 41 41" width="41" xmlns="http://www.w3.org/2000/svg"></svg>  
</div></div></div></div></div>

# Data Types \Color

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/uF3image.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/uF3image.png)Color To RGB 

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Zjrimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Zjrimage.png)


This node converts colors to their RGB components. After that changes can be done to these components.

#### Example

In the below example "**Node Triggered**" node is linked to "**First\_drawer**" geometry that when clicked the "**Get Material Color**" node gets "**Drill\_material**". In "**Color To RGB**" node the color of this material is converted to its RGB components, and then a value of "**1**" is added to its Green component. The RGB components are converted back to color using "**RGB To Color**" node, and the material color is set in the "**Set Material Color**" node.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/nLvimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/nLvimage.png)

Below is the effect of changing material color components.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/QiVimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/QiVimage.png)[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/GpFimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/GpFimage.png)

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Jxoimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Jxoimage.png)RGB To Color 

As in the above example, "**RGB To Color**" converts

RGB components back to color.[![MXfimage.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/mxfimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/mxfimage.png)

# Data Types\Boolean\ Expression

---

This node can be used to generate values (true or false) that can

trigger events throughout the interactive experience.[![WIEimage.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/wieimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/wieimage.png)

#### Example

In the example below when "**3DGeom-7**" is clicked, the expression in "**Evaluate Boolean Expression**" node is checked to execute the node after or not. In this case the expression is simple "**==**" which is true, so the "**3DGeom-7**" geometry will be set to Grabbable.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/GCtimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/GCtimage.png)

# Data Types\Time

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/93yimage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/93yimage.png)Time Interval 

This node calculates the time difference between[![RR5image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Gakrr5image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Gakrr5image.png)

"**Start**", and "**End**" times. It stores the result in

an integer "**Interval**" out put.

###   


---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/ZqZimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/ZqZimage.png)Update Time Variable

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/FvKimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/FvKimage.png)

This node can be used to store time variables.

#### Example

The example below demonstrates the use of both time nodes above. In it the value of "**inisial\_time**" variable is updated upon Scene Start. Then when "**Box**" geometry is clicked the value of "**current\_time**" variable is updated. Then the "**Time Interval**" node is executed, where "**result**" variable is calculated as difference between both times.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/xvWimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/xvWimage.png)

In the experience the "**result**" variable is connected to[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/NxPimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/NxPimage.png)

a Variable writer to display its value.

# Scene State

---

### Apply SceneState 

This node can be used to apply a scene state when an[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/YOwimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/YOwimage.png)

action is done in the 3D area.

#### Example

In the below example when "**Body\_9**" is clicked the "**BlueColor\_pump**" scene state is applied.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/CPiimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/CPiimage.png)

---

### Find SceneState By Name

In complicated scenes with large number of scene [![Lgmimage.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/lgmimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/lgmimage.png)

states, this node can come in handy. The user can use

this node to search for a scene state and then apply

it or do any action with it.

#### Example

In the example below this node is used to search for "GreenColor\_pump" and then applied the scene state.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/548image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/548image.png)

# Sequence

---

### Attach Sequence To

[Creating sequences](https://simlab-soft.com/help/books/simlab-composer-help/page/sequence-timeline) can be done from animating an object in the scene. This sequence can be attached to Hand or an Object in VR.

#### Hand

With sequences available in the Sequences Library, a sequence can be attached to the Hand in VR experience using this node in Dynamic Training Builder.

#### Example

Check this [tutorial ](https://www.youtube.com/watch?v=YkPAQTO5GKE)for the example below, where Boolean expressions were created and upon checking the Boolean Expression a sequence is attached to Hand.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/EtGimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/EtGimage.png)

#### Object

This node can be used to connect a controller grabbable object to a sequence in VR.

#### Example

In the example below the "Switch" sequence is attached to "Handle" object, when Controller "Gloves" geometry moves it. In this example a simple grabbable sequence can do the job, but this is just to demonstrate use of this node.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/HOwimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/HOwimage.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Y4ximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Y4ximage.png)

#### Example 2

In this example we have a path for a box to walk along being controlled by a magnet.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/5Cnimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/5Cnimage.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/095image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/095image.png)

---

### Detach Sequence

Releases a sequence that was attached to a scene object, so it is no longer linked to that object.

#### What it does

If you previously attached a sequence to an object in your scene, this node breaks that link. After it runs, the sequence stands on its own again and no longer follows the object it was attached to.

The sequence itself is not deleted or changed — only the attachment is removed. The same sequence comes back out of the node, so you can keep using it in the steps that follow.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Sequence**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence you want to detach — the one that is currently attached to a scene object.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Sequence**</td><td style="white-space: nowrap;">Sequence</td><td>The same sequence, now detached — ready to use in the next steps.</td></tr></tbody></table>

#### Example

<table id="bkmrk-sequence-input-the-o"><tbody><tr><td>**Sequence** input</td><td>The `Open Door` sequence that was attached to the door handle</td></tr><tr><td>**Sequence** output</td><td>The same `Open Door` sequence, no longer linked to the handle</td></tr></tbody></table>

#### Tips

- Use this to undo an earlier “Attach Sequence To” step when you no longer want the sequence to stay tied to that object.

---

### Playback Controls

Used to control sequence behavior.

#### Continue

##### Same Direction

The selected sequence will continue[![J0Simage.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/GDxj0simage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/GDxj0simage.png)

to play in the same direction.

##### Set Direction

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/Niaimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/Niaimage.png)With this node the user can change the selected sequence direction, by selecting Reverse to True.

##### Example

In the below example a number of the above Playback Controls are used. Here on "**Scene Start**","**Play Sequence**" response is executed for "Elevator\_Up" sequence. Followed by a 1 second "**Delay**", then "**Stop Sequence**" for another one second "**Delay**". Then the sequence is continued, followed by another "**Delay**" then "**Resume Animation Sequence**" from start.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/iEZimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/iEZimage.png)

#### Play

##### Play Sequence/Play Sequence From Start

Both controls will play animation sequence, one from current position, and the other -as the name implies- will play it from start.

#### Reverse

##### Reverse

Reverse sequences starts the animation sequence in the reverse mode (from the last frame). The reverse control will start from the last frame not from the current (because it reverses the overall animation)

In the below example the "Elevator\_Up" sequence upon clicking "Elevator\_panel(2)" geometry will be played from start. So if the elevator at that time was at the top position, it would go down then -as the sequence implies- would go up, then wait for 5 seconds, then "Reverse Sequence" that is go down from last frame.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/TSAimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/TSAimage.png)

####   


####   


####   


####   


##### Reverse From End


This control will start the sequence from the end, even if it hasn’t been played yet.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/QSBimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/QSBimage.png)

#### Flip

Flip sequences flips current animation (that is, forward animation will be backward , backward animation will be forward). Think about it like we are opening a door and we pause the animation in the middle, flip control will return the door back from the current frame to original start position.

#### Stop

Stopes the animation sequence, as shown in examples presented in this section.


---

### Playback Properties

#### Current Frame

##### Get Sequence Current Frame

This node will get the value of the current sequence frame, the user can then use this value in any operation. In the example below the value of the current sequence frame is stored in "Current\_Frame" variable, which is set to the "VR Variable Writer" in the scene to display its value.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/0ESimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/0ESimage.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/eqmimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/eqmimage.png)

#####   


##### Set Sequence Current Frame

If the user wants to go to a specific frame in the sequence this is the function to use. In the below example upon clicking node the sequence current frame is set to 10.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/8l6image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/8l6image.png)

To show the result we got the valued of the current frame and assign it to "Current\_Frame" variable that is displayed in the variable writer as shown below.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/PSnimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/PSnimage.png)

#### Full Range

This node can be used to calculate the full range of a sequence.

##### Get End

Gets and outputs the end frame of the selected [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/tddimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/tddimage.png)

sequence, when triggered.

#####   


##### Get Start


Gets and outputs the start frame of the selected [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/b3timage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/b3timage.png)

sequence, when triggered.

#### Looping

Sequences can be set to loop after finishing.

##### Get Sequence Looping

This node will get the looping status of the input[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/2m2image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/2m2image.png)

sequence, whether true or false.

#####   


##### Set Sequence Looping

This node will set the looping status for the input [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/ElPimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/ElPimage.png)

sequence to either true or false.

#### Play Range

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/LKqimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/LKqimage.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/hK7image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/hK7image.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/dyeimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/dyeimage.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-10/scaled-1680-/TQximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-10/TQximage.png)

#### Play Rate (Speed)

#### Swing

#### Is Playing

#### Is Reversing

---

### Find By Name

# User

### ![Response_User_MouseCursor_Show.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-user-mousecursor-show.png) Show Mouse Cursor

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/GhKimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/GhKimage.png)

The **Show Mouse Cursor node** explicitly controls the visibility and functionality of the user's mouse pointer within the VR Viewer. When activated, the node checks the boolean Enable input for the specified User. Setting it to True displays the cursor on-screen, allowing the user to freely move it and click to interact with objects utilizing **Node Triggered** events. It is important to note that while this cursor mode is active, standard navigation is suspended—the user cannot walk or rotate their camera view until the node is activated again with the Enable input set to False, which hides the cursor and restores normal movement.  
  
The **Show Mouse Cursor** mode is used for desktop/PC version of VR Viewer

<div dir="auto" id="bkmrk--0"><div dir="auto">---

</div></div>### Enable Gamepad Navigation

Turns gamepad navigation on or off for a user, so they can move through the scene with a game controller.

#### What it does

When you switch this on, the chosen user can use a connected gamepad to navigate the scene. Switch it off and gamepad navigation is turned off again for that user. You decide whether this applies just to the host or to everyone in the session.

The node only changes the gamepad setting for the user you pick — it doesn’t affect anything else about the scene. It also passes the same user and the on/off value straight through, so you can carry on with more steps right after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Choose which participant this applies to: **Host Only** or **All Users**. You can also wire in a specific user from an earlier node.</td></tr><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Set this to true to turn gamepad navigation on, or false to turn it off.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user, passed along so you can chain more user steps after this one.</td></tr><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>The same on/off value you set, passed along for any later steps that need it.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-all-users"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`All Users`</td></tr><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The same user, ready for the next step</td></tr><tr><td style="white-space: nowrap;">**Enable** output</td><td>`true`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-use-the-same-node-wi"><div dir="auto">- Use the same node with **Enable** set to false later in your scene to turn gamepad navigation back off when it’s no longer needed.

---

</div></div>### Start QR Detection

Turns on QR code scanning for a participant so the scene can react when they point their view or device at a QR code.

#### What it does

When this node fires, the chosen participant starts looking for QR codes. From that moment on, whenever they aim at a QR code it can be picked up and used elsewhere in your scene. You can also choose whether an on-screen scanning panel appears to guide them, or whether detection happens quietly in the background.

This only switches scanning on — it doesn’t change the participant or the scene in any other way. The same participant is passed straight back out so you can connect more participant-related nodes after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Choose who starts scanning: **Host Only** (just the main user) or **All Users** (everyone in the session). You can also wire in a participant from an earlier node.</td></tr><tr><td style="white-space: nowrap;">**Show UI?**</td><td style="white-space: nowrap;">True / false</td><td>Set to `true` to show the on-screen scanning panel that guides the participant, or `false` to scan quietly in the background. Defaults to `true`.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same participant you chose, passed along so you can connect more participant nodes after this one.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-host-only"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`Host Only`</td></tr><tr><td style="white-space: nowrap;">**Show UI?** input</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The same participant, ready to pass on to the next node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-set-show-ui%3F-to-fals"><div dir="auto">- Set **Show UI?** to `false` when you want scanning to feel seamless — for example, automatically recognizing a code the participant walks up to without a panel popping up.
- This node only starts scanning. Use a matching stop node when you want the participant to stop looking for QR codes.

---

</div></div>### Stop QR Detection

Turns off QR code scanning for a participant, so the app stops looking for QR codes through their headset or device camera.

#### What it does

When you start QR detection, the chosen participant’s view keeps watching for QR codes in the real world around them. This node switches that watching back off. Once it runs, the app no longer scans for QR codes for that person, which is handy after they’ve scanned the code you needed, or when a part of your scene that relied on scanning is finished.

You pick who it applies to with the **User** input — just the host, or everyone. It only stops the scanning; it doesn’t undo anything that was already detected, and it has no effect if scanning wasn’t running for that participant. The same participant is passed straight through the **User** output, so you can carry on with more steps for that person.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Choose who this applies to: **Host Only** (the default) or **All Users**. You can also wire in a participant passed along from an earlier user node.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished, so you can continue to the next step.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same participant you chose, passed along so you can chain more user nodes after this one.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-host-only-0"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`Host Only`</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The same participant, ready for the next user node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-pair-this-with-start"><div dir="auto">- Pair this with **Start QR Detection**: switch scanning on when you need a code read, then switch it off here once you’re done.
- Make sure the **User** choice matches the one you used to start scanning — if you started it for **All Users**, stop it for **All Users** too.

---

</div></div>### Show User Search Menu

Opens the user search menu on screen so a participant can look up and find other people in the session.

#### What it does

When this node runs, it brings up SimLab’s built-in user search menu for the participant you choose. From that menu the participant can search through the people in the session — handy in multi-user scenes where someone needs to locate a specific teammate.

You decide who sees the menu with the User input: either just the Host (`Host Only`) or everyone in the session (`All Users`). The node only opens the menu — it doesn’t change anything about the participant, and it passes that same user along on its output so you can connect more user-related nodes after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-2"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to open the menu.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Chooses who the search menu opens for. Pick `Host Only` to show it just to the host, or `All Users` to show it to everyone in the session.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-2"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the menu has been opened, so you can continue to the next node.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Passes the same user along, so you can chain more user nodes after this one.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-all-users-0"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`All Users`</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The same participant, ready to pass to the next user node.</td></tr></tbody></table>

</div>

# User \ Controller

<div dir="auto" id="bkmrk-"><div dir="auto"><div style="clear: left;"></div></div></div>### [![Response_Node_AttachToHand.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-node-attachtohand.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Attach To Hand

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Fq2image.png)

The **Attach to Hand** node enables the user to attach objects to specific parts of the hand in a VR environment by selecting the desired hand part. This node allows for precise placement of objects, such as tools or items, enhancing interactivity within the VR Experience. Once the attachment is configured, the object will remain in the chosen part of the hand during interactions.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Hp1image.png)

In this example, an **Attach to Hand node** is used to attach a syringe to the index finger once the "Hand Enter Node" event is triggered. The syringe is attached to the specified part of the hand automatically when the event occurs, enabling interaction with the object in the VR environment.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/b1KMBtWP8EQ" width="560"></iframe>

<div dir="auto" id="bkmrk--3"><div dir="auto">---

</div></div>### [![Response_Node_DetachFromHand.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-detachfromhand.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/response-node-detachfromhand.png) Detach From Hand 

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/scLimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scLimage.png)

The **Detach From Hand** , detaches an object currently attached by the [Attach To Hand ](https://simlab-soft.com/help/link/369#bkmrk-number-variable-valu)response, so the object no more moves with the hand

<div dir="auto" id="bkmrk--6"><div dir="auto">---

</div></div>### [![Response_User_SetShowBeam.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-user-setshowbeam.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Trigger Beam<span style="color: rgb(34, 34, 34); font-size: 2.333em; font-weight: 400;"> </span>  


![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/rWQimage.png)

The **Trigger Beam node** enables the user to control the visibility of a beam coming out of the controller in the VR Experience, once the node is executed.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/woWimage.png)

In this example, a **Trigger Beam node** is used to hide the beam coming out of the controller once the object named Activate is triggered. When the event is triggered, the change is reflected during the VR Experience.

<div dir="auto" id="bkmrk--13"><div dir="auto">---

</div></div><div dir="auto" id="bkmrk--15"><div dir="auto">---

</div></div>### Enable Controller Vibration

Makes a participant’s VR controller buzz, so you can give them a physical nudge of feedback during a scene.

#### What it does

When this node runs, the chosen user’s controller vibrates in their hand. You pick which hand buzzes, how strong the buzz feels, how fast it pulses, and how long it lasts. This is great for confirming an action, drawing attention to something, or signalling a mistake.

It only triggers a buzz — it doesn’t change anything about the user or the scene. The same user is passed straight back out, so you can keep chaining more user nodes after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Choose who feels the buzz. Pick `Host Only` to vibrate just the host’s controller, or `All Users` to vibrate everyone’s. You can also connect a User coming from an earlier node.</td></tr><tr><td style="white-space: nowrap;">**Hand**</td><td style="white-space: nowrap;">Choice</td><td>Which controller buzzes: `Right`, `Left`, or `Both`. Choosing `Both` vibrates both controllers at once.</td></tr><tr><td style="white-space: nowrap;">**Strength**</td><td style="white-space: nowrap;">Choice</td><td>How intense the buzz feels: `High`, `Medium`, or `Low`.</td></tr><tr><td style="white-space: nowrap;">**Frequency**</td><td style="white-space: nowrap;">Choice</td><td>How fast the buzz pulses: `High`, `Medium`, or `Low`.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How long the buzz lasts, in seconds (0 or more). For example, `1` is a one-second buzz.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you chose, passed along so you can connect more user nodes after this one.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-host-only"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`Host Only`</td></tr><tr><td style="white-space: nowrap;">**Hand** input</td><td>`Right`</td></tr><tr><td style="white-space: nowrap;">**Strength** input</td><td>`High`</td></tr><tr><td style="white-space: nowrap;">**Frequency** input</td><td>`Medium`</td></tr><tr><td style="white-space: nowrap;">**Duration** input</td><td>`1` (a one-second buzz)</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The host, ready to pass on to the next node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-use-a-short%2C-strong-"><div dir="auto">- Use a short, strong buzz to confirm a correct action, and a longer or gentler one to warn of a mistake.
- Pick `Both` for the Hand when you want a buzz the participant can’t miss.

---

</div></div>### Disable Controller Vibration

Turns off the buzzing (haptic feedback) in a participant’s VR controller.

#### What it does

This node stops the vibration in the chosen hand’s controller for the user you pick. Use it to silence the controller after a buzz, or to make sure a controller stays quiet during a particular part of your scene.

You choose which participant it affects (the host only, or everyone) and which hand to quiet down — the right controller, the left controller, or both. It only controls the vibration; it doesn’t change anything else about the controller or the user, and the same user is passed straight back out so you can connect more user nodes after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to run the node.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Chooses which participant to act on. Pick **Host Only** to quiet just the main user’s controller, or **All Users** to quiet everyone’s.</td></tr><tr><td style="white-space: nowrap;">**Hand**</td><td style="white-space: nowrap;">Choice</td><td>Which controller to turn off the vibration on: **Right**, **Left**, or **Both**.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the vibration has been turned off, so you can continue to the next node.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you chose, passed along so you can chain more user nodes after this one.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-host-only-0"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`Host Only`</td></tr><tr><td style="white-space: nowrap;">**Hand** input</td><td>`Both`</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The same host user, ready to connect to the next node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-pair-this-with-the-e">- Pair this with the **Enable Controller Vibration** node: turn the buzzing on for a moment of feedback, then use this node to switch it back off.
- Choose **Both** when you want both controllers to stop at the same time, rather than adding two separate nodes for the left and right hands.

</div>

# User \ Transform

### ![Response_User_Rotation_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-user-rotation-get.png) Get User Rotation

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/95simage.png)

The **Get User Rotation** response enables the user to get the values of the User's head rotation, and allows them to store the values of the **Pitch**, **Yaw** and **Roll** and the results can be acquired through their output ports.

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk-"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8"><svg class="icon-md" fill="none" height="41" role="img" viewbox="0 0 41 41" width="41" xmlns="http://www.w3.org/2000/svg"></svg>  
</div></div>####   


####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/Hmgimage.png)


In this example, a **Get User Rotation** response is used to check the head rotation angles (Pitch, Yaw and Roll). Once the object named Activate is triggered, the head rotation values (Pitch, Yaw, Roll) of the user with attribute InBuilding and Value Yes are calculated and stored in the variables named Pitch, Yaw, Roll, in order to use them in the VR Experience.

---

### Get User Location

Finds out where a user is currently standing in your scene and gives you their position as three numbers.

#### What it does

This node reads a user’s current position in the scene and hands back the three coordinates that describe it: `X`, `Y`, and `Z`, measured in meters. You can use these numbers to check where someone is, compare it to another spot, or feed it into other nodes.

It only reads the position — it does not move the user or change anything about them. The user stays exactly where they are.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user whose position you want to read. A dropdown lets you choose **Host Only** (the default — the main user) or **All Users**, which reads the position of everyone in a shared collaboration session.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you put in, passed straight through so you can chain it into more user nodes.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The user’s position along the X axis, in meters.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The user’s position along the Y axis, in meters.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The user’s position along the Z axis, in meters.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-host-only"><tbody><tr><td>**User** input</td><td>`Host Only`</td></tr><tr><td>**X** output</td><td>`2.5`</td></tr><tr><td>**Y** output</td><td>`1.7`</td></tr><tr><td>**Z** output</td><td>`-4.0`</td></tr></tbody></table>

#### Tips

- Pair this with **Get User Rotation** when you need both where the user is standing and which way they are facing.
- Choose **All Users** only in a shared collaboration session; for a single-user scene, **Host Only** is what you want.

---

### [![Response_User_TeleportToCamera.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-user-teleporttocamera.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Teleport To Camera

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/utpimage.png)

The **Teleport To Camera** node enables the user to teleport to a new location by assigning a camera in the **CameraNode** field. Once the teleportation is executed, the user is moved to the position and orientation defined by the specified camera, the user can also decide whether this teleportation affect the host only or all the user in the experience (in case of collaboration).

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/A1Fimage.png)

In this example, a **Teleport To Camera** response is used to move the user to a new location once the object named Activate is triggered. When triggered, the sound named Teleport\_Sound will play, and the user will be teleported to the location of the camera assigned in the Teleport To Camera node.

> [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1272491882890399814/1272491882890399814 "Tutorial is available on SimLab VR Discord server")

---

### [![Response_User_TeleportToCamera.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/response-attachuser.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Attach User

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/Y9cimage.png)

The **Attach User** node allows users to attach the user to specific objects within the VR Experience. This node ensures that the user moves along with the object, providing an immersive experience where the user is fixed to the selected object throughout the VR environment, this can be decided to affect only the host or all user (in case of collaboration).

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/0dDimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-01/0dDimage.png)

In this example, the **Attach User** node is used to attach the user to a roller coaster at the start of the scene. When the scene starts, the user will be fixed to the roller coaster, moving along with it as it travels through the environment, providing an immersive experience.

> [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1298557994208071701/1328733596726333451 "Tutorial is available on SimLab VR Discord server")

---

### [![Response_User_TeleportToCamera.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/Fphresponse-user-detach.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Detach User

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/1jBimage.png)

The **Detach User** node allows users to detach from an object within the VR Experience. This node provides a straightforward way to release the user from an object they were attached to, ensuring they regain control of their own movement and are no longer fixed to the selected object or location.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/Fw9image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-01/Fw9image.png)

In this example, the **Detach User** node is used to detach the user from a roller coaster when the roller coaster's animation ends. Once the animation is complete, the user will be released from the roller coaster.

> [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1298557994208071701/1328733596726333451 "Tutorial is available on SimLab VR Discord server")

# User \  Gadget

### [![Response_Gadget_EquipToUser.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-gadget-equiptouser.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Equip To User

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/vvmimage.png)

The **Equip to User** Node enables the user to equip or unequip gadgets, adjacent objects, or HUD elements to the user within the VR environment. This node enhances interactivity by enabling users to interact directly with various items and interface elements as part of their virtual experience.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/ji9image.png)

In this example, the **Equip to User Node** is used to equip a gun controller to the user. Select the gun object, then assign it to the controller by clicking on the plus icon in the User Gadget window.

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/J1kimage.png)

To activate the gun gadget, press the right grip button then the gun will be attached to the User's controller in the VR environment.

---

# User \ Attributes

Every user in your experience can carry extra pieces of information called **attributes** — small named values you attach to a user and read back later. Attributes can also be grouped into named **categories**, which lets one user keep separate attributes that share a name. The nodes on this page let you add, read, check for, and remove attributes on a user, both on their own and inside a category.

Reading an attribute never changes it; setting or removing one changes only that single attribute and leaves everything else about the user untouched.

## Get a user attribute

### Get User Attribute (Number)

Reads a named attribute from a user and gives it back as a number.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the user you connect and hands its value back as a number. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a number. If it is missing, or what is stored cannot be read as a number, the node stops with an error instead of giving you a result — so check with **User Has Attribute** first if you are not sure.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from. If you leave this port unconnected, you can pick an option on the node itself: **Host Only** (the default) or **All Users**.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`score`</td></tr><tr><td>**Value** output</td><td>`85`</td></tr></tbody></table>

### Get User Attribute (Boolean)

Reads a named attribute from a user and gives it back as a true / false value.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the user you connect and hands its value back as a true / false value. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a true / false value. If it is missing, or what is stored cannot be read as a true / false value, the node stops with an error instead of giving you a result — so check with **User Has Attribute** first if you are not sure.

Saved values of `true`, `yes` or `on` are read as true, and `false`, `no` or `off` are read as false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from. If you leave this port unconnected, you can pick an option on the node itself: **Host Only** (the default) or **All Users**.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-0"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`certified`</td></tr><tr><td>**Result** output</td><td>`true`</td></tr></tbody></table>

### Get User Attribute (SceneNode)

Reads a named attribute from a user and gives it back as a scene node.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the user you connect and hands its value back as a scene node. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a scene node. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-1"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`assignedStation`</td></tr><tr><td>**Result** output</td><td>`<WeldingStation>`</td></tr></tbody></table>

### Get User Attribute (SceneState)

Reads a named attribute from a user and gives it back as a scene state.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the user you connect and hands its value back as a scene state. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a scene state. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-2"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`checkpoint`</td></tr><tr><td>**Result** output</td><td>`<Checkpoint2>`</td></tr></tbody></table>

### Get User Attribute (Sequence)

Reads a named attribute from a user and gives it back as a sequence.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the user you connect and hands its value back as a sequence. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a sequence. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-3"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`introSequence`</td></tr><tr><td>**Result** output</td><td>`<SafetyBriefing>`</td></tr></tbody></table>

## Set a user attribute

### [![Response_User_Attribute_StringSet.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-user-attribute-stringset.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Set User Attribute (String)

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/D3Iimage.png)

The **Set User Attribute** response enables user to set a value to an attribute by either typing in a string value in the value field or by attaching a value or a variable node to that port. Then once the response is executed, the variable value can be acquired through the **Value** port.

####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/6ZGimage.png)

[ ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/euiimage.png)

In this example, we added a **String User Attribute** called it **Indoor** with the value **No**

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/TXeimage.png)

<div class="pointer-container" id="bkmrk-%C2%A0-18"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>Once the user enters the object named Building, the **Indoor** attribute's value will be set to **Yes**, then when the object named Teleport Button is triggered, the user(s) with the attribute named **Indoor** and the value **Yes** will be teleported to the **Outside** CameraNode location.

---

### Set User Attribute (Number)

Saves a number onto a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the user you connect and stores a number in it. If the user already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on. If you leave this port unconnected, you can pick an option on the node itself — **Host Only** (the default) or **All Users**, which saves the attribute on every user in the session.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-4"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`score`</td></tr><tr><td>**Value** input</td><td>`85`</td></tr></tbody></table>

### Set User Attribute (Boolean)

Saves a true / false value onto a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the user you choose and stores a true / false value in it. If the user already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on. If you leave this port unconnected, you can pick an option on the node itself — **Host Only** (the default) or **All Users**, which saves the attribute on every user in the session.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-5"><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`certified`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`true`</td></tr></tbody></table>

### Set User Attribute (SceneNode)

Saves a scene node onto a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the user you connect and stores a scene node in it. If the user already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-6"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`assignedStation`</td></tr><tr><td>**Value** input</td><td>the `<WeldingStation>` object</td></tr></tbody></table>

### Set User Attribute (SceneState)

Saves a scene state onto a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the user you connect and stores a scene state in it. If the user already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-7"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`checkpoint`</td></tr><tr><td>**Value** input</td><td>`<Checkpoint2>`</td></tr></tbody></table>

### Set User Attribute (Sequence)

Saves a sequence onto a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the user you connect and stores a sequence in it. If the user already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-8"><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`introSequence`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`<SafetyBriefing>`</td></tr></tbody></table>

## Check or remove a user attribute

### User Has Attribute

Checks whether a user has an attribute with a given name.

#### What it does

This node looks at the user you connect and tells you whether they already have an attribute saved under the name you provide. You get back **true** if they do and **false** if they do not. It only checks — nothing on the user is changed.

It is handy to run before reading or changing an attribute, to be sure it is there.

#### Inputs

<table id="bkmrk-port-type-what-to-co-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to check.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to look for.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>**True** if the attribute exists, otherwise **false**.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-9"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`certified`</td></tr><tr><td>**Result** output</td><td>**true** — the attribute exists</td></tr></tbody></table>

### Remove User Attribute

Deletes a named attribute from a user.

#### What it does

This node removes the attribute saved under the name you provide from the user you connect. That one attribute and its value are deleted from the user; everything else about the user stays the same.

If the user has no attribute with that name, nothing happens.

#### Inputs

<table id="bkmrk-port-type-what-to-co-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to remove the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to remove.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-10"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`tempNote`</td></tr></tbody></table>

## Get a user attribute in a category

### Get User Attribute in Category (String)

Reads a named attribute kept in a category on a user and gives it back as a piece of text.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the user you connect and hands its value back as a piece of text. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold text. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-11"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`role`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>`Safety Officer`</td></tr></tbody></table>

### Get User Attribute in Category (Number)

Reads a named attribute kept in a category on a user and gives it back as a number.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the user you connect and hands its value back as a number. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a number. If it is missing, or what is stored cannot be read as a number, the node stops with an error instead of giving you a result — so check with **User Has Attribute In Category** first if you are not sure.

#### Inputs

<table id="bkmrk-port-type-what-to-co-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Number</td><td>The number stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-12"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`score`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>`85`</td></tr></tbody></table>

### Get User Attribute in Category (Boolean)

Reads a named attribute kept in a category on a user and gives it back as a true / false value.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the user you connect and hands its value back as a true / false value. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a true / false value. If it is missing, or what is stored cannot be read as a true / false value, the node stops with an error instead of giving you a result — so check with **User Has Attribute In Category** first if you are not sure.

Saved values of `true`, `yes` or `on` are read as true, and `false`, `no` or `off` are read as false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-13"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`certified`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>`true`</td></tr></tbody></table>

### Get User Attribute in Category (SceneNode)

Reads a named attribute kept in a category on a user and gives it back as a scene node.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the user you connect and hands its value back as a scene node. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a scene node. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-14"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`assignedStation`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>the `<WeldingStation>` object</td></tr></tbody></table>

### Get User Attribute in Category (SceneState)

Reads a named attribute kept in a category on a user and gives it back as a scene state.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the user you connect and hands its value back as a scene state. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a scene state. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-15"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-15"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-15"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`checkpoint`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>`<Checkpoint2>`</td></tr></tbody></table>

### Get User Attribute in Category (Sequence)

Reads a named attribute kept in a category on a user and gives it back as a sequence.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the user you connect and hands its value back as a sequence. It only reads the user — it does not change the user or the attribute in any way.

The attribute should already exist and hold a sequence. If it is missing, you get an empty result rather than an error, so it is still worth checking with **User Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-16"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-16"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-16"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`introSequence`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>`<SafetyBriefing>`</td></tr></tbody></table>

## Set a user attribute in a category

### Set User Attribute in Category (String)

Saves a piece of text into a category on a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the user you connect and stores a piece of text in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-17"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-17"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-17"><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`role`</td></tr><tr><td style="white-space: nowrap;">**Category** input</td><td>`Training`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`Safety Officer`</td></tr></tbody></table>

### Set User Attribute in Category (Number)

Saves a number into a category on a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the user you connect and stores a number in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-18"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-18"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-18"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`score`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Value** input</td><td>`85`</td></tr></tbody></table>

### Set User Attribute in Category (Boolean)

Saves a true / false value into a category on a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the user you connect and stores a true / false value in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-19"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-19"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-19"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`certified`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Value** input</td><td>`true`</td></tr></tbody></table>

### Set User Attribute in Category (SceneNode)

Saves a scene node into a category on a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the user you connect and stores a scene node in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-20"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-20"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-20"><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`assignedStation`</td></tr><tr><td style="white-space: nowrap;">**Category** input</td><td>`Training`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>the `<WeldingStation>` object</td></tr></tbody></table>

### Set User Attribute in Category (SceneState)

Saves a scene state into a category on a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the user you connect and stores a scene state in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-21"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-21"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-21"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`checkpoint`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Value** input</td><td>`<Checkpoint2>`</td></tr></tbody></table>

### Set User Attribute in Category (Sequence)

Saves a sequence into a category on a user as a named attribute.

#### What it does

Every user in your session can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single user can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the user you connect and stores a sequence in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-22"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-22"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-22"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`introSequence`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Value** input</td><td>`<SafetyBriefing>`</td></tr></tbody></table>

## Check, list, or remove attributes in a category

### User Has Attribute In Category

Checks whether a user has an attribute with a given name inside a category.

#### What it does

This node looks at the user you connect and tells you whether they already have an attribute saved under the name you provide inside the category you name. You get back **true** if they do and **false** if they do not. It only checks — nothing on the user is changed.

#### Inputs

<table id="bkmrk-port-type-what-to-co-23"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to check.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to look for.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to look in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-23"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>**True** if the attribute exists in that category, otherwise **false**.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-23"><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`certified`</td></tr><tr><td style="white-space: nowrap;">**Category** input</td><td>`Training`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>**true** — the attribute exists</td></tr></tbody></table>

### Get User Attribute Category Names

Lists the names of the attributes kept inside a category on a user.

#### What it does

Attributes on a user can be grouped into named **categories**. This node looks at the user you connect and gives you back the names of the attributes that are stored inside the category you name. The names come back as a list of separate pieces of text, so you can connect a node that steps through a list to handle them one at a time. It only reads the user — nothing is changed.

#### Inputs

<table id="bkmrk-port-type-what-to-co-24"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to look at.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category whose attribute names you want.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-24"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The names of the attributes found in that category, returned as a list of separate pieces of text. Connect a node that steps through a list to read them one by one.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-24"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr><tr><td>**Result** output</td><td>a list of names — e.g. `certified`, `score`, `assignedStation`</td></tr></tbody></table>

### Remove User Attribute From Category

Deletes a named attribute that is kept in a category on a user.

#### What it does

This node removes the attribute saved under the name you provide, inside the category you name, from the user you connect. That one attribute and its value are deleted from that category; everything else about the user stays the same.

If no attribute with that name exists in the category, nothing happens.

#### Inputs

<table id="bkmrk-port-type-what-to-co-25"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The user you want to remove the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to remove.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to remove it from.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-25"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same user you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-user-input-the-%3Ctrai-25"><tbody><tr><td>**User** input</td><td>the `<Trainee01>` user</td></tr><tr><td>**Attribute Name** input</td><td>`tempNote`</td></tr><tr><td>**Category** input</td><td>`Training`</td></tr></tbody></table>

# User \  Point To Object

### [![Response_Gadget_EquipToUser.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-gadget-equiptouser.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Point To Object

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/gdNimage.png)

The **Point To Node** enables the user to be guided to the location of a specific place or object within the scene. When this node is activated, an arrow is displayed, pointing to the location of the assigned SceneNode within the VR environment.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/Bd3image.png)

In this example, the **Point To Node** is used to guide the user to the location of an object named button when the Scene Start event occurs. As soon as the scene begins, an arrow appears, pointing directly to the button location, helping the user finding it within the VR environment.

---

# User \ Set Mode

### ![Response_InteractionMode_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-interactionmode-set.png) Set Interaction Mode

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/image.png)

The **Set Interaction Mode node** dynamically changes how participants engage with the VR environment. When activated, the node evaluates the targeted User input—which can be configured for either "Host Only" or "All Users" and immediately switches their current control state to the selected Mode. The available interaction modes include:

<div dir="auto" id="bkmrk-default%3A-the-standar"><div dir="auto">- **Default:** The standard, baseline interaction and movement mechanics of the VR Viewer.
- **Drawing:** Enables the user to freely draw directly onto 3D surfaces within the scene.
- **Scene Building:** Unlocks spatial editing capabilities, allowing the user to dynamically adjust the location, rotation, and scale of 3D objects to freely move and place models around the environment.
- **Measurement:** Enables the user to draw straight lines across the scene, accurately measuring distances and lengths in meters.

</div></div>###   


<div dir="auto" id="bkmrk--0"><div dir="auto">---

</div></div>### ![Response_Scene_NightMode_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-scene-nightmode-set.png) Set Night Mode

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/rKvimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/rKvimage.png)

**The Set Night Mode node** instantly alter the environmental lighting and skybox of the VR scene to nighttime. Once activated, the node evaluates the boolean Enable input—transitioning the scene's overall environment to a dark night mode.

<div dir="auto" id="bkmrk--3"><div dir="auto">---

</div></div>### Set Fly Mode

Turns fly mode on or off for a user, letting them move freely up and down through the air instead of being kept on the ground.

#### What it does

With fly mode on, the chosen user can move up, down, and through the scene freely — handy for inspecting a tall machine from above or getting a bird’s-eye view of a training area. With it off, the user is returned to normal ground-level movement and walks along surfaces as usual.

You pick who this applies to with the **User** port (just the host, or everyone), and you set whether fly mode is on or off with the **Enable** port. The node only changes how that user moves — it doesn’t move or alter anything in the scene itself. The same user is passed back out so you can connect more user nodes after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to run the node.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Chooses who fly mode applies to. Pick **Host Only** to affect just the host, or **All Users** to affect everyone in the session.</td></tr><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Set to `true` to turn fly mode on, or `false` to turn it off and return to normal ground movement.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished, so you can continue to the next step.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Passes the same user along so you can chain more user nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Passes along the on/off value you set, in case a later node needs it.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-host-only"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`Host Only`</td></tr><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**Enable** output</td><td>`true` — the host can now fly freely through the scene</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-pair-two-of-these-no"><div dir="auto">- Pair two of these nodes — one with **Enable** set to `true` and one set to `false` — to let an author toggle flying on and off with a button or voice command.
- Remember to turn fly mode back off when it’s no longer needed, so users return to normal walking.

---

</div></div>### Set Speed Mode

Sets how fast a participant moves around the VR scene — walking, jogging, or running.

#### What it does

This node changes a participant’s movement speed in the VR environment. When it runs, it looks at the user you target and switches their walking pace to the speed you pick: `Walk`, `Jog`, or `Run`.

You choose whether to change just the host or everyone in the session. The new speed stays in effect until something changes it again, so you can use this node to slow people down in a tight space or let them cover ground quickly in a large scene.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Chooses who this applies to. Pick **Host Only** to change just the host, or **All Users** to change the speed for everyone in the session.</td></tr><tr><td style="white-space: nowrap;">**Mode**</td><td style="white-space: nowrap;">Choice</td><td>The movement speed to apply. Pick one of **Walk**, **Jog**, or **Run**.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the speed has been set, so you can continue to the next node.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Passes along the same user you targeted, so you can chain more user nodes after this one.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-all-users"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`All Users`</td></tr><tr><td style="white-space: nowrap;">**Mode** input</td><td>`Run`</td></tr><tr><td style="white-space: nowrap;">**User** output</td><td>The same participants, ready for the next node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-pair-this-with-a-tri"><div dir="auto">- Pair this with a trigger such as entering a large open area to let participants `Run`, then switch back to `Walk` when they reach a detailed space.
- Use **Host Only** when you want a guide to keep up with a group without changing everyone’s pace.

---

</div></div>### Set Speeds Multiplier

Changes how fast a participant moves around in the scene by applying a speed multiplier to them.

#### What it does

This node sets a movement-speed multiplier on the chosen participant. A value of `1` is normal speed, `2` makes them move twice as fast, and `0.5` slows them to half speed. Use it to speed people up across a large area or slow them down for a careful, detailed task.

The change applies to whichever participant you point the node at — just the host, or everyone. It only adjusts their movement speed; nothing else about the scene or the participant is affected, and the same participant is passed straight out again so you can connect more actions after it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>Choose which participant to affect: **Host Only** or **All Users**.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The speed multiplier. `1` is normal speed, higher is faster, lower is slower. Must not be negative.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**User**</td><td style="white-space: nowrap;">User</td><td>The same participant you chose, passed along so you can chain more user actions after this one.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The multiplier you set, passed along for reuse.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-user-input-all-users-0"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**User** input</td><td>`All Users`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`1.5`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`1.5`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-set-the-value-back-t">- Set the value back to `1` when you want participants to return to their normal speed.
- A value of `0` stops movement entirely — useful for briefly holding everyone in place.

</div>

# User Name & ID

### [![Response_Cloud_USERID_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-cloud-userid-get.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Get User ID

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/xXdimage.png)

The **Get User ID node** is used to retrieve the unique identifier of the user interacting within the VR environment. This ID can be utilized for various purposes, such as tracking user actions or customizing experiences based on the user.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/YZximage.png)

In this example, the **Get User ID node** is used to create a student attendance system. When the user triggers the Activate event, the "Get User ID" retrieves the Student ID number and stores it in the "`attendance_ID"` variable using the "Set Number Variable" node.

**Note:** To retrieve the User ID, the experience must be run from a **logged-in** account in SimLab VR Viewer.

<div dir="auto" id="bkmrk--0"><div dir="auto">---

</div></div>### [![Response_User_Name_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-user-name-get.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-user-name-get.png) Get User Name

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/5fXimage.png)

The **Get User Name node** is used to retrieve the name of the user interacting within the VR environment. This name can be utilized for various purposes, such as personalizing interactions or saving progress tied to a specific user.

<div dir="auto" id="bkmrk--6"><div dir="auto"><div class="mt-1 flex gap-3 empty:hidden -ml-2" id="bkmrk--15"><div class="items-center justify-start rounded-xl p-1 flex"><div class="flex items-center"><button aria-label="Read Aloud" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Copy" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Regenerate" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex"><button aria-label="Good response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Bad response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button>  
</div><div class="flex items-center pb-0"><div class="[&_svg]:h-full [&_svg]:w-full icon-md h-4 w-4"><svg fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg>  
</div></div><button aria-expanded="false" aria-haspopup="menu" class="cursor-pointer h-[30px] rounded-md px-1 text-token-text-secondary hover:bg-token-main-surface-secondary" data-state="closed" id="bkmrk--18" type="button"></button></div></div></div></div></div>#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/0aDimage.png)

In this example, the "Get User Name" node is used to create a student attendance system. When the user triggers the Activate event, the "Get User Name" retrieves the student's name and stores it in the `attendance_UserName` variable using the "Set String Variable" node.

  
**Note:** To retrieve the User Name, the experience must be run from a **logged-in** account in SimLab VR Viewer.

<div dir="auto" id="bkmrk--9"><div dir="auto">---

</div></div>

# Material

A **material** decides how a surface looks in your scene — its color, how see-through it is, and the image (called a **texture**) painted across it. The nodes on this page let your scene read and change those looks while it is running: fade an object out, recolor a warning light, combine two images, or save a texture to a picture file. You normally get a material by reading it from an object in your scene, then wire it into the **Material** input of these nodes. Because objects can share the same material, changing a material updates every object using it at once.

## What's on this page

- **Alpha** — read or change how see-through a material is.
- **Color** — read or change a material’s color.
- **Texture** — blend two images into a new one, or save a material’s texture out as a picture file.

---

## Alpha

A material’s **alpha** is how see-through it is, given as a number from `0` (fully transparent) to `1` (fully solid). A value like `0.5` is half see-through. These two nodes read a material’s current alpha or set a new one — useful for fading objects in and out.

### Get Material Alpha

Reads how transparent a material is, so you can check its current see-through level.

#### What it does

This node looks at a material and tells you its alpha — the amount the material lets you see through it. The alpha is given as a Number from `0` (fully see-through) to `1` (fully solid), where a value like `0.5` is half see-through.

It only reads the value — it does not change the material in any way. The same material you fed in comes straight back out, so you can keep working with it in the next node.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material you want to check. Connect a node that gives you a material, such as one that reads the material from an object in your scene.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished. Wire it to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The same material you connected, passed straight through unchanged so you can use it again.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The material’s alpha, from `0` (fully see-through) to `1` (fully solid).</td></tr></tbody></table>

#### Example

<table id="bkmrk-material-input-the-g"><tbody><tr><td>**Material** input</td><td>The glass panel material from your scene</td></tr><tr><td>**Value** output</td><td>`0.5`</td></tr></tbody></table>

#### Tips

- A value of `0` means the material is completely see-through, and `1` means it is fully solid.
- Pair this with **Set Material Alpha** when you want to remember a material’s current transparency, change it for a while, and then put it back.

### Set Material Alpha

Changes how see-through a material is, from fully invisible to fully solid.

#### What it does

This node sets the transparency of a material. You give it a material and a number between `0` and `1`: `0` makes the material completely invisible (see-through), `1` makes it completely solid, and values in between make it partly see-through — for example `0.5` is half-transparent.

The change takes effect right away on the material you pass in. The node hands the same material straight back out, along with the transparency value you set, so you can keep using them in the next steps of your script.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material whose transparency you want to change.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>How see-through to make it, from `0` (fully invisible) to `1` (fully solid). Must be in the range `0` to `1`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The same material you passed in, now with its new transparency.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The transparency value you set, passed back so you can reuse it.</td></tr></tbody></table>

#### Example

<table id="bkmrk-material-input-the-g-0"><tbody><tr><td>**Material** input</td><td>The glass material on a window</td></tr><tr><td>**Value** input</td><td>`0.3`</td></tr><tr><td>**Material** output</td><td>The same glass material, now mostly see-through</td></tr><tr><td>**Value** output</td><td>`0.3`</td></tr></tbody></table>

#### Tips

- Keep the value between `0` and `1`. Think of it as a percentage: `0` is 0% solid (invisible), `1` is 100% solid, and `0.5` is halfway.
- To fade something out over time, run this node repeatedly with a value that steps down from `1` toward `0`.

---

## Color

These two nodes read or change a material’s **color**. A color is shown as a small swatch you can click to open a color picker — a color wheel with RGB, HSV, and HEX entry. Remember that setting a color changes every object that shares the material.

### Get Material Color

Reads the current color of a material so you can use it elsewhere in your scene.

#### What it does

Give this node a material and it hands you back that material’s current color — the color a viewer sees on every object using that material. The color comes out as a color value (shown as a small colored swatch), which you can feed into other nodes, compare against another color, or store for later.

Reading the color does not change anything — the material keeps looking exactly as it did. If you actually want to change a material’s color, use the **Set Material Color** node instead, where you pick the new color from a swatch and color picker.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material whose color you want to read. Connect a material coming from another node, such as one you picked from an object in your scene.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The same material you connected, passed straight through — handy for wiring it into the next node without fetching it again.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Color</td><td>The material’s current color, as a color value you can reuse. It shows as a colored swatch and can be passed to any node that accepts a color.</td></tr></tbody></table>

#### Example

<table id="bkmrk-material-input-the-m"><tbody><tr><td>**Material** input</td><td>The material on a warning light in your scene</td></tr><tr><td>**Material** output</td><td>The same material, passed through</td></tr><tr><td>**Value** output</td><td>A red color value — for example `#C81E1E`</td></tr></tbody></table>

#### Tips

- Use the **Material** output to keep your wiring tidy — you can read the color and pass the same material along to the next step in one go.
- Pair this with **Set Material Color** to save a material’s original color, change it for a while, then put the saved color back later.

### Set Material Color

Changes the color of a material so everything using that material takes on the new look.

#### What it does

This node paints a material with the color you choose. Once it runs, every object in your scene that uses that material is shown in the new color right away — handy for things like turning a warning light red, swapping a wall’s paint, or highlighting a part during a training step.

It only changes the color of the material; the material’s shape, texture, and everything else stay the same. The same material comes back out so you can keep working with it, along with the color you applied.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material you want to recolor. Connect it from a node that gives you a material, such as one that picks an object’s material.</td></tr><tr><td style="white-space: nowrap;">**Color**</td><td style="white-space: nowrap;">Color</td><td>The new color you want the material to have. Click the color swatch on the node to open the color picker, then pick a color from the wheel, type in RGB or HSV numbers, or enter a HEX code such as `#C81E1E`. You can also connect a color coming from another node.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished, so you can continue to the next step.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The same material you sent in, now showing the new color. Pass it on if you want to make more changes to it.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Color</td><td>The color that was applied, in case you want to reuse it elsewhere.</td></tr></tbody></table>

#### Example

<table id="bkmrk-material-input-the-m-0"><tbody><tr><td>**Material** input</td><td>The material on a warning lamp in your scene</td></tr><tr><td>**Color** input</td><td>`#C81E1E` (a red, chosen from the color picker)</td></tr><tr><td>**Material** output</td><td>The same lamp material, now red</td></tr><tr><td>**Value** output</td><td>`#C81E1E`</td></tr></tbody></table>

#### Tips

- Because the color is set on the material, every object that shares that material changes together. If you only want one object to change, give it its own material first.
- To put the original color back later, save it first with a Get Material Color node, then feed that saved color back into this node when you want to restore it.

---

## Texture

A **texture** is the image painted across a material’s surface. These two nodes work with image files inside your project: one blends two images into a new one, the other saves a material’s texture out as a PNG picture. Both do their work in the background and hand back a true/false result telling you whether they succeeded.

### Blend Textures

Combines two image files from your project into a single new image, with one laid on top of the other.

#### What it does

This node takes two images that already live in your project — a **Base** image and an **Overlay** image — and lays the Overlay on top of the Base to create one combined picture. It saves the result as a brand-new image file inside your project and gives you back that new file’s name, so you can use it as a texture, a label, or any other image.

Your two original images are left untouched — the node only creates a new combined image and never changes the Base or the Overlay. Because building the new image can take a moment, this node works in the background: its Execute output fires only once the blend has finished. You also get a true/false result telling you whether it worked.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Base**</td><td style="white-space: nowrap;">Text</td><td>The name of the bottom image — the one that goes underneath. Use a short file name (including its extension) for an image inside your project, such as `wood_panel.png`.</td></tr><tr><td style="white-space: nowrap;">**Overlay**</td><td style="white-space: nowrap;">Text</td><td>The name of the top image — the one laid over the Base. Use a short file name (including its extension) for an image inside your project, such as `logo.png`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the two images have finished blending. Wire this to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**Base**</td><td style="white-space: nowrap;">Text</td><td>The Base image name you provided, passed straight through so you can reuse it.</td></tr><tr><td style="white-space: nowrap;">**Overlay**</td><td style="white-space: nowrap;">Text</td><td>The Overlay image name you provided, passed straight through so you can reuse it.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>`true` if the new combined image was created, or `false` if it could not be made (for example, if one of the image names was wrong).</td></tr><tr><td style="white-space: nowrap;">**FileName**</td><td style="white-space: nowrap;">Text</td><td>The short file name of the new combined image inside your project. When the blend fails this comes back empty.</td></tr></tbody></table>

#### Example

<table id="bkmrk-base-input-wood_pane"><tbody><tr><td style="white-space: nowrap;">**Base** input</td><td>`wood_panel.png`</td></tr><tr><td style="white-space: nowrap;">**Overlay** input</td><td>`logo.png`</td></tr><tr><td style="white-space: nowrap;">**Success** output</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**FileName** output</td><td>`wood_panel_blended.png`</td></tr></tbody></table>

#### Tips

- Make sure both images are already part of your project and that you type their names exactly, including the file extension (for example `.png`).
- Check the **Success** output before using the new image — if it comes back `false`, the **FileName** will be empty.
- The order matters: the **Overlay** always sits on top of the **Base**. Swap the two inputs if the result looks upside-down.

### Save Texture

Saves a material’s texture image out as a PNG picture file inside your project.

#### What it does

This node takes the texture (the surface image) used by a material and writes it out as a PNG picture file inside your current SimLab project. You give it the material to read from and a file name to save under, and it produces that picture for you.

It does not change the material or its texture in any way — it simply makes a copy of the texture as a separate picture file. The node works in the background, so its Execute output only fires once the picture has been fully saved. You also get a true/false result telling you whether the save worked.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material whose texture you want to save. Its surface image is the one that gets written out as a PNG.</td></tr><tr><td style="white-space: nowrap;">**FileName**</td><td style="white-space: nowrap;">Text</td><td>The name to save the picture under, including the `.png` ending — for example `crate_diffuse.png`. This is a short name; the file is saved inside your current project.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the picture has finished saving. Wire this to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The same material you passed in, handed straight back so you can keep using it in later nodes.</td></tr><tr><td style="white-space: nowrap;">**FileName**</td><td style="white-space: nowrap;">Text</td><td>The short name the picture was saved under, such as `crate_diffuse.png`.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>`true` if the picture was saved, or `false` if it could not be saved (for example, the material has no texture).</td></tr></tbody></table>

#### Example

<table id="bkmrk-material-input-the-m-1"><tbody><tr><td>**Material** input</td><td>The material on a crate object</td></tr><tr><td>**FileName** input</td><td>`crate_diffuse.png`</td></tr><tr><td>**FileName** output</td><td>`crate_diffuse.png`</td></tr><tr><td>**Success** output</td><td>`true`</td></tr></tbody></table>

#### Tips

- Remember to include the `.png` ending in the file name yourself — for example `crate_diffuse.png`.
- Check the **Success** output before relying on the saved picture; a material with no texture image will return `false`.
- Because the save happens in the background, build the rest of your steps off this node’s Execute output so they only run after the picture is ready.

---

### ![Response_Material_Copy.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-material-copy.png) Copy Material

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/7KYimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/7KYimage.png)

The Copy Material node duplicates an existing material and create a completely independent instance. Upon triggering the Execute input, the node takes the specified Material input and outputs a newly generated Copy of that material, which can then be freely modified without altering the original source.

---

### ![Response_Material_CopyProperties.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-material-copyproperties.png) Copy Material Properties

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/6MLimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/6MLimage.png)

The Copy Material Properties node transfers visual attributes directly from one material to another without generating a new instance. When the Execute input is triggered, the node takes the characteristics of the Source Material input and applies them directly to the Target Material input, instantly overwriting the target's previous properties.

##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/9lXimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/9lXimage.png)

In this example, triggering the "Change Color" object prompts the system to execute the Copy Material Properties node. Once activated, the node takes all the visual attributes from the "cabinets" source material and immediately applies them to the "tables" target material, causing any 3D objects using the tables material to instantly match the appearance of the cabinets.

# Material \ Texture

### ![Response_Material_Texture_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-material-texture-set.png) Set Texture From File  
  


[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/YgPimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/YgPimage.png)

This node replaces the current texture of a specified material with a 2D image file stored in your Resource Management system. By inputting the exact file name, you can dynamically update the visual appearance of any object using that material during the experience.

# Execution

### ![Response_BranchExpression.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-branchexpression.png) Branch on Expression

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/q8Mimage.png)The **Branch on Expression** response enables the user to evaluate an expression with the possible outputs of True or False each time the event connected to it is triggered. Once the response is executed, the result of the evaluation can be acquired through the **True** or **False** ports.

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk-"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8"><svg class="icon-md" fill="none" height="41" role="img" viewbox="0 0 41 41" width="41" xmlns="http://www.w3.org/2000/svg"></svg>  
</div></div></div></div></div>#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/WPEimage.png)


In this example, a **Branch on Expression** response is used to evaluate an expression once the user triggers the object named Activate. The result of the expression, which will be either True or False, if the result was true, the object named "Variable\_01" will be shown, if it was false, the object named "Variable\_02" will be shown.

---

### [![Response_Delay.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-delay.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/response-delay.png) Delay

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/UO0image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/UO0image.png)

**The Delay node** waits for the specified **Duration** (in seconds), then executes the node linked to its **Execute** output.

Duration can be an integer or a float less than one to achieve sub-second delays.

---

### ![Response_Loop.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-loop.png) Loop

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/72Yimage.png)

The **Loop node** enables the user to repeatedly execute a connected response for a specified number of times as defined in the Number of Loops field. Each time the event connected to the loop is triggered, the response is executed repeatedly, and the loop continues until the assigned number of repetitions is completed.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/tagimage.png)


In this example, a **Loop node** is used to repeatedly execute the connected response that decreases the value of a number variable by one. The Decrement response is repeated for the number of times specified in the **Number of Loops** field, with the duration between each repetition set in the **Interval** field. Once the assigned number of repetitions is completed, the sound named **Countdown\_Over** plays.

---

### ![Responses_execution_RunScript.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/responses-execution-runscript.png) Run Script

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/untitled-1.png)

The **Run Script** node allows the user to execute advanced functions using the **Lua programming language**. This node provides flexibility by enabling custom scripts to be triggered when an event occurs. Allowing for complex operations and logic to be carried out as defined in the script. This node is ideal for scenarios requiring functionality beyond the standard nodes, offering advanced customization and control over the system.

You can read about Lua Scripting in SimLab Training builder through the following Blog:

<span style="text-decoration: underline;">**[Lua Scripting Blog](https://blog.simlab-soft.com/lua-scripting-in-simlab-training-builder-from-beginner-to-beyond/ "Lua Scripting Blog")**</span>

> **[Lua Documentation for SimLab Training Builder](https://www.simlab-soft.com/3d-products/docs/help/scripting/English/Lua/ "Lua Documentation for SimLab Training Builder")**

---

### [![Response_CustomEvent_Trigger.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-customevent-trigger.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/response-customevent-trigger.png) Trigger Custom Event

[![xyLimage.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/xylimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/xylimage.png)

Calling this **Trigger Custom Action** will execute the corresponding [**Custom Action** event ](https://simlab-soft.com/help/link/581#bkmrk-custom-event%C2%A0)(based on the matching ID), passing along any optional information provided in the info field.

This is useful when you want multiple paths in your experience to produce the same response — without duplicating it each time.

---

### Branch

Sends the action down one of two paths depending on whether a yes/no value is true or false.

#### What it does

Branch is a fork in the road for your scene’s actions. When it runs, it looks at the yes/no value wired into **Condition**. If that value is true, it fires the **True** path; if it’s false, it fires the **False** path.

Exactly one of the two paths fires every time — never both, and never neither. This lets you say “if this is the case, do these steps; otherwise, do those steps instead.” Branch only chooses a direction; it doesn’t change the value you give it.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Condition**</td><td style="white-space: nowrap;">True / false</td><td>The yes/no value to test. Wire in anything that gives a true/false result — for example a check on whether a door is open or whether a score has passed a target.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**True**</td><td style="white-space: nowrap;">Trigger</td><td>Fires when the Condition is true. Wire the steps you want to run in that case here.</td></tr><tr><td style="white-space: nowrap;">**False**</td><td style="white-space: nowrap;">Trigger</td><td>Fires when the Condition is false. Wire the steps you want to run in that case here.</td></tr></tbody></table>

#### Example

<table id="bkmrk-condition-input-true"><tbody><tr><td style="white-space: nowrap;">**Condition** input</td><td>`true`</td></tr><tr><td style="white-space: nowrap;">**True** output</td><td>Fires — the steps wired here run (for example, play a success sound).</td></tr><tr><td style="white-space: nowrap;">**False** output</td><td>Does not fire this run.</td></tr></tbody></table>

#### Tips

- Leave the **False** path empty if you only care about acting when the Condition is true — nothing happens on that side and the rest of your scene carries on.
- To choose between more than two paths, chain several Branch nodes together, sending the **False** path of one into the next.

### Do Then

Splits one trigger into two that fire in a guaranteed order — first the “Execute” output, then the “Then” output, right after.

#### What it does

When this node runs, it fires its “Execute” output first and then immediately fires its “Then” output. Use it when you want two things kicked off from a single trigger and you care which one starts first.

The node only controls the **order** the two outputs fire in — it does not wait for the work wired to “Execute” to finish before firing “Then.” The “Then” output always fires, no matter what happens on the “Execute” side. This node doesn’t change or hold onto any of your scene data; it simply directs the flow.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to run this node.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires first. Wire this to the steps you want to start before the “Then” steps.</td></tr><tr><td style="white-space: nowrap;">**Then**</td><td style="white-space: nowrap;">Trigger</td><td>Fires right after “Execute,” without waiting for the “Execute” steps to finish. It always fires. Wire this to the steps you want to start second.</td></tr></tbody></table>

#### Example

<table id="bkmrk-execute-input-trigge"><tbody><tr><td style="white-space: nowrap;">**Execute** input</td><td>Triggered when a button in the scene is clicked</td></tr><tr><td style="white-space: nowrap;">**Execute** output</td><td>Fires first — starts playing a door-opening animation</td></tr><tr><td style="white-space: nowrap;">**Then** output</td><td>Fires right after — shows a hint label to the user</td></tr></tbody></table>

#### Tips

- Reach for this when two actions share one trigger and you want a reliable order — the “Execute” output’s steps always start before the “Then” output’s.
- Remember that “Then” does not wait for the “Execute” side to finish. If you need the second action to begin only after the first one has fully completed, drive it from the end of the first chain instead.

# SceneNode \ Management

### [![Responses_SceneNode_NodesManagement_CastSceneNode.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/responses-scenenode-nodesmanagement-castscenenode.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Cast SceneNode

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/DPOimage.png)

The **Cast SceneNode** enables the user to change the type of a SceneNode by selecting a typeInfo from the list, such as sound, 3D object, video, gadget, or camera. This node identifies the assigned SceneNode as the chosen type, allowing it to function accordingly within the VR environment.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/d0fimage.png)

In this example, Animals sounds are assigned to the animals as **SceneNode** type

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/c2vimage.png)

A **Cast SceneNode** is used to identify the SceneNode of an animal object (dog, cat, and horse) as a sound. An attribute named "Sound" is added to all three animals, and the corresponding sound is assigned to each. When the user triggers the animal SceneNode, the **Cast SceneNode** plays the sound assigned in the attribute.

<div dir="auto" id="bkmrk--5"><div dir="auto">---

</div></div>### [![Response_Node_Parent_Reset.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/responses-scenenode-nodesmanagement-enablecollision.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Set Node Collision Enabled

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The **Set Node Collision Enabled** node is used to enable or disable collision for the user. This can be utilized to allow the user to pass through objects or be blocked by them within the VR environment.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/KNtimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/S2himage.png)

<div dir="auto" id="bkmrk-%C2%A0-5"><div dir="auto"><div class="pointer-container" id="bkmrk-%C2%A0-11"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div></div>In this example, the **Set Node Collision Enabled** node is used to disable collision for the user when the scene starts. The wall is assigned as the target object, and the collision is set to "False," allowing the user to pass through it.

This is shown in the following tutorial

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/QlagX08XJE0" width="560"></iframe>

<div dir="auto" id="bkmrk--7"><div dir="auto"><div class="mb-2 flex gap-3 empty:hidden -ml-2" id="bkmrk--50"><div class="items-center justify-start rounded-xl p-1 flex">  
</div></div>---

</div></div>### [![Response_Node_Parent_Reset.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/responses-scenenode-nodesmanagement-enablecollision.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Delete SceneNode

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/kyTimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)

The **Delete SceneNode** node enables users to remove a specified object from the scene during a VR Experience. This node allows for dynamic scene modifications by deleting objects based on interactions or conditions, making the environment more interactive and adaptable. Once executed, the specified object is permanently removed from the scene.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/0QSimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/0QSimage.png)

<div dir="auto" id="bkmrk-%C2%A0-6"><div dir="auto"><div class="pointer-container" id="bkmrk-%C2%A0-14"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div></div>In this example, the **Delete SceneNode** node is used to remove a trigger box from the scene. The **Node Triggered** event is activated when the user triggers or clicks on an object named "Remove." As soon as the object is triggered, the **Delete SceneNode** node removes the trigger box from the scene, preventing further interactions with it.

<div dir="auto" id="bkmrk--10"><div dir="auto">---

</div></div>###   


### ![Response_Node_Collision_WalkThrough.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-collision-walkthrough.png) Enable Walk-Through

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Eoyimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Eoyimage.png)

The **Enable Walk-Through node** explicitly controls the physical collision properties of a targeted 3D object within the VR Viewer. When activated, the node uses the boolean Enable input to determine the collision state of the specified SceneNode—allowing users to seamlessly pass directly through the object without physical obstruction if set to *True.*

<div dir="auto" id="bkmrk--20"><div dir="auto">---

</div></div>### ![Response_Node_FindByName.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-findbyname.png) Find Node By Name

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/zXiimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/zXiimage.png)

The **Find Node By Name node** searches the VR environment and dynamically locate a specific 3D object based on its assigned text identifier. When activated, the node takes the exact string provided in the Name input, searches the scene to find the corresponding object, and outputs that specific SceneNode reference.

###   


[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/yeKimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/yeKimage.png)

###   


<div dir="auto" id="bkmrk--32"><div dir="auto">---

</div></div>### ![Response_Node_Name_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-name-get.png) Get Node Name

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Ynximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Ynximage.png)

The **Get Node Name node** retrieves the exact text identifier of a specific 3D object within the scene. When activated, the node takes the targeted SceneNode input, extracts its assigned name, and outputs this text as a string value through the Result pin.

<div dir="auto" id="bkmrk--35"><div dir="auto">---

</div></div>### ![Response_Node_MakeCopy.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-makecopy.png) Make Node Copy

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/m3ximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/m3ximage.png)

The **Make Node Copy node** duplicates a specific 3D object along with an independent copy of its material. Once activated, the node takes the targeted SceneNode input and generates a completely separate Copy, ensuring that any subsequent material or texture changes applied to this new object do not affect the original source.

<div dir="auto" id="bkmrk--40"><div dir="auto">---

</div></div>### ![Response_Node_MakeInstance.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-makeinstance.png) Make Node Instance

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/HRAimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/HRAimage.png)

The **Make Node Instance node** generates a direct clone of a specific 3D object in the scene. When activated, the node takes the targeted SceneNode input and creates a new Instance that shares the exact same material properties as the original.


##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/PCVimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/PCVimage.png)

In this example, we create a simple shooting mechanic where firing a gun generates and shoots a bullet toward a target:

<div dir="auto" id="bkmrk-a-node-is-grabbed-no"><div dir="auto">1. A **Node Is Grabbed** node continuously checks if the user is holding the "Gun" object, enabling the next node if the condition is met.
2. A **Grip Pressed** event node listens for the user to press the right hand's grip button, acting as the trigger to fire the weapon.
3. Once the grip is pressed, the **Make Node Instance** node activates, immediately generating a new instance of the "Bullet" object in the scene.
4. A **Get Node Location** node is then used to retrieve the exact X, Y, and Z coordinates of a specific "AimTarget" object.
5. Finally, a **Set Node Location (Animated)** node takes the newly generated bullet instance and smoothly moves it to the AimTarget's coordinates over a quick duration of 0.2 seconds, simulating a flying projectile.

<div class="flex items-center" id="bkmrk--61"><button aria-expanded="false" aria-haspopup="menu" class="cursor-pointer h-[30px] rounded-md px-1 text-token-text-secondary hover:bg-token-main-surface-secondary" data-state="closed" id="bkmrk--62" type="button"></button></div><div class="flex items-center" id="bkmrk--63"></div>---

<div class="flex items-center" id="bkmrk--65"></div><div class="flex items-center" id="bkmrk--66"></div></div></div>### ![Response_Node_SimulatePhysics.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-simulatephysics.png) Set Node Simulate Physics

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/eVHimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/eVHimage.png)

The **Set Node Simulate Physics node** activates or deactivates real-time physics calculations for a specific 3D object within the VR Viewer. When activated, the node uses the boolean Enable input to determine the object's physical state, allowing the object to react to gravity, collisions, and user interactions based on its assigned material physics properties

[![Untitled-1.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/untitled-1.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/untitled-1.png)

To configure how an object behaves during simulation, navigate to the Properties panel and select the Material tab. Under the Physics Properties section, you can adjust specific physical attributes for that material, such as its Density, Friction, and Restitution, which directly impact how the object interacts with the environment when physics are enabled.

<div dir="auto" id="bkmrk--48"><div dir="auto">---

</div></div>### Is Same Node

Checks whether two scene nodes are the same node, and gives you a true/false answer.

#### What it does

You hand this node two scene nodes — **SceneNode A** and **SceneNode B** — and it tells you whether they are the same. The answer comes out of the **Result** port as true or false: true when the two are the same, false when they are different.

This node only looks — it never changes either scene node. Both scene nodes also come straight back out unchanged, so you can keep wiring from them to whatever should happen next.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode A**</td><td style="white-space: nowrap;">Scene node</td><td>The first scene node you want to compare.</td></tr><tr><td style="white-space: nowrap;">**SceneNode B**</td><td style="white-space: nowrap;">Scene node</td><td>The second scene node you want to compare against the first.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode A**</td><td style="white-space: nowrap;">Scene node</td><td>The same first scene node you connected, passed straight back out unchanged so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**SceneNode B**</td><td style="white-space: nowrap;">Scene node</td><td>The same second scene node you connected, passed straight back out unchanged so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>True when the two scene nodes are the same, false when they are different.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-a-input-th"><div dir="auto"><table><tbody><tr><td>**SceneNode A** input</td><td>The `Front Door` node picked earlier in your script</td></tr><tr><td>**SceneNode B** input</td><td>The node the user just clicked</td></tr><tr><td>**Result** output</td><td>`true` if the clicked node is the `Front Door`, otherwise `false`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-wire-the-result-into"><div dir="auto">- Wire the **Result** into a node that branches on true/false to do one thing when the two match and another when they don’t — for example, only open a door when the clicked node really is that door.

---

</div></div>### Set Socket Node Enabled

Turns a snapping socket on or off, so you can control whether objects are allowed to snap into that spot.

#### What it does

A socket is a spot in your scene that objects can snap into — for example the place where a bolt seats into a housing, or where a tool clips onto a wall mount. This node lets you switch one of those sockets on or off while the scene is running. When you set it to on, objects can snap into the socket as usual; when you set it to off, the socket stops accepting anything, so nothing can snap there until you turn it back on.

This is handy for guiding a trainee through steps in order — you can keep a socket switched off until it is the right time to use it, then switch it on so the next part can be placed. The node only changes whether that socket is active; it does not move, snap, or remove anything already in the scene. It hands the same object and the same on/off value back out so you can keep wiring from them.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to run the node at the moment you want the socket switched.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The socket you want to switch — the snapping spot in your scene whose state you want to change, such as a `BoltSocket_01`.</td></tr><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>Whether the socket should be on or off. Connect `true` to switch it on so objects can snap into it, or `false` to switch it off so nothing can snap there.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished, so you can continue to the next step.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same socket you put in, passed straight back out so you can keep wiring from it without looking it up again.</td></tr><tr><td style="white-space: nowrap;">**Enable**</td><td style="white-space: nowrap;">True / false</td><td>The same on/off value you put in, passed back out in case you want to reuse it further along.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-bolt"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`BoltSocket_01`</td></tr><tr><td style="white-space: nowrap;">**Enable** input</td><td>`true` — switch the socket on so the bolt is now allowed to snap into it</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`BoltSocket_01`, handed straight back so you can wire it into the next node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-keep-a-socket-switch">- Keep a socket switched off until it is the right step, then switch it on — a good way to make sure parts are placed in the order you intend.
- Switching a socket off does not remove anything already snapped into it; it only stops new objects from snapping there.

</div>

# SceneNode \ Transform

### ![Response_Node_Transform_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-transform-set.png) Get Node Transform

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/3kSimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/3kSimage.png)

The **Get Node Transform node** retrieves the complete spatial data—including the exact location, rotation, and scale values—of a specific 3D object in the scene. When activated, the node takes the targeted SceneNode input, extracts its current transform matrix, and outputs this combined information through the Transform pin.

<div dir="auto" id="bkmrk-"><div dir="auto">---

</div></div>### ![Response_Node_Transform_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/SKsresponse-node-transform-set.png) Set Node Transform

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Inximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Inximage.png)

The **Set Node Transform node** instantly applies a complete set of spatial data—encompassing location, rotation, and scale—to a specific 3D object. Once activated, the node evaluates the targeted SceneNode and immediately updates its physical presence in the scene to perfectly match the data provided through the Transform input.

<div dir="auto" id="bkmrk--0"><div dir="auto">---

</div></div>### ![Response_Node_Transform_Set_Animated.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-transform-set-animated.png) Set Node Transform (Animated)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/hFSimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/hFSimage.png)

The **Set Node Transform (Animated) node** functions similarly to the standard set transform node, but it smoothly transitions the 3D object to the new location, rotation, and scale over a defined period. When activated, the node takes the targeted SceneNode and seamlessly tweens its spatial data to match the provided Transform input over the specific amount of time defined by the numerical Duration input (measured in seconds).

<div dir="auto" id="bkmrk--1"><div dir="auto">---

</div></div>### ![Response_Node_Transform_Swap.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-transform-swap.png) Swap Nodes Transform

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/aiximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/aiximage.png)

**The Swap Nodes Transform node** instantly exchanges the complete spatial data—including location, rotation, and scale—between two distinct 3D objects in the scene. When activated, the node evaluates the targeted objects provided in the SceneNode A and SceneNode B inputs and simultaneously swaps their placements, rotations, and proportions.

<div dir="auto" id="bkmrk--3"><div dir="auto">---

</div></div>### Transform Node to Node (Animated)

Smoothly moves one or more objects so they end up exactly where a second object is — same position, rotation, and size — over a set number of seconds.

#### What it does

This node takes a target object and reads its full placement in the scene — its position, its rotation, and its size. It then animates your chosen object(s) so that, over the time you set, they smoothly travel to that same placement and come to rest matching the target exactly.

The movement is measured in absolute scene coordinates, so your object lands at the target’s real position in the scene regardless of any groups either one belongs to. The target object itself is never changed — it stays put, and only the object(s) you pointed at the **SceneNode** input move. The non-animated version of this node snaps the object into place instantly; this version eases it there over the **Duration** you choose.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to start the movement.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object (or objects) you want to move. Each one will travel to match the target.</td></tr><tr><td style="white-space: nowrap;">**ToNode**</td><td style="white-space: nowrap;">Scene node</td><td>The target object whose place you want to match. This object is read only — it doesn’t move.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How many seconds the smooth movement should take. Leave it at `2` for a gentle two-second glide, or set a smaller number to make it faster.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object(s) you moved, passed straight through so you can connect more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**ToNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same target object, passed through unchanged.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>The same number of seconds you set, passed through so you can reuse it.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-the-"><div dir="auto"><table><tbody><tr><td>**SceneNode** input</td><td>The `Drone` object</td></tr><tr><td>**ToNode** input</td><td>The `Landing Pad` object</td></tr><tr><td>**Duration** input</td><td>`3` (the drone glides onto the landing pad over three seconds)</td></tr><tr><td>**SceneNode** output</td><td>The `Drone`, now resting in the landing pad’s place — ready to chain into the next node</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-because-the-object-m">- Because the object matches the target’s rotation and size as well as its position, you can use an empty or hidden helper object as a “marker” to define exactly how and where something should arrive.
- Set **Duration** to `0` for an instant jump, or use the non-animated version of this node if you never want the smooth motion.

</div>

# SceneNode \ Transform \ Location

### [![Visual.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Y8Yvisual.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Y8Yvisual.png)Get Node Visual Location

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/z1Kimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/z1Kimage.png)

The **Get Node Visual Location** node enables the system to retrieve the exact X, Y, and Z coordinates of a SceneNode based on its absolute visual representation in the 3D scene.

Unlike standard location nodes that calculate position relative to a parent object, this node fetches the true visual position of the object within the environment, completely unaffected by the scene's parent-child hierarchy system.

<div dir="auto" id="bkmrk--0"><div dir="auto"><div _ngcontent-ng-c761594330="" class="container" id="bkmrk--32"><div _ngcontent-ng-c2150360127="" aria-busy="false" aria-live="polite" class="markdown markdown-main-panel stronger enable-updated-hr-color" dir="ltr" id="bkmrk--33" inline-copy-host=""></div></div></div></div>### [![Visual.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Y8Yvisual.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Y8Yvisual.png)Set Node Visual Location

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/R0Timage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/R0Timage.png)

The **Set Node Visual Location** node enables the system to instantly move a SceneNode to specific X, Y, and Z coordinates within the absolute visual space of the 3D scene. By directly altering where the object appears visually, this node completely bypasses any positional offsets or transformations that the object might normally inherit from its parent hierarchy.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/nVwimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/nVwimage.png)

In this example, an interaction is set up to match the positions of two independent objects.

<div dir="auto" id="bkmrk-upon-interacting-wit"><div dir="auto">1. Upon interacting with the "Ball" object, the **Node Triggered** event initiates the execution flow.
2. The **Get Node Visual Location** node extracts the true visual X, Y, and Z coordinates of the "Ball" in the scene.
3. These coordinate values are then fed directly into the X, Y, and Z inputs of a **Set Node Visual Location** node assigned to a "Target" object. This instantly moves the Target to the exact visual location of the Ball, regardless of how deeply nested either object is within the scene's hierarchy.

</div></div>### [![Visual.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Y8Yvisual.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Y8Yvisual.png)Set Node Visual Location (Animated)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/2Vlimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/2Vlimage.png)

The **Set Node Visual Location (Animated)** node enables the system to smoothly move a SceneNode to specific X, Y, and Z coordinates within the absolute visual space of the 3D scene over a set period.

Similar to the standard **Set Node Visual Location** node, this movement completely bypasses any positional offsets or transformations inherited from the object's parent hierarchy. However, this animated variant includes an additional **Duration** parameter. Instead of instantly snapping the object to the new coordinates, this node creates a smooth transition (tweening) from its current visual location to the target location over the specified number of seconds.

<div dir="auto" id="bkmrk--4"><div dir="auto">---

</div></div>### ![Response_Node_Location_FalltoSurface.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-location-falltosurface.png) Fall To Surface

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/SiBimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/SiBimage.png)

The F**all To Surface node** instantly repositions a specific 3D object directly onto the nearest 3D surface located immediately below it in the scene. When activated, the node takes the targeted SceneNode input and immediately updates its vertical placement to simulate a sudden, instantaneous drop, resting the object perfectly against the underlying geometry.

### ![Response_Node_Location_FalltoSurface.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-location-falltosurface.png) Fall To Surface (Animated)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/nXaimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/nXaimage.png)

The **Fall To Surface (Animated) node** functions similarly to the standard fall node, but instead of an instant drop, it smoothly transitions the 3D object down to the nearest underlying surface over a defined period. Once activated, the node takes the targeted SceneNode and seamlessly tweens its vertical descent until it rests on the geometry below, completing the fall animation over the exact amount of time specified by the numerical Duration input (measured in seconds).

<div dir="auto" id="bkmrk--7"><div dir="auto">---

</div></div>### [![Response_Node_Location_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-node-location-get.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Get Node Location

  
![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/lDximage.png)

The **Get Node Location** response obtains the X, Y, and Z coordinates of an object's location each time the event connected to it is triggered. Once the response is executed, the coordinates can be acquired through the **X**, **Y**, and **Z** ports.

####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/j1rimage.png)


<div dir="auto" id="bkmrk-%C2%A0-24"><div dir="auto"><div class="pointer-container" id="bkmrk-%C2%A0-26"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div></div>In this example, a **Get Node Location** response is used to obtain the X, Y, and Z coordinates of an object named Table once the user triggers the object named Activate. The coordinates are then stored in variables named X, Y, and Z, which can be connected to a variable writer to be displayed during the VR Experience.

<div dir="auto" id="bkmrk--12"><div dir="auto">---

</div></div>### [![Response_Node_Location_AnimatedSet.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-node-location-animatedset.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Set Node Location

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/fliimage.png)

The **Set Node Location** response enables the user to set the location of an object to specific X, Y, and Z coordinates by either typing in the numerical values or by attaching a variable node to those ports. Once the response is executed, the object's new location is applied using the provided coordinates.

####   


#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/w9timage.png)


<div dir="auto" id="bkmrk-%C2%A0-25"><div dir="auto"><div class="pointer-container" id="bkmrk-%C2%A0-27"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div></div>In this example, a **Set Node Location** response is used to assign the X, Y, and Z coordinates stored in variables named X, Y, and Z to an object named Pot once the user triggers the object named Activate. The object's new location is set based on these coordinates, allowing the updated position to be reflected during the VR Experience.

### [![Response_Node_Location_AnimatedSet.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-node-location-animatedset.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)Set Node Location (Animated)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/JRIimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/JRIimage.png)

The **Set Node Location (Animated)** node enables the system to smoothly move a SceneNode to a specific global coordinate in the 3D space over a set period. this node creates a seamless tweening effect from the object's current position to its new target destination

This differs significantly from the standard **Set Node Location** node, which instantly snaps or teleports the object to the new coordinates without any transition. The animated variant is ideal for creating moving platforms, sliding doors, or moving vehicles.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/a35image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/a35image.png)

In this example, an interactive elevator mechanism is created.

<div dir="auto" id="bkmrk-upon-interacting-wit-0"><div dir="auto">1. Upon interacting with the button object, the **Node Triggered** event initiates the execution flow.
2. The **Get Node Location** node is used to retrieve the current X, Y, and Z global coordinates of the "Elevator" object.
3. To move the elevator up, the Y-axis coordinate is passed into an **Add** node, where 5 units are added to its current value. The X and Z coordinates remain unchanged.
4. Finally, the **Set Node Location (Animated)** node applies these new coordinates to the elevator object. The **Duration** parameter is set to 3, meaning it will take exactly 3 seconds for the elevator to smoothly transition (tween) to its new position 5 units higher.

</div></div>
<div dir="auto" id="bkmrk--30"><div dir="auto">---

</div></div><div dir="auto" id="bkmrk--31"><div dir="auto">---

</div></div>## Local position

These behave like the position nodes above, but the X, Y, and Z values are measured relative to the object’s parent or group instead of the whole scene. If the object isn’t inside a group, the result is the same as the world versions.

### Get Node Location (Local)

Reads where an object currently sits, measured relative to its parent or group.

#### What it does

This node looks at an object in your scene and tells you its position as three numbers — X, Y, and Z — given in meters. The position is *local*, which means it is measured relative to the object’s parent or group: if that parent or group is moved, turned, or resized, the local position stays the same. (If the object has no parent or group, its local position and its position in the whole scene are the same.)

It only reads the position — it doesn’t move the object or change anything else in your scene. Use it whenever you need to know where something is so you can react to it, compare it, or feed the numbers into another node.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object whose position you want to read.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object passed straight through, so you can chain more nodes onto it.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The object’s position along the X axis, in meters.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The object’s position along the Y axis, in meters.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The object’s position along the Z axis, in meters.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-a-wr"><div dir="auto"><table><tbody><tr><td>**SceneNode** input</td><td>A wrench resting on a workbench</td></tr><tr><td>**X** output</td><td>`1.5`</td></tr><tr><td>**Y** output</td><td>`0.75`</td></tr><tr><td>**Z** output</td><td>`2`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-if-you-want-the-obje"><div dir="auto">- If you want the object’s position in the whole scene rather than relative to its parent or group, use the matching node without “(Local)” in its name.

---

</div></div>### Set Node Location (Local)

This node moves an object to a position you choose, measured relative to its parent or group.

#### What it does

You give it an object and three numbers — X, Y, and Z, in meters — and it places that object at exactly that position. The position is “local,” meaning it is measured relative to the object’s parent or group: if you later move, turn, or resize that parent or group, this object keeps the same local position and travels along with it. If the object has no parent or group, its local position is the same as its position in the whole scene.

Only the object you connect is moved — no other objects in the scene are affected. The change happens instantly. The node then hands the same object straight back out, along with the X, Y, and Z values you set, so you can connect it to more nodes.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to move.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The position along X, in meters. Leave at `0` for no change on this axis.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The position along Y, in meters. Leave at `0` for no change on this axis.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The position along Z, in meters. Leave at `0` for no change on this axis.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object, passed through so you can chain more nodes onto it.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X position you set, in meters.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y position you set, in meters.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z position you set, in meters.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-the-"><div dir="auto"><table><tbody><tr><td>**SceneNode** input</td><td>The crate you want to reposition</td></tr><tr><td>**X** input</td><td>`1.5`</td></tr><tr><td>**Y** input</td><td>`0.75`</td></tr><tr><td>**Z** input</td><td>`2`</td></tr><tr><td>**SceneNode** output</td><td>The same crate, now at that position, ready to chain</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-because-the-position"><div dir="auto">- Because the position is local, it is easiest to picture when the object sits inside a group: the numbers are measured from that group, not from the whole scene.
- To move the object using absolute scene coordinates instead, use the matching node without “(Local)” in its name.

---

</div></div>### Set Node Location (Local, Animated)

Smoothly moves a 3D object to a new spot over a set number of seconds, using a position measured relative to the object’s parent or group.

#### What it does

This node glides an object from where it is now to a new position you choose, given as X, Y, and Z values in meters. Instead of snapping there instantly, it animates the move over the number of seconds you set in **Duration**, so the object appears to travel to its new spot.

The position is “local,” meaning it is measured relative to the object’s parent or group rather than the whole scene. If you later move, turn, or resize that parent or group, this local position stays the same. (If the object has no parent or group, its local position is just its position in the scene.) Only the object you connect is affected — nothing else in the scene moves.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to start the movement.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The 3D object you want to move. You can connect more than one object to move them all the same way.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X position to move to, in meters.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y position to move to, in meters.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z position to move to, in meters.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How many seconds the smooth movement should take. Must be zero or more; `2` by default.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires to let the flow continue once the movement has been applied.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object (or objects) passed straight through, so you can chain more nodes onto it.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X position you asked for, passed through.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y position you asked for, passed through.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z position you asked for, passed through.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>The number of seconds you set, passed through.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-a-cr"><div dir="auto"><table><tbody><tr><td>**SceneNode** input</td><td>A crate object in your scene</td></tr><tr><td>**X** input</td><td>`1.5`</td></tr><tr><td>**Y** input</td><td>`0.75`</td></tr><tr><td>**Z** input</td><td>`2`</td></tr><tr><td>**Duration** input</td><td>`2` (the crate glides to its new spot over 2 seconds)</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-for-an-instant-jump-">- For an instant jump with no animation, use the non-animated version of this node instead.
- Set **Duration** to `0` for the fastest possible move.
- To move an object to a spot fixed in the whole scene rather than relative to its parent or group, use the world version of this node (the one without “(Local)” in its name).

</div>

# SceneNode \ Grab

### ![Response_Node_Grabbing_Ignore.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-grabbing-ignore.png) Ignore grabbing

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/zRnimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/zRnimage.png)

The **Ignore Grabbing node** explicitly prevents a specific 3D object from being picked up or interacted with by the user's hands during the VR experience. When activated, the node disables the grabbable state of the targeted SceneNode if set to True. This node is highly useful for complex models where you want to enforce realistic interactions by restricting grip points, allowing you to easily exclude certain parts of a grouped object from being grabbed without having to detach or separate the components from the main assembly.

##### Example:

In this example, we configure a screwdriver so that the user can only pick it up by its handle, preventing them from grabbing it awkwardly by the metal rod or tip:

If **Set Node Grabbable State node** is used on the handle part of the screw driver alone, only the handle will move along with the grabbing hand, leaving the rest of the screw driver's assembly in place. Instead, **Ignore Grabbing** node should be used to exclude unwanted parts from being grabbed:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/ccwimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/ccwimage.png)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/RgNimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/RgNimage.png)

1. A **Set Node Grabbable State** node is activated to make the entire "Philips Screw Driver" parent group grabbable.
2. The execution flow immediately continues into an **Ignore Grabbing** node.
3. The specific "Screw driver head" object is assigned to the SceneNode input, and the Ignore boolean is set to True.
4. As a result, the metal tip is excluded from being a valid grab target, forcing the user to grab the tool properly by its handle while still ensuring the entire screwdriver assembly moves together as one cohesive object in the user's hand.

---

### ![Response_Node_GrabbableSequenceSet.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-grabbablesequenceset.png) Set Grabbable Sequence

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/rDjimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/rDjimage.png)

The Set Grabbable Sequence node makes a specific 3D object interactively grabbable by assigning an animation sequence to it during the VR experience. Once activated, the node evaluates the targeted SceneNode and attaches the specified Sequence input, defining exactly how the object animates when grabbed and manipulated by the user. This versatile node can be used to add a sequence, dynamically switch between different sequences on the fly, or completely remove an existing sequence from a grabbable object before continuing the logic flow.

##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/68Bimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/68Bimage.png)

In this example, we use the Set Grabbable Sequence node to create a dynamic gear stick that changes states based on the user's interactions:

1. A **Set Grabbable Sequence** node is used to make a "Gear Stick" object grabbable and attaching an animation sequence that, when grabbed, shifts the gear to first.
2. A **Watch Boolean Expression** node continuously monitors a string variable named "Clutch".
3. When the "Clutch" variable is set to "pressed", the watch node passes its OnTrue execution path to a second **Set Grabbable Sequence** node, which changes the grabbable object's sequence to a "Shift Gear To Second" sequence.

##### Tip:

Using the Set Grabbable Sequence node without attaching a sequence will disable the grabbing state of an object.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/bkIimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/bkIimage.png)

Here, another **Watch Boolean Expression** node is used to monitor a variable called "engineStatus". When the "engineStatus" variable is set to "off", it triggers a **Set Grabbable Sequence** node targeting the gear stick, but this time with no sequence attached (Empty). Leaving the sequence input empty completely disables the grabbing interaction, turning the gear stick back into a still, non-interactable object.

---

### ![Response_Node_GrabbableSet.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-grabbableset.png) Set Node grabbable State

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/5Nvimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/5Nvimage.png)

**The Set Node Grabbable State node** evaluates the boolean Enable input to determine the targeted SceneNode's grabbable status—making the object fully grabbable by the user if set to True, or disabling grab interactions entirely to make it a static object if set to False.

# Resource

---

### ![Response_Resource_DeleteResource.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-resource-deleteresource.png) Delete Resource

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/lM9image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/lM9image.png)

The **Delete Resource** node enables the system to remove specific resources currently stored in the SimLab File Vault. This node simply requires the exact "FileName" of the target file as an input to execute the deletion. It outputs a "Success" boolean to confirm whether the specified file was successfully removed from the vault.

---

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/T47image.png) ](https://simlab-soft.com/help/uploads/images/gallery/2025-09/T47image.png) Download Resource

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-09/scaled-1680-/QXZimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-09/QXZimage.png)

The **Download Resource** node enables the system to download a specific file directly from the SimLab File Vault while a user is actively engaged inside a VR experience. This node requires the exact URL of the vault file to be linked into the node's input. Upon execution, it retrieves the file and provides a "Success" status alongside the downloaded "FileName" to be used in subsequent logic.

For more information, refer to SimLab Vault tutorial below:

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/ZrGcO0HZmDI" width="560"></iframe>

---

### ![Response_Resource_GetPathFromResource.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-resource-getpathfromresource.png) Get Path From Resource

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/rPtimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/rPtimage.png)

The **Get Path From Resource** node enables the system to retrieve the exact URL or local file path of a specific resource or file. This node requires the exact "FileName" of the target file as an input.

---

### [![Response_Resource_SaveVRPackage.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-resource-savevrpackage.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-03/response-resource-savevrpackage.png)Save VRPackage

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/jgoimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/jgoimage.png)

The **Save VRPackage** node enables the system to save the current, active VR experience as a standalone `.vrpackage` file, directly from within the VR session itself. It requires a "FileName" to name the new package and includes a "User" dropdown (e.g., "Host Only") to specify which user is authorizing the save. It outputs a "Success" boolean and the final "FileName" to confirm the action.

###   


---

### ![Response_Resource_UploadMediaFromUser.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-resource-uploadmediafromuser.png) Upload Media From User

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/yl5image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/yl5image.png)

The **Upload Media From User** node functions similarly to the standard **Upload Resource** node by sending files to the SimLab File Vault via a designated URL. This node is specifically designed for multiplayer VR Collaboration environments.

It allows an administrator or host to target a specific user (via the "User" dropdown) and upload a file from *that user's* local device directly to the central File Vault. This is crucial for sharing media when a file exists only on an individual participant's machine and not on the host's device. Like the standard upload node, it outputs a "Success" boolean.

---

###   


### ![Response_Resource_UploadToURL.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-resource-uploadtourl.png) Upload Resource

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Zkrimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Zkrimage.png)

The **Upload Resource** node enables the system to send and save resources to the SimLab File Vault during a live VR experience. This node requires the destination URL for the file vault, as well as the assigned "FileName" for the file being uploaded and outputs a "Success" boolean.

For more information, refer to SimLab Vault tutorial below:

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/hUZvEgmD5Ls" width="560"></iframe>

# External Connection \ WebSocket

### [![OpenExternalConnection.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/openexternalconnection.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Open External Connection

SimLab Composer 14 introduces WebSocket support, enabling seamless integration with external systems allowing it to work with external hardware, co-simulation engines, and websites, unlocking numerous possibilities.

The WebSocket nodes (Open External Connection, Send Message, and <span style="text-decoration: underline; color: rgb(35, 111, 161);">[On Message Received](https://simlab-soft.com/help/books/dynamic-training-builder-nodes-manual/page/on-message-received)</span>) are exclusively available in the Ultimate Edition.

The **Open External Connection** node enables the opening of a WebSocket connection to an external system. When the **Auto Handle Lua** is set to **true**, incoming messages containing Lua scripts will be automatically executed. This allows for real-time interaction between SimLab Composer and external systems, such as co-simulation engines or hardware, with the ability to dynamically execute Lua code as part of the interaction.

[![Screenshot 2025-02-02 162338.jpg](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/screenshot-2025-02-02-162338.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/screenshot-2025-02-02-162338.jpg)

**Input Ports:**

- Execute
- URL: WebSocket URL that includes the server IP address, port, channel (optional). Example: ws://server1.simlab-soft.com:8765/robots\_1
- Auto Handle Lua: Incoming messages containing Lua scripts will automatically execute those scripts If enabled (True). <div class="container_b7e1cb" id="bkmrk--25"><div class="visualMediaItemContainer_f4758a"><div class="oneByOneGrid_f4758a oneByOneGridSingle_f4758a"><div class="mosaicItem__6c706 mosaicItemNoJustify__6c706 mosaicItemMediaMosaic__6c706 hideOverflow__6c706"><div class="imageContent__0f481 embedWrapper_b7e1cb itemContentContainer_f4758a mosaicItemContent__6c706">  
    </div></div></div></div></div>

**Output Ports:**

- Execute
- URL
- Auto Handle Lua

---

###   
[![MessageSent.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/messagesent.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Send Message

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/h5mimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/h5mimage.png)

The **Send Message** node allows you to communicate with the WebSocket server by sending messages. It is essential to ensure that the message format follows the protocol that the server and other clients can process. This node enables real-time interaction with external systems, making it possible to transmit data or commands to connected servers or clients.

**Input Ports:**

- Executive
- URL: WebSocket URL that includes the server IP address, port, and channel (optional). Example: ws://server1.simlab-soft.com:8765/robots\_1
- Message

**Output Ports:**

- Execute
- URL
- Message

# Media

### ![Response_Node_MessageBoxShow.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-messageboxshow.png) Message Box \\ Show Message Box

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/EC3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/EC3image.png)

The **Show Message Box node** displays a floating text panel directly above a specific 3D object in the VR scene. Once activated, the node takes the targeted SceneNode input and generates a visible UI element containing the text strings provided in the Title and Body inputs, to provide contextual information or instructions to the user.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/lYyimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/lYyimage.png)

### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/7O8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/7O8image.png)

###   


###   


---

###   


### ![Response_Node_MessageBoxHide.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-messageboxhide.png) Message Box \\ Hide Message Box

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/3urimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/3urimage.png)

The **Hide Message Box node** removes an active text panel currently displayed above a specific 3D object. When activated, the node takes the targeted SceneNode input and immediately dismisses its attached message box from the user's view.

---

### [![Response_Node_Capture_Picture.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-node-capture-picture.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Capture Picture

[![aM3image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/N18am3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/N18am3image.png)

<div class="pointer-container" id="bkmrk-%C2%A0-12"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>The **Capture Picture node** is used to capture an image from a camera within the scene, and the captured image can then be displayed on a 3D object within the scene. This allows the user to take snapshots and show them in the VR environment, such as displaying a captured image on a screen or other surface.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/5wEimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-09/Xn9image.png)

A **Surveillance Monitor** is first created to display the captured images. This monitor is then attached to the VR camera.

[![Add_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/cT8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this example, the **Capture Picture Node** is used to capture an image on a picture frame model when the user triggers the Activate event. Before that, the Cast SceneNode is used to identify the picture frame as a 3D object, as the Capture Picture Node only works with 3D objects.

---

### ![Response_WebBrowser_SetURL.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/response-webbrowser-seturl.png) Set Web Browser URL

![web URL.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/web-url.png)

The **Set Web Browser URL** node sets the URL for a web browser within the VR Experience. This node enables users to open and navigate to a specified webpage, making it possible to display web content like videos or instructional resources directly within the VR environment.

<div class="mb-2 flex gap-3 empty:hidden -ml-2" id="bkmrk--13"><div class="items-center justify-start rounded-xl p-1 z-10 -mt-1 bg-token-main-surface-primary screen-arch:mt-1 md:absolute flex"><div class="flex items-center"><button aria-label="Read aloud" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="voice-play-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Copy" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="copy-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Edit in canvas" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex items-center pb-0">  
</div></div></div></div><div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--14"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8"><svg class="icon-md" fill="none" height="41" role="img" viewbox="0 0 41 41" width="41" xmlns="http://www.w3.org/2000/svg"></svg>  
</div></div>#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/G1Pimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/G1Pimage.png)


![web URL PLANE.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/Bkxweb-url-plane.png)

In this example, the **Set Web Browser URL** node is used to open the SimLab website. The **Node Triggered** event is activated when the user triggers an object named "activate." As soon as the object is triggered, the **Set Web Browser URL** node is triggered, setting the URL to the SimLab website. The website then loads and is displayed on a web browser plane within the VR environment.

> [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1298557994208071701/1312684216776916994 "Tutorial is available on SimLab VR Discord server")

<div class="mb-2 flex gap-3 empty:hidden -ml-2" id="bkmrk--18"><div class="items-center justify-start rounded-xl p-1 flex"><div class="flex items-center"><button aria-label="Read aloud" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="voice-play-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Copy" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="copy-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex"><button aria-label="Good response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="good-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><button aria-label="Bad response" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary" data-testid="bad-response-turn-action-button"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button>  
</div><button aria-label="Edit in canvas" class="rounded-lg text-token-text-secondary hover:bg-token-main-surface-secondary"><svg class="icon-md-heavy" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg></button><div class="flex items-center pb-0"><svg class="icon-md" fill="none" height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"></svg>  
</div><button aria-expanded="false" aria-haspopup="menu" class="cursor-pointer h-[30px] rounded-md px-1 text-token-text-secondary hover:bg-token-main-surface-secondary" data-state="closed" id="bkmrk--20" type="button"></button></div></div></div>

# Media \ Variable Writer \

### ![Color.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/color.png) Get/Set Variable Writer Color

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-05/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-05/image.png)

The **Set / Get Variable Writer Color** nodes are used to control the color of the text displayed by a Variable Writer in the VR environment. The Set node allows you to change the text color dynamically based on events or conditions, while the Get node retrieves the current color of the Variable Writer. This is useful for customizing the visual appearance of displayed values, such as indicating status or drawing attention to changes.

---

### ![Prefix.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/prefix.png) Get/Set Variable Writer Prefix:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-05/scaled-1680-/stCimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-05/stCimage.png)

The **Set / Get Variable Writer Prefix** nodes are used to modify or retrieve the prefix text displayed before the variable value in a Variable Writer. The Set node allows you to add custom text before the value, such as labels or units, while the Get node retrieves the current prefix. This helps provide context to the displayed value, making it clearer for the user.

---

### [![Suffix.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/JqVsuffix.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/JqVsuffix.png) Get/Set Variable Writer Suffix:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-05/scaled-1680-/30Kimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-05/30Kimage.png)

The **Set / Get Variable Writer Suffix** nodes are used to modify or retrieve the suffix text displayed after the variable value in a Variable Writer. The Set node allows you to add custom text after the value, while the Get node retrieves the current suffix. This helps make the displayed value more informative and user-friendly.

### ![Response_VariableWriter_Value_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-variablewriter-value-get.png) Get Variable Writer Value

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/YYCimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/YYCimage.png)

The **Get Variable Writer Value** node retrieves the pure data value from a designated **SceneNode** (the target Variable Writer object) and outputs this core **Value** for use in your logic.

###   


### ![Response_VariableWriter_Value_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-variablewriter-value-set.png) Set Variable Writer Value

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/F5iimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/F5iimage.png)

The **Set Variable Writer Value** node dynamically updates the core data of a target **SceneNode** (the Variable Writer object). By inputting a new string or numerical **Value**, the node overrides the writer's pure value while keeping any existing prefixes and suffixes perfectly intact.

### ![Response_Scene_Font_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-scene-font-set.png) Set Scene Font

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/W3Ximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/W3Ximage.png)

The **Set Scene Font** node updates the typography globally by changing the font of every Variable Writer object currently present in the VR scene. This node requires the exact **FileName** of a TrueType Font (`.ttf`) as its input. To function correctly, the designated `.ttf` file must first be imported into your project via the Resource Management tab in SimLab Composer.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/sEximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/sEximage.png)

###   


<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/rThSaw78sKU" width="560"></iframe>

### ![Response_VariableWriter_Font_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-variablewriter-font-set.png) Set Variable Writer Font

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Dimimage.png)The **Set Variable Writer Font** node allows for targeted typography changes by updating the font of a single, specific Variable Writer rather than the entire environment. By assigning the target **SceneNode** and providing the **FileName** of a valid `.ttf` font file (previously imported through the Resource Management tab), this node applies the new text style exclusively to the selected object, leaving all other text in the scene unaffected.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/l1Oimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/l1Oimage.png)

---

### [![variable.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/25Jvariable.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/25Jvariable.png) Set Variable Writer Variable:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-05/scaled-1680-/Lvcimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-05/Lvcimage.png)

The **Set Variable Writer Variable** node is used to assign or change the variable displayed by an existing Variable Writer. This allows you to update the displayed content dynamically during the VR experience by switching the linked variable at any time.

# Media \ Dynamic Menu

### ![Response_Node_DynamicMenu_Visibility_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-dynamicmenu-visibility-set.png) Set Dynamic Menu Visibility

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/LmLimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/LmLimage.png)

The **Set Dynamic Menu Visibility** node controls whether dynamic menus (specifically used with the Objects Menu and Group Menus add-ons) are shown or hidden during a VR experience, using a boolean toggle where **True** displays the menu and **False** hides it.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/8NtfNkBr_Z0" width="560"></iframe>

---

# Media \ Sound

### ![Response_Sound_RecordSound.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-sound-recordsound.png) Record Sound

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/F1Uimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/F1Uimage.png)

The **Record Sound** node initiates an audio recording session within the VR experience. This node utilizes a **User** dropdown parameter to determine whether the system captures microphone audio exclusively from the host or from all participating users. It outputs a **Success** boolean when the recording successfully starts.

---

### ![Response_Sound_File_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-sound-file-set.png) Set Sound File

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/2umimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/2umimage.png)

The **Stop Sound Recording** node halts an active audio recording session. This node requires a specified target **User** and an exact **FileName**. Upon execution, it stops the capture process and stores the resulting audio file directly into the project's Resource Management tab under the provided name

---

### ![Response_Sound_Volume_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/CZZresponse-sound-volume-set.png) Set Sound Volume

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/RDGimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/RDGimage.png)

The **Set Sound Volume node** is used to adjust the audio playback level of a specific 3D sound object within the scene. The numerical Volume input operates strictly within a range of 0 (muted) to 4 (maximum amplification)

---

### ![Response_Sound_PlayPause.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-sound-playpause.png) Sound Play

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/b8Gimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/b8Gimage.png)

The **Sound Play node** controls the playback of the audio file stored within a specific 3D sound object. When activated, the node uses the boolean Play input to determine the action for the targeted Sound Node—triggering the sound to start playing from the start of the audio file, or stopping the audio and seeking to the start.

---

### ![Response_Sound_Seek.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-sound-seek.png) Sound Seek

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/09limage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/09limage.png)

The **Sound Seek node** instantly jumps to a specific moment within the audio file attached to a 3D sound object. When activated, the node takes the targeted Sound Node and moves its playback position to the exact duration specified by the numerical Time input, measured in seconds.

---

### ![Response_Sound_Toggle.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-sound-toggle.png) Sound Toggle

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/rxDimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/rxDimage.png)

The **Sound Toggle node** easily switches between playing and pausing a specific 3D sound object in the scene. Once activated, the node evaluates the targeted Sound Node and automatically reverses its current playback status—pausing it if it is currently playing, or playing it if it is currently paused.

---

### ![Response_Sound_StopSoundRecording.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-sound-stopsoundrecording.png) Stop Sound Recording

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/yRAimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/yRAimage.png)

The **Set Sound File** node dynamically attaches or updates the audio source of a designated **Sound Node** object in the scene. This node requires the exact **FileName** of an audio file previously imported into the Resource Management tab, strictly including its file extension (for example, "welcome.mp3"). It outputs a **Success** boolean to confirm that the sound file was located and attached properly.

# Media \ Video

### ![Response_Video_File_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-video-file-set.png) Set Video File

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/W9Ximage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/W9Ximage.png)

The **Set Video File** node allows you to dynamically attach or change the media source of a specific Video Node within your scene. By assigning the target **Video Node** and inputting the exact **FileName** of your desired video (such as an `.mp4`), this node updates the object's media. For this to function correctly, the video file must first be imported into your project through the Resource Management tab. It also outputs a **Success** boolean to verify that the file was found and loaded.

##### Example

##### [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/tRGimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/tRGimage.png)

In this example, an interaction is set up to load a short film onto a TV screen and immediately begin playback.

1. Upon interacting with the "Play Button" object, the **Node Triggered** event initiates the execution flow.
2. The **Set Video File** node is executed, assigning the previously imported video file "Short Film.mp4" directly to the "TV" video node object.
3. Once the file is successfully attached, the execution flow passes to the **Video Play** node (with the Play toggle set to **True**), which instantly starts playing the newly loaded short film on the TV screen.

---

### Set Video URL

Points a video object in your scene at a new video, so it plays from the web address (or file path) you give it.

#### What it does

This node takes one of the video objects in your scene and tells it which video to play, using the address you provide in the URL. As soon as it runs, the video object switches to that new source — handy for showing different clips on the same screen depending on what the user does.

It only works on a video object; if you point it at any other kind of scene object, nothing changes and the result simply reports that it didn’t succeed. The node hands the same video object straight back out, so you can keep working with it, and it tells you whether the change went through.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Video Node**</td><td style="white-space: nowrap;">Scene node</td><td>The video object in your scene whose video you want to change. It must be a video object — other kinds of objects are ignored.</td></tr><tr><td style="white-space: nowrap;">**URL**</td><td style="white-space: nowrap;">Text</td><td>The web address (or path) of the video to play, for example `https://videos.example.com/safety-intro.mp4`. You can leave this empty to clear the current video.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Video Node**</td><td style="white-space: nowrap;">Scene node</td><td>The same video object you passed in, so you can connect it to the next node.</td></tr><tr><td style="white-space: nowrap;">**URL**</td><td style="white-space: nowrap;">Text</td><td>The video address you supplied, passed straight through.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>True if the video object accepted the new video, false if it didn’t (for example, if the object isn’t a video).</td></tr></tbody></table>

#### Example

<table id="bkmrk-video-node-input-the"><tbody><tr><td>**Video Node** input</td><td>The `Lobby Screen` video object in your scene</td></tr><tr><td>**URL** input</td><td>`https://videos.example.com/safety-intro.mp4`</td></tr><tr><td>**Success** output</td><td>`true`</td></tr></tbody></table>

#### Tips

- Make sure the object you connect is actually a video object — if it isn’t, the change is skipped and Success comes back false.
- Check the Success output before moving on, so you can show a fallback or message if the video couldn’t be loaded.

---

### ![Response_Video_PlayPause.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-video-playpause.png) Video Play

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/VFGimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/VFGimage.png)

The **Video Play** node provides direct control over the playback of a **Video Node** through a boolean **Play** input. Setting the toggle to **True** starts the video, while **False** stops it.

### ![Response_Video_Seek.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-video-seek.png) Video Seek

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/nfcimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/nfcimage.png)

The **Video Seek** node immediately moves the playback of the target **Video Node** to a specific **Time** defined in seconds. It enables precise navigation to any timestamp within the video's total duration.

### ![Response_Video_Toggle.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-video-toggle.png) Video Toggle

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/cLoimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/cLoimage.png)

The **Video Toggle** node switches the playback state of the assigned **Video Node** between playing and paused. Each execution reverses the current state of the video material, making it ideal for simple play/pause button interactions.

# Cloud

### [![Response_Cloud_get_Attribute.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-cloud-get-attribute.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Get Cloud Attribute

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/plqimage.png)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--7"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8">  
</div></div></div></div></div>The **Get Cloud Attribute** node enables the user to retrieve saved progress for a specific VR Experience by assigning the attribute in the Attribute Name field. The progress can be saved for either the scene, the user, or both. Once the node is executed, the retrieved value can be acquired through the **Result** port.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/hALimage.png)

In this example, a **Get Cloud Attribute** node is used to retrieve stored data from Cloud. When the user enters the object named FinishLine, the object named Scoreboard will be shown. The data saved for this specific scene for all users is retrieved and stored in a variable named Scoreboard, which can then be displayed during the VR Experience.

---

### [![Response_Cloud_get_Attribute.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/response-cloud-get-attribute.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Set Cloud Attribute

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/JyBimage.png)

<div class="flex-shrink-0 flex flex-col relative items-end" id="bkmrk--15"><div><div class="pt-0"><div class="gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full"><div class="relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8">  
</div></div></div></div></div>The **Set Cloud Attribute** node enables the user to store data for a specific VR Experience by assigning the attribute in the Attribute Name field then set the value of it. the data can be stored for either the user, the scene, or both. Once the node is executed, the specified data is saved accordingly.

#### Example

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/orJimage.png)

In this example, a **Set Cloud Attribute** node is used to store data in Cloud. When the user enters the object named **FinishLine**, the value of the variable **Time** will be converted to String and stored under the **attribute named Time** for the **Scene Only**, meanwhile the value of the variable **Coins\_Count** will be converted to String and then stored under **the attribute Score** for the **User Only**.

**Note:** To retrieve the Cloud data, the experience must be run from a logged-in account in SimLab VR Viewer.

---

## HTTP Requests

These two nodes let your scene talk to a web service over the internet — for example to fetch some information from a server, send a result to one, or call an online tool. You give the node a web address and a few details about the request; it contacts the server, waits for the reply, and hands you back whatever the server sent. The two nodes are identical except for one thing — **the form the reply comes back in**:

- **Http Request** — gives the reply back as a **JSON object**. Use this when the server answers with JSON.
- **Http Request (String)** — gives the reply back as **plain text**. Use this for raw text, or when you'd rather read the text yourself later.

### Things to know before you start

These points apply to **both** nodes.

#### They wait for the request to finish before carrying on

Talking to a server isn't instant — it can take a moment for the reply to come back. These nodes handle that waiting for you. The node's **Execute** output does *not* fire the moment the request is sent; it fires only once the request has finished — that is, once the server has answered *or* the attempt has failed. So **the nodes you wire after this one run when the request comes back**, not the instant it goes out, and you don't need to add any delay of your own. The rest of your scene keeps running in the meantime — only this branch waits.

Because the **Execute** output fires whether the request succeeded or not, always check the result before trusting the reply — see below.

#### Always check Success before using the reply

A request can go wrong for many reasons — a mistyped address, no internet connection, or the server itself reporting a problem (such as “not found”). That is what the **Success** output is for. It is **Yes** only when the server was reached *and* answered normally; otherwise it is **No** and the **Response** comes back empty. Always send **Success** into a **Branch** node and only use the **Response** on the “Yes” side.

#### The request, in four parts

Every request you send is built from the same few pieces. You set these on the inputs of both nodes:

- **Verb** — what kind of request it is, chosen from a drop-down. **GET** (the default) asks the server *for* something and is by far the most common. **POST** sends new information to the server; **PUT** and **PATCH** update something that already exists; **DELETE** removes something. (**REQUEST** is a general-purpose option for unusual cases.) If you are just reading data, leave this on GET.
- **URL** — the web address to contact, for example `https://api.example.com/status`. This is required.
- **Header** (optional) — extra details about the request, given as a JSON object of name-and-value pairs (text values). It is most often used to pass a key or token that proves who you are, such as `{"Authorization": "Bearer abc123"}`.
- **Body** (optional) — the information you are sending *to* the server, given as a JSON object. It is used with POST, PUT, and PATCH. A GET request never carries a body, so anything you connect here is ignored when the verb is GET.

#### Which one should I use?

Most modern web services answer with **JSON**. If yours does, use **Http Request** and you'll get a JSON object you can read straight away with the **JSON Object** nodes. If the server sends back plain text, or you aren't sure of the format and want the exact text, use **Http Request (String)**. You can always turn text into a JSON object afterwards with **Create Json Object From String**.

### Http Request

Sends a request to a web address and gives you the server's reply as a **JSON object**.

#### What it does

This is the node to reach for when the server answers with JSON, which most web services do. It contacts the address you give it, waits for the reply, and reads that reply into a **JSON object** — so you can pull values straight out of it with the **Get Json Object Field** nodes on the **JSON Objects** page. Only the reply's content comes back; this node doesn't hand you the technical status number separately. Remember to check **Success** first: if the request failed, or the reply wasn't valid JSON, Success is **No** and the Response is empty.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Verb**</td><td style="white-space: nowrap;">Choice</td><td>The kind of request: GET, POST, DELETE, PUT, REQUEST, or PATCH. Defaults to **GET**.</td></tr><tr><td style="white-space: nowrap;">**URL**</td><td style="white-space: nowrap;">Text</td><td>The web address to contact.</td></tr><tr><td style="white-space: nowrap;">**Header**</td><td style="white-space: nowrap;">JSON object</td><td>*Optional.* Extra request details as name-and-value pairs, such as an authorization key.</td></tr><tr><td style="white-space: nowrap;">**Body**</td><td style="white-space: nowrap;">JSON object</td><td>*Optional.* The information to send to the server. Used with POST, PUT, and PATCH; ignored for GET.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the request finishes — whether it succeeded or not.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>**Yes** if the server was reached, answered normally, and the reply could be read as JSON; **No** otherwise.</td></tr><tr><td style="white-space: nowrap;">**Response**</td><td style="white-space: nowrap;">JSON object</td><td>The server's reply, as a JSON object. Empty when **Success** is No.</td></tr></tbody></table>

#### Example

<table id="bkmrk-verb-input-get-url-i"><tbody><tr><td style="white-space: nowrap;">**Verb** input</td><td>`GET`</td></tr><tr><td style="white-space: nowrap;">**URL** input</td><td>`https://api.example.com/weather?city=Dubai`</td></tr><tr><td style="white-space: nowrap;">**Header** input</td><td>`{"Accept": "application/json"}` — optional</td></tr><tr><td style="white-space: nowrap;">**Success** output</td><td>**Yes**</td></tr><tr><td style="white-space: nowrap;">**Response** output</td><td>`{"city": "Dubai", "temperature": 41, "unit": "C"}`</td></tr></tbody></table>

#### Tips

- **Check Success first.** Wire **Success** into a **Branch** node and only read the **Response** when it's Yes. A server error such as “not found” counts as No.
- **Read one value out.** Wire the **Response** into a **Get Json Object Field** node with the field name to pull a single value (for example `temperature`) out of the reply.
- **Sending data?** Fill in the **Body** and choose **POST** (or PUT / PATCH). When a body is sent, the request is automatically marked as JSON for you.
- **Reply isn't JSON?** If the server sends plain text rather than JSON, use **Http Request (String)** below instead.

### Http Request (String)

Sends the same kind of request, but gives you the server's reply as **plain text**.

#### What it does

Works exactly like **Http Request**, with one difference: the reply comes back as a piece of **text**, exactly as the server sent it, instead of being read into a JSON object. Use this when the server returns plain text, when the reply isn't JSON, or when you simply want the raw text to store, display, or read yourself later. As with the other node, check **Success** first; if the request failed, Success is **No** and the text comes back empty.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Verb**</td><td style="white-space: nowrap;">Choice</td><td>The kind of request: GET, POST, DELETE, PUT, REQUEST, or PATCH. Defaults to **GET**.</td></tr><tr><td style="white-space: nowrap;">**URL**</td><td style="white-space: nowrap;">Text</td><td>The web address to contact.</td></tr><tr><td style="white-space: nowrap;">**Header**</td><td style="white-space: nowrap;">JSON object</td><td>*Optional.* Extra request details as name-and-value pairs, such as an authorization key.</td></tr><tr><td style="white-space: nowrap;">**Body**</td><td style="white-space: nowrap;">JSON object</td><td>*Optional.* The information to send to the server. Used with POST, PUT, and PATCH; ignored for GET.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the request finishes — whether it succeeded or not.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>**Yes** if the server was reached and answered normally; **No** otherwise.</td></tr><tr><td style="white-space: nowrap;">**Response**</td><td style="white-space: nowrap;">Text</td><td>The server's reply, as plain text. Empty when **Success** is No.</td></tr></tbody></table>

#### Example

<table id="bkmrk-verb-input-get-url-i-0"><tbody><tr><td style="white-space: nowrap;">**Verb** input</td><td>`GET`</td></tr><tr><td style="white-space: nowrap;">**URL** input</td><td>`https://api.example.com/version`</td></tr><tr><td style="white-space: nowrap;">**Success** output</td><td>**Yes**</td></tr><tr><td style="white-space: nowrap;">**Response** output</td><td>`v2.4.1`</td></tr></tbody></table>

#### Tips

- **Check Success first.** Wire **Success** into a **Branch** node and only read the **Response** when it's Yes. A server error such as “not found” counts as No.
- **Good for non-JSON replies.** Plain text, a version number, a short status word, or a line of CSV all come back cleanly as text.
- **Text that's really JSON?** If the reply happens to be JSON and you want to read fields out of it, pass the **Response** into **Create Json Object From String** — or just use **Http Request** above, which does that step for you.

### Related

- **JSON Objects** — build the **Header** and **Body** objects you send, and read values out of the reply from **Http Request**.
- **Create Json Object From String** — turn the text from **Http Request (String)** into a JSON object.
- **Branch** — use the **Success** output to decide what happens next.

# Scene

### [![Response_Scene_Load.png](https://simlab-soft.com/help/uploads/images/gallery/2024-11/response-scene-load.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Load Scene

[![Screenshot 2024-11-04 160632.png](https://simlab-soft.com/help/uploads/images/gallery/2024-11/scaled-1680-/w6Gimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The **Load Scene node** is used to teleport between different scenes within your VR Experience. Enhancing the overall immersion and interactivity of the experience.

####   


#### Example

[![Add_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-11/scaled-1680-/WFMimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this example, the **Load Scene Node** is used to transition the user from one scene to another. This node facilitates changing scenes, allowing for a dynamic experience as users navigate through different environments within the VR application.

> [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[ Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1307969317068869664 "Tutorial is available on SimLab VR Discord server")

---

### [![Response_Scene_Home.png](https://simlab-soft.com/help/uploads/images/gallery/2024-11/response-scene-home.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Home Scene

[![Screenshot 2024-11-04 160632.png](https://simlab-soft.com/help/uploads/images/gallery/2024-11/screenshot-2024-11-04-160632.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The **Home Scene node** enables users to return to the initial scene of the VR Experience. This node provides a straightforward way for users to reset the VR Experience to the starting point, ensuring a user-friendly navigation experience.

####   


#### Example

[![Add_Example2.jpg](https://simlab-soft.com/help/uploads/images/gallery/2024-11/scaled-1680-/image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-example.jpg)

In this example, the **Home Scene Node** is used to return the user to the main scene when the trigger event occurs. This allows you to teleport back to the primary environment, enhancing the user experience by providing a clear and intuitive way to return to the starting point.

> <span style="color: rgb(0, 0, 0);">[![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[ Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1307969317068869664 "Tutorial is available on SimLab VR Discord server")</span>

---

### [![Response_Scene_Home.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/response-scene-import.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Import Scene

[![Screenshot 2024-11-04 160632.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/Mg3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The **Import Scene** node is used to load an external scene into the current VR Experience. This allows users to dynamically bring in additional environments, objects, or elements as needed during runtime.

####   


#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/xguimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-01/xguimage.png)[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-01/scaled-1680-/NMTimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-01/NMTimage.png)

In this example, the **Import Scene node** is used to load a car model into the scene when the "Import" object is triggered. The Node Triggered event detects user interaction and executes the Import Scene node, which then loads the specified car model from an external VR package file. This allows the car to appear dynamically within the VR environment.

---

### Reload Scene

Restarts the scene that is currently running, bringing it back to the way it was at the start.

#### What it does

When this node runs, it reloads the current scene from the beginning. Everything in the scene starts over — objects return to their starting positions and the scene plays as if it had just been opened.

It’s a handy way to give the user a “start over” or “try again” option, such as a reset button that puts a training exercise back to the beginning.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output — for example, from a button click or another action that should restart the scene.</td></tr></tbody></table>

#### Outputs

This node has no outputs.

#### Example

<table id="bkmrk-execute-input-wired-"><tbody><tr><td>**Execute** input</td><td>Wired from a “Restart” button so that clicking it starts the scene over from the beginning.</td></tr></tbody></table>

#### Tips

- Reloading starts the scene over completely, so any progress the user has made will be lost — use it when you want a clean fresh start.
- This node has no Execute output, so it’s always the last step in its chain — nothing runs after it.

---

## Enterprise VR Packages

An **Enterprise VR Package** is a complete VR experience saved as a single, **protected** `.evrpackage` file. These packages are **encrypted**, so only a viewer that has the matching enterprise key can unlock and open them, and creating them is part of a SimLab **Enterprise** licence. The node below brings one of these packages into the running Viewer and adds it to the **main menu**, ready to be opened.

### Add Enterprise VR Package To Viewer

Fetches an Enterprise VR Package from a web address, unlocks it, and adds it to the Viewer's main menu.

#### What it does

Give this node the address of an Enterprise VR Package (an `.evrpackage` file) and, while your experience is running, it downloads the package, unlocks it with its enterprise key, and adds it to the Viewer's **main menu** — the list of experiences someone can open. The package is stored **locally** on the device, so from then on it can be opened from the menu like any other entry.

**It does not put anything into the scene that's currently playing.** This node makes a whole package available to open from the menu; it does not drop models or other content into the running scene. If what you want is to bring content *into* the current scene, use the **Import** node instead — that's what it's for.

Because these packages are protected, this only works with genuine Enterprise VR Packages, and the Viewer has to be able to unlock the file. The **Success** output tells you whether the package was added.

#### It waits until the package is ready

Downloading a package and unlocking it isn't instant — it takes a moment, and it happens quietly in the background so the rest of your experience keeps running. This node handles that waiting for you. Its **Execute** output does *not* fire the moment the node runs; it fires only once the package has been added to the menu *or* the attempt has failed. So **the nodes you wire after this one run when the package is ready**, not the instant it's requested, and you don't need to add any delay of your own. Because **Execute** fires whether it worked or not, always check **Success** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**URL**</td><td style="white-space: nowrap;">Text</td><td>The web address of the Enterprise VR Package (an `.evrpackage` file) to add. A local file path on the device also works.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished — whether the package was added or not.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>**Yes** if the package was downloaded, unlocked, and added to the main menu; **No** otherwise — for example the address was wrong, the download couldn't be completed, or the package couldn't be unlocked.</td></tr></tbody></table>

#### Example

<table id="bkmrk-url-input-https%3A%2F%2Fen"><tbody><tr><td style="white-space: nowrap;">**URL** input</td><td>`https://enterprise.example.com/packages/assembly-training.evrpackage`</td></tr><tr><td style="white-space: nowrap;">**Success** output</td><td>**Yes** — the package now appears in the Viewer's main menu</td></tr></tbody></table>

#### Tips

- **It adds to the menu, not the scene.** The package becomes available to open from the Viewer's main menu. To bring content *into* the scene that's currently playing, use the **Import** node instead.
- **Enterprise VR Packages only.** This works only with protected `.evrpackage` files. Ordinary files won't be added — use **Import** for those.
- **The Viewer must be able to unlock it.** These packages are encrypted. If the file is damaged, its key isn't available, or there's no connection to download it, **Success** comes back **No** and nothing is added.
- **Check Success first.** Wire the **Success** output into a **Branch** node so the rest of your experience only relies on the package on the “Yes” side.
- **No need to add a delay.** The node already waits for the download and unlock to finish before its **Execute** output fires, so the nodes after it run at the right time on their own.

---

## Scene actions

These nodes work with the experience that’s currently running — finding out which scene is open, returning to the home screen, saving how the scene looks, and sending the scene back to the cloud. None of them change what’s in your scene; they read from it or move the viewer somewhere else.

### Get Running Scene GUID

Gives you the unique ID of the scene that is currently running.

#### What it does

Every scene (VR package) has its own unique ID — a long piece of text that no other scene shares. This node hands you that ID for the scene that is open and running right now.

It only reads the ID; it doesn’t change anything about the scene. You can use the result to tell scenes apart, to label saved data so you know which scene it came from, or to pass along to other nodes that need to know which scene is loaded.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The unique ID of the scene that is currently running, as text.</td></tr></tbody></table>

#### Example

<table id="bkmrk-result-output-3f2a9c"><tbody><tr><td>**Result** output</td><td>`3f2a9c7e-1b4d-4e8a-9c2f-7a1e5d6b0c84`</td></tr></tbody></table>

#### Tips

- Two different scenes always have different IDs, so this is a reliable way to check which scene is loaded before running scene-specific steps.
- The exact text will look different for every scene — treat it as a label to match or store, not something to read by eye.

### Home Screen

Takes the viewer back to the application’s home screen — the main start screen they see when SimLab Composer first opens.

#### What it does

When this node runs, it closes out of the current scene and returns the viewer to the home screen, where they can choose what to open next. Think of it as a “back to the main menu” button you can trigger from your scripting.

This node doesn’t change or delete anything in your scene — it simply switches the view back to the home screen. Note that this is different from the **Home Scene** node, which moves to the home scene inside the content you have open rather than leaving for the main screen.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output. The moment it fires, the viewer is taken back to the home screen.</td></tr></tbody></table>

#### Outputs

This node has no outputs.

#### Example

<table id="bkmrk-execute-input-connec"><tbody><tr><td>**Execute** input</td><td>Connect this to a “Quit” or “Exit to menu” button so that pressing it returns the viewer to the home screen.</td></tr></tbody></table>

#### Tips

- Use this when a training session is finished and you want the viewer returned to the main screen rather than left in the scene.
- If you only want to jump to the home scene *within* the open content, use the **Home Scene** node instead.

### Save Visual Settings

Saves how your scene currently looks — its lighting and environment, color adjustments, background, and the appearance of every material — to a visual-settings file (a `.vis` file) you can import back into SimLab Composer to re-apply that look.

#### What it does

This node takes a snapshot of the scene’s current visual style and stores it under the name you give it. The snapshot covers the lighting and environment (sun and sky, the surrounding environment light, and fog), the color and exposure adjustments (such as contrast, saturation, white balance, tint, and overall brightness), the background (whether it’s an image, the environment, or a solid color), and how every material in the scene looks (its color, shininess, transparency, reflection, and similar settings).

Saving doesn’t change your scene at all — it only reads the current values and stores them, so everything keeps looking exactly the same. The settings are written to a **visual-settings file** (a `.vis` file) named after the name you provide; saving again with the same name replaces the earlier file. Leaving the name empty saves it under a default name.

#### Applying a saved look

The `.vis` file this node creates can be **imported back into SimLab Composer** to apply the saved look to the scene. Save and import it **within the same session** — don’t close and reopen the scene in between. The saved look is tied to the scene’s internal IDs, and those can change when the scene is reopened, so a file saved in an earlier session may not apply correctly.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The name for the visual-settings file to create, such as `Daytime` (saved as `Daytime.vis`). If you leave it empty, a default name is used. Saving again with the same name replaces the earlier file.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Name**</td><td style="white-space: nowrap;">Text</td><td>The same name you provided, passed along so you can reuse it in later nodes.</td></tr></tbody></table>

#### Example

<table id="bkmrk-name-input-daytime-n"><tbody><tr><td>**Name** input</td><td>`Daytime`</td></tr><tr><td>**Name** output</td><td>`Daytime`</td></tr></tbody></table>

#### Tips

- **Save and import in the same session.** Apply the `.vis` file before closing and reopening the scene — if the scene is reopened first, its internal IDs may have changed and the saved look might not apply correctly.
- Give each look a clear, memorable name (for example `Daytime`, `Night`, or `Sunset`) so it’s easy to recognize when you import it back into Composer.
- Reusing a name on purpose is a handy way to update a saved look — the new save simply replaces the earlier `.vis` file under that name.

### ShareBack Scene

Sends the current scene back to the cloud, saving your changes as a new version of the experience it came from.

#### What it does

When this node runs, the Viewer shows a “Share Back Scene” prompt and the current scene is saved up to the cloud as a new version of the original experience it was opened from. This lets the changes the viewer made travel back to the shared cloud copy of the experience.

The node waits for the save to finish before it continues, so its result is ready by the time the next node runs. The **Success** output then tells you whether it worked: `true` if the scene was saved back as a new version, or `false` if it couldn’t be shared back right now. This does not change the scene that is currently running — it just publishes a copy back to the cloud.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output, for example from a button the viewer presses when they want to send their changes back.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the scene has finished being shared back — whether it succeeded or not. Check Success before assuming the save worked.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>`true` if the scene was saved back to the cloud as a new version; `false` if it couldn’t be shared back — for instance if the scene didn’t come from the cloud, the viewer isn’t signed in or doesn’t have permission to update it, or there’s no connection.</td></tr></tbody></table>

#### Example

<table id="bkmrk-execute-input-wired--0"><tbody><tr><td>**Execute** input</td><td>Wired from a “Save my changes” button in the scene</td></tr><tr><td>**Execute** output</td><td>Continues to a Branch node that reacts based on Success</td></tr><tr><td>**Success** output</td><td>`true`</td></tr></tbody></table>

#### Tips

- Because the Execute output fires whether the save worked or not, check the **Success** output first — a Branch node is a handy way to show a “Saved!” message on `true` and a “Couldn’t save” message on `false`.
- This only works for scenes that were opened from a cloud experience, and the viewer needs to be signed in with permission to update it.

# Integration

### [![OpenExternalConnection.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/openexternalconnection.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Open External Connection

SimLab Composer 14 introduces WebSocket support, enabling seamless integration with external systems allowing it to work with external hardware, co-simulation engines, and websites, unlocking numerous possibilities.

The WebSocket nodes (Open External Connection, Send Message, and <span data-darkreader-inline-color="" style="text-decoration: underline; color: rgb(35, 111, 161);">[On Message Received](https://simlab-soft.com/help/books/dynamic-training-builder-nodes-manual/page/on-message-received)</span>) are exclusively available in the Ultimate Edition.

The **Open External Connection** node enables the opening of a WebSocket connection to an external system. When the **Auto Handle Lua** is set to **true**, incoming messages containing Lua scripts will be automatically executed. This allows for real-time interaction between SimLab Composer and external systems, such as co-simulation engines or hardware, with the ability to dynamically execute Lua code as part of the interaction.

[![Screenshot 2025-02-02 162338.jpg](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/screenshot-2025-02-02-162338.jpg)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/screenshot-2025-02-02-162338.jpg)

**Input Ports:**

- Execute
- URL: WebSocket URL that includes the server IP address, port, channel (optional). Example: ws://server1.simlab-soft.com:8765/robots\_1
- Auto Handle Lua: Incoming messages containing Lua scripts will automatically execute those scripts If enabled (True). <div class="container_b7e1cb" id="bkmrk--25"><div class="visualMediaItemContainer_f4758a"><div class="oneByOneGrid_f4758a oneByOneGridSingle_f4758a"><div class="mosaicItem__6c706 mosaicItemNoJustify__6c706 mosaicItemMediaMosaic__6c706 hideOverflow__6c706"><div class="imageContent__0f481 embedWrapper_b7e1cb itemContentContainer_f4758a mosaicItemContent__6c706">  
    </div></div></div></div></div>

**Output Ports:**

- Execute
- URL
- Auto Handle Lua

---

### ![Response_Report_Completed.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-report-completed.png) Report Completed

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/Bukimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/Bukimage.png)

The **Report Completed** node functions similarly to the **Report Score** node, but it records both a score and a completion time simultaneously. It is ideal for finalizing tasks, exams, or training scenarios where both accuracy and speed are evaluated. Like the Report Score node, the recorded data is safely stored and utilized within the SimLab VR Assessment Portal for instructor review.

Key parameters:

- **Object Name:** The name of the exam, task, or entity being evaluated.
- **Score:** The numerical score or grade achieved.
- **Duration:** The total time taken to complete the evaluated task.

---

###   


### ![Response_Report_Score.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-report-score.png) Report Score

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/6Q4image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/6Q4image.png)

The **Report Score** node enables the system to register and record a specific value as a score when the node is executed. This is highly useful for tracking user performance, evaluating task completion, or logging quiz results within a training scenario.

The node utilizes the following key parameters to define the recorded data:

- **Object Name:** Specifies the name of the exam, task, or specific entity being evaluated.
- **Score:** The numerical input field where the final score value is passed or entered.
- **Report Type:** A dropdown menu that determines the classification or outcome of the score. The available options are **Passed**, **Scored**, and **Failed**.

The node stores the score and its associated information to be used primarily in the **SimLab VR Assessment Portal**, where instructors and administrators can securely view and evaluate the reported values.

##### Example

In this example, the system records a student's final score the moment they finish a test.

1. Upon interacting with the "Finish Quiz" object, the **Node Triggered** event initiates the execution flow.
2. The **Number Variable Value** node is used to retrieve the current numerical value stored in the `FinalScore` variable.
3. This retrieved value is passed directly into the **Score** input of the **Report Score** node.
4. The **Report Score** node is configured with the **Object Name** set to "Student Final Score" and the **Report Type** set to "Scored," which officially logs the student's result into the system's evaluation records when executed.

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/bkUimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/bkUimage.png)

---

### [![MessageSent.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/messagesent.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Send Message

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2025-02/scaled-1680-/h5mimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2025-02/h5mimage.png)

The **Send Message** node allows you to communicate with the WebSocket server by sending messages. It is essential to ensure that the message format follows the protocol that the server and other clients can process. This node enables real-time interaction with external systems, making it possible to transmit data or commands to connected servers or clients.

**Input Ports:**

- Executive
- URL: WebSocket URL that includes the server IP address, port, and channel (optional). Example: ws://server1.simlab-soft.com:8765/robots\_1
- Message

**Output Ports:**

- Execute
- URL
- Message

# SceneNode \ Snapping

### [![Response_Node_Transform_Snap_Can.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-transform-snap-can.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/response-node-transform-snap-can.png) Can Snap Node

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/HBgimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/HBgimage.png)

The **Can Snap Node** checks whether a specific SceneNode is currently within the eligible snapping range of another object. This node evaluates the spatial relationship between objects and outputs a "Possible" boolean to confirm if a snap can occur, alongside referencing the "Other Node" and its spatial "Transform" data for further logic use.

---

###   


### [![Response_Node_Transform_Snap.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-transform-snap.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/response-node-transform-snap.png) Snap Node

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/UwFimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/UwFimage.png)

The **Snap Node** instantly snaps a designated SceneNode directly to the nearest eligible target socket or node. Executing this node forces the object to immediately align and attach itself to the valid snapping destination without any transition time.

---

###   


### ![Response_Node_Transform_Snap_Animated.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-transform-snap-animated.png) Snap Node (Animated)

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/gZEimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/gZEimage.png)

The **Snap Node (Animated)** securely aligns and attaches a SceneNode to its nearest eligible target, but does so with a smooth visual transition. This node utilizes a "Duration" input to smoothly interpolate the object's movement into its snapped position over the specified number of seconds, rather than snapping instantly.

# SceneNode \ Hierarchy

### [![Responses_SceneNode_NodesManagement_GetNodeChildren.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/responses-scenenode-nodesmanagement-getnodechildren.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Get Node Children

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/Zlrimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The **Get Node Children** enables the user to retrieve child SceneNodes from a specified parent node within the hierarchy in the scene browser. This function allows users to access the children of a parent node in the VR environment, facilitating more complex interactions and hierarchies.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/mPyimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/S2himage.png)

In this example, the **Get Node Children** enables the user to retrieve the child of a group named "Ball Parent" on the Trigger event. When the user triggers the Activate object, the Get Node Children retrieves the child node, and the Get Node Attribute (String) is used to acquire the child’s attribute.

<div dir="auto" id="bkmrk-"><div dir="auto">---

</div></div>### [![Response_Node_Parent_Reset.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-node-parent-reset.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png) Reset Parent Node

[![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/YMCimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/add-node.jpg)The **Reset Parent Node** enables the user to reset all transformations applied to an object and return it to its original position relative to its main parent. This can be done by linking the node to an event or condition within the scene. Once the reset is executed, the object will revert to its default state under the main parent.

#### Example

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/uD6image.png)](https://simlab-soft.com/help/uploads/images/gallery/2024-08/S2himage.png)

In this example, a **Reset Parent Node** is used to reset the transformations of a car object to its original state relative to its main parent once the "Car Move" sequence ends. When the user triggers the Activate object, the car move animation sequence will play. After the sequence concludes, the Reset Parent Node is triggered automatically, returning the car to its default position under the main parent.

> [![Discord_Icon.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/discord-icon.png) ](https://simlab-soft.com/help/uploads/images/gallery/2024-08/response-value-number-add.png)[Tutorial is available on SimLab VR Discord server](https://discord.com/channels/1062715275805470821/1239178616877875354/1239178616877875354 "Tutorial is available on SimLab VR Discord server")

<div dir="auto" id="bkmrk--0"><div dir="auto">---

</div></div>### Get Node Descendants

Gives you every node nested underneath a scene node — not just its direct children, but everything below it at any depth.

#### What it does

Point this node at a scene node (often a group or assembly) and it hands back all of the nodes contained inside it: its children, their children, and so on all the way down. It’s like asking “give me everything inside this, no matter how deeply it’s tucked away.” This is the difference between this node and Get Node Children, which only returns the items one level down.

It simply reads the scene and reports back — nothing is moved, regrouped, or changed. The scene node you started from also comes straight back out, so you can keep wiring from it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The node whose contents you want — usually a group or assembly. Everything nested inside it will be returned.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same scene node you connected, passed straight back out unchanged so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Descendants**</td><td style="white-space: nowrap;">Scene node</td><td>Every node nested inside the one you gave — children, grandchildren, and deeper — gathered together. Connect this to a node that works through each one in turn.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-a-gr"><div dir="auto"><table><tbody><tr><td>**SceneNode** input</td><td>A group named `Engine Assembly`</td></tr><tr><td>**SceneNode** output</td><td>The same `Engine Assembly` group, unchanged</td></tr><tr><td>**Descendants** output</td><td>Every part inside it at any level — `Block`, `Cylinder Head`, the bolts grouped under it, and so on</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-use-this-when-you-wa"><div dir="auto">- Use this when you want to reach *everything* inside a group, including items nested several levels deep. If you only need the items directly under a node, use **Get Node Children** instead.
- The Descendants output is a collection of many nodes, so it pairs well with a node that loops through or acts on each one — for example to hide, color, or move every part inside an assembly at once.

---

</div></div>### Get Parent Node

Finds the object that a scene node sits inside — its parent in the scene tree.

#### What it does

Scene objects can be nested: a wheel might sit inside a car, which sits inside a group. This node takes one object and gives you back the object directly above it in that nesting — the thing it belongs to.

It only looks the parent up; it doesn't move or change anything in your scene. You also get the original object handed straight back, so you can keep working with both the object and its parent. If the object is at the very top of the scene and isn't inside anything, the Parent result will be empty.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object whose parent you want to find.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected in, passed straight back so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Parent**</td><td style="white-space: nowrap;">Scene node</td><td>The object that the input object sits inside. Empty if the object is at the top level and isn’t inside anything.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-fron"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Front Left Wheel`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Front Left Wheel` (handed back unchanged)</td></tr><tr><td style="white-space: nowrap;">**Parent** output</td><td>`Car Body`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-always-check-whether"><div dir="auto">- Always check whether the Parent result is empty before using it — a top-level object has no parent to return.
- Because the original object comes back out unchanged, you can chain this node and keep building from the same object further down your script.

---

</div></div>### Set Parent Node

Moves a scene node so it becomes a child of another node, changing how the two move and behave together.

#### What it does

In your scene, nodes are arranged in a parent-and-child tree. When one node is the child of another, it travels with its parent — move, rotate, or hide the parent and the child follows along. This node lets you set (or change) which node a given scene node belongs to.

You give it the node you want to move and the node that should become its new parent. It places the first node under the second, then hands both nodes back out so you can keep wiring from them. It only changes the parent-child relationship — the node itself, along with its name and contents, stays the same.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The node you want to move — the one that will become a child.</td></tr><tr><td style="white-space: nowrap;">**Parent**</td><td style="white-space: nowrap;">Scene node</td><td>The node that should become the new parent. The node above will be placed under it.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same node you sent in, passed straight back out so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Parent**</td><td style="white-space: nowrap;">Scene node</td><td>The same parent node you sent in, passed straight back out so you can keep wiring from it.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-whee"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Wheel_FrontLeft`</td></tr><tr><td style="white-space: nowrap;">**Parent** input</td><td>`Car_Body`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Wheel_FrontLeft` — now a child of `Car_Body`, so it moves with the car body from here on</td></tr><tr><td style="white-space: nowrap;">**Parent** output</td><td>`Car_Body`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-this-is-handy-for-gr">- This is handy for grouping things together at runtime — for example, attaching a tool to a hand so it follows the hand’s movement.
- The child keeps its place in the scene; only what it is attached to changes.

</div>

# SceneNode \ Appearance

### ![Response_Node_Visibility_Get.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/response-node-visibility-get.png) Is Node Visible

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/MNnimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/MNnimage.png)

This node checks the current visibility state of a specified 3D object within the VR Viewer. It evaluates whether the targeted object is currently rendered (shown) or hidden in the scene, and outputs this status as a boolean value (True or False).

##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-03/scaled-1680-/DtJimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-03/DtJimage.png)

In this example, triggering the "Assembly" object prompts the system to check if the "Gear" node is currently visible. If the gear is visible, the True branch executes, setting the gear to glow and playing a "Remove Gear" animation sequence. However, if the gear is already hidden, the False branch executes instead, displaying a "Help Panel" to the user.

<div dir="auto" id="bkmrk--1"><div dir="auto">---

</div></div>### Get Node Material

Finds out which material is currently applied to a 3D object in your scene.

#### What it does

Point this node at a 3D object and it hands you back the material that is currently on it — the look that gives the object its color, texture, shininess, and so on. You can then pass that material to another object, inspect it, or change it elsewhere in your script.

This only reads the object’s material; it doesn’t change the object or its appearance in any way. The same object comes straight back out so you can keep wiring more steps from it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The 3D object whose material you want to read.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight back out so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material currently applied to that object.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-car-"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Car Body`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Car Body` (unchanged)</td></tr><tr><td style="white-space: nowrap;">**Material** output</td><td>`Red Glossy Paint`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-use-this-to-copy-a-l"><div dir="auto">- Use this to copy a look from one object to another: read the material here, then apply it to a different object with a “Set Node Material” node.

---

</div></div>### Set Node Glow State

Turns a glowing highlight on or off for an object in your scene.

#### What it does

This node takes an object from your scene and switches its glow effect on or off. Use it to make something stand out — for example, lighting up the part a trainee needs to pick up next, or highlighting a button they should press.

It only changes whether the glow is showing; nothing else about the object is altered. The same object is handed straight back out so you can keep wiring more actions onto it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene you want to glow (or stop glowing).</td></tr><tr><td style="white-space: nowrap;">**Glow**</td><td style="white-space: nowrap;">True / false</td><td>Set to `true` to turn the glow on, or `false` to turn it off. Defaults to `true` if you leave it unconnected.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-0"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you sent in, passed straight back out so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Glow**</td><td style="white-space: nowrap;">True / false</td><td>The glow setting you applied (`true` or `false`), passed along.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-the-"><div dir="auto"><table><tbody><tr><td>**SceneNode** input</td><td>The `Wrench` object the trainee needs to find next</td></tr><tr><td>**Glow** input</td><td>`true`</td></tr><tr><td>**SceneNode** output</td><td>The same `Wrench` object, now glowing</td></tr><tr><td>**Glow** output</td><td>`true`</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-to-turn-a-highlight-"><div dir="auto">- To turn a highlight off later, run this node again on the same object with **Glow** set to `false`.
- Because the object comes straight back out, you can chain another action right after — for example, glow it and then play a sound.

---

</div></div>### Set Node Material

Gives a scene object a new look by applying a material to it.

#### What it does

This node takes one of your scene objects and a material, and puts that material onto the object — changing how it looks (its color, texture, shininess, and so on). For example, you could switch a part from a plain gray finish to a glossy red one.

The object itself is the same object as before — only its appearance changes. The node hands the object and the material straight back out, so you can keep wiring more steps from either of them.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene whose look you want to change.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The material to put on the object — the new color, texture, and finish it should have.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-1"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you sent in, passed straight back out so you can keep wiring from it.</td></tr><tr><td style="white-space: nowrap;">**Material**</td><td style="white-space: nowrap;">Material</td><td>The same material you sent in, passed back out in case you want to use it again.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-car_"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Car_Body`</td></tr><tr><td style="white-space: nowrap;">**Material** input</td><td>`Glossy_Red`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Car_Body` — now showing the glossy red finish, ready to wire into the next step</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-prepare-the-material"><div dir="auto">- Prepare the materials you want to switch between in your scene first, then feed the right one into this node when you want the object to change.
- Because the object comes straight back out, you can chain several changes — for example, set a material and then move or highlight the same object in the next node.

---

</div></div>### Show/Hide

Shows or hides a scene node, so you can make objects appear and disappear during your scene.

#### What it does

Give this node a scene node and a true/false value. When set to true, the node becomes visible; when set to false, it is hidden from view. This is handy for revealing a part once a step is reached, or hiding a finished assembly to clear the workspace.

Hiding a node only changes whether it can be seen — the object itself stays in your scene, keeps its position, and can be shown again at any time. The same scene node comes straight back out so you can keep wiring more actions from it.

#### Inputs

<div dir="auto" id="bkmrk-port-type-what-to-co-2"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to show or hide, such as a part, group, or model in your scene.</td></tr><tr><td style="white-space: nowrap;">**Show**</td><td style="white-space: nowrap;">True / false</td><td>Set to `true` to make the object visible, or `false` to hide it.</td></tr></tbody></table>

</div></div>#### Outputs

<div dir="auto" id="bkmrk-port-type-what-you-g-2"><div dir="auto"><table><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same scene node you passed in, handed straight back so you can keep wiring more actions from it.</td></tr><tr><td style="white-space: nowrap;">**Show**</td><td style="white-space: nowrap;">True / false</td><td>The same true/false value you passed in, so you can reuse it further along.</td></tr></tbody></table>

</div></div>#### Example

<div dir="auto" id="bkmrk-scenenode-input-warn"><div dir="auto"><table><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Warning_Light`</td></tr><tr><td style="white-space: nowrap;">**Show** input</td><td>`true` — the warning light appears to alert the trainee</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Warning_Light`, passed straight back so you can move or color it next</td></tr></tbody></table>

</div></div>#### Tips

<div dir="auto" id="bkmrk-to-hide-an-object%2C-s">- To hide an object, set **Show** to `false`; to bring it back, run the node again with `true`.
- A hidden object is only invisible — it is still in your scene and keeps its place, so showing it again puts it right back where it was.

</div>

# SceneNode \ Curve

### ![Response_Curve_Create.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-curve-create.png) Create Curve

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/5FWimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/5FWimage.png)

The **Create Curve node** initializes a new 3D cylindrical line within the VR scene. This is highly useful for creating dynamic visual elements like charts, graphs, or data visualizations.

When activated, it generates a base curve using four primary inputs: a unique text **Name** (which acts as an identifier required by all other curve-related nodes to target this specific line), a **Color**, a numerical **Thickness** value, and a **CurveType** dropdown that dictates whether the overall line behaves as a smooth curve or rigid straight lines. It then outputs a reference to the newly created CurveNode to continue the logic flow.

---

### ![Response_Curve_Point_Add.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-curve-point-add.png) Add Curve Point

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/BI7image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/BI7image.png)

The **Add Curve Point node** builds upon an existing curve by generating a new point in 3D space. Once activated, the node locates the specific curve identified by the **Name** input and places a new point at the provided **X, Y, and Z** coordinates. The system automatically draws a line connecting this newly created point to the previously established point, seamlessly extending the curve. Crucially, this node outputs an **Index** value—a unique number assigned to this specific point in the sequence (e.g., the 3rd point created gets an index of 3)—which is used to target this point later.

##### Example:

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/yV8image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/yV8image.png)

In this expanded example, we build an interaction where clicking a button initializes a new curve and sequentially places two connected points based on a target object's location:

1. A **Node Triggered** event node continuously listens for the user to interact with a specific "Button" object in the scene.
2. Once the button is clicked, it activates a **Create Curve** node, which initializes a new curve named "dataCurve" with a distinct green color, a thickness value of 7, and a "Curved" line type.
3. The execution flow immediately proceeds to a **Get Node Location** node, which retrieves the exact X, Y, and Z spatial coordinates of a target 3D object named "Point".
4. The first **Add Curve Point** node is activated. It takes the "dataCurve" identifier and utilizes the precise X, Y, and Z coordinates retrieved from the target object to generate the first anchor point of the curve.
5. Simultaneously, an **Add** math node receives the original Y coordinate from the "Point" object and adds a numerical value of 2 to it.
6. Following the creation of the first point, a second **Add Curve Point** node is executed. It uses the same "dataCurve" identifier and the original X and Z coordinates, but it uses the newly calculated result from the Add node (Y + 2) for its vertical placement. This generates a second point exactly 2 units directly above the first, automatically drawing a connected line between them.

---

### ![Response_Curve_Point_Remove.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-curve-point-remove.png) Remove Curve Point

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/hWoimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/hWoimage.png)

The **Remove Curve Point node** is used to permanently delete a specific point from an active curve. Once activated, it takes the curve's **Name** and the specific **Index** number of the point you wish to erase. Upon deletion, the curve automatically bridges the gap between the remaining adjacent points to maintain a continuous, unbroken line.

---

### [![Response_Curve_Thickness_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-curve-thickness-set.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-04/response-curve-thickness-set.png)Set Curve Thickness

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/5qKimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/5qKimage.png)

The **Set Curve Thickness node** dynamically adjusts the physical width of an existing curve during the VR experience. When activated, it targets the curve specified by the **Name** input and instantly changes its visual bulk to match the number provided in the **Value** input, allowing you to easily scale the visual prominence of the line on the fly.

---

### [![Response_Curve_Type_Set.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-curve-type-set.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-04/response-curve-type-set.png)Set Curve Type

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/iW3image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/iW3image.png)

The **Set Curve Type node** instantly alters how the connections between a curve's points are visually rendered in the scene. Once activated, it locates the curve by its **Name** and applies the newly selected **CurveType** from the dropdown menu. This allows you to toggle a curve between "Curved" (which renders smooth, sweeping connections between the points) and "Linear" (which renders sharp, perfectly straight lines between the points) at any time.

---

### [![Response_Curve_Point_Update.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/response-curve-point-update.png) ](https://simlab-soft.com/help/uploads/images/gallery/2026-04/response-curve-point-update.png)Update Curve Point

[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-04/scaled-1680-/wE1image.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-04/wE1image.png)

The **Update Curve Point** node allows you to dynamically change the 3D location of a previously created point on an existing curve. When activated, it targets the curve using the **Name** input and isolates a specific point using its numerical **Index** value. It then instantly moves that point to the newly provided **X, Y, and Z** coordinates. The line connecting the points will automatically recalculate and redraw itself to reflect the point's new location in the scene.

# Data Types \ Transform

A **Transform** describes where something sits in the 3D scene and how it is oriented. It is made of three parts: a **position** (called `translation`), a **rotation** (which way it is turned), and a **scale** (how large it is). The nodes on this page convert a Transform to and from text or a JSON object — so you can save it, send it to another system, store it in an attribute, or rebuild it later.

## What's on this page

- **Create** — build a Transform from a piece of text, or from a JSON object.
- **Convert** — turn a Transform into a piece of text, or into a JSON object.

**The three parts of a Transform.** In both the text form and the JSON object form, a Transform is written with three named values:

- `translation` — the **position**, given as three numbers (left/right, up/down, forward/back). `[0, 0, 0]` means "at the origin."
- `rotation` — the **orientation**, given as four numbers that together describe which way the object is turned. `[0, 0, 0, 1]` means "not rotated at all."
- `scale` — the **size**, given as three numbers. `[1, 1, 1]` means "normal size."

All four nodes below use this same example throughout: a Transform positioned at `[10, 5, 0]`, with no rotation and normal scale.

---

## Create

These two nodes build a brand-new Transform from data you already have — one reads it from text, the other from a JSON object. Neither one moves anything in the scene on its own; they produce a Transform *value* that you can then use elsewhere.

### Create Transform From String

Reads a piece of text describing a Transform and turns it into a real Transform you can use.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/58" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Useful when the Transform arrived as text — for example from a file you read, a message someone sent, or a value stored in an attribute. The node reads the text and gives you back a proper Transform. The text must contain the three named values `translation`, `rotation`, and `scale`.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text to read. It should describe a Transform, with `translation`, `rotation`, and `scale` values.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**Transform**</td><td style="white-space: nowrap;">Transform</td><td>The Transform built from your text.</td></tr></tbody></table>

#### Example

<table id="bkmrk-value-input-%7B%22transl"><tbody><tr><td style="white-space: nowrap;">**Value** input</td><td>`{"translation":[10,5,0],"rotation":[0,0,0,1],"scale":[1,1,1]}`</td></tr><tr><td style="white-space: nowrap;">**Transform** output</td><td>A Transform at position `[10, 5, 0]`, no rotation, normal scale.</td></tr></tbody></table>

#### Tips

- **Match the format.** If the text is missing one of the three values, or a bracket or comma is out of place, the node won't be able to read it.
- **Rotation, the short way.** You can write `rotation` as three numbers (a simple turn in degrees) instead of four — both are accepted. Four numbers describe the orientation exactly; three are easier to write by hand.
- **Reverse direction.** To go the other way and turn a Transform *into* text, see **Transform To String** further down this page.

### Create Transform From Json Object

Builds a Transform from a JSON object that holds the position, rotation, and scale.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/55" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Same idea as **Create Transform From String**, but the data comes in as a JSON object rather than as text. This is handy when you've built the values up using the **JSON Object** nodes — for example by setting a `translation` field, a `rotation` field, and a `scale` field — and now want a Transform out of them.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">JSON object</td><td>An object with `translation`, `rotation`, and `scale` fields. See the **JSON Objects** page for nodes that build one.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**Transform**</td><td style="white-space: nowrap;">Transform</td><td>The Transform built from the object.</td></tr></tbody></table>

#### Example

<table id="bkmrk-value-input-%7B%22transl-0"><tbody><tr><td style="white-space: nowrap;">**Value** input</td><td>`{"translation": [10, 5, 0], "rotation": [0, 0, 0, 1], "scale": [1, 1, 1]}`</td></tr><tr><td style="white-space: nowrap;">**Transform** output</td><td>A Transform at position `[10, 5, 0]`, no rotation, normal scale.</td></tr></tbody></table>

#### Tips

- **Missing fields are fine.** If the object leaves out one of the three values, that part is left at its default (no movement, no rotation, or normal scale).
- **Reverse direction.** To turn a Transform *into* a JSON object, see **Transform To Json Object** further down this page.

---

## Convert

These two nodes take a Transform and produce a text or JSON-object version of it. The original Transform isn't changed — each node hands you back the same Transform plus the converted form, so you can keep using the Transform downstream.

### Transform To String

Turns a Transform into a single piece of text.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/56" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Produces a text version of the Transform, written with its `translation`, `rotation`, and `scale` values. Useful when you need to save the Transform to a file, store it in a device attribute, or send it to another system that only accepts text.

The Transform itself isn't modified — you get the same Transform back plus a text version.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Transform**</td><td style="white-space: nowrap;">Transform</td><td>The Transform to convert.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**Transform**</td><td style="white-space: nowrap;">Transform</td><td>The same Transform you passed in.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text version of the Transform.</td></tr></tbody></table>

#### Example

<table id="bkmrk-transform-input-a-tr"><tbody><tr><td style="white-space: nowrap;">**Transform** input</td><td>A Transform at position `[10, 5, 0]`, no rotation, normal scale.</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`'{"translation":[10,5,0],"rotation":[0,0,0,1],"scale":[1,1,1]}'`</td></tr></tbody></table>

#### Tips

- **Reverse direction.** To go back from text to a Transform, use **Create Transform From String** at the top of this page.
- **Round trip.** Text made by this node can be read straight back in by **Create Transform From String** — handy for saving a Transform now and restoring it later.

### Transform To Json Object

Turns a Transform into a JSON object with separate fields for position, rotation, and scale.

<video autoplay="autoplay" height="auto" loop="loop" muted="" width="100%"> <source src="https://simlab-soft.com/help/attachments/57" type="video/mp4"> Your browser doesn't support embedded video. </source></video>

#### What it does

Produces a JSON object holding the Transform's `translation`, `rotation`, and `scale`. Unlike the text version, the result is a real JSON object — so you can read out an individual part (just the position, say) using the **Get** nodes on the **JSON Objects** page.

The Transform itself isn't modified — you get the same Transform back plus the object version.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node's **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Transform**</td><td style="white-space: nowrap;">Transform</td><td>The Transform to convert.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires after this node finishes.</td></tr><tr><td style="white-space: nowrap;">**Transform**</td><td style="white-space: nowrap;">Transform</td><td>The same Transform you passed in.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">JSON object</td><td>The object version of the Transform, with `translation`, `rotation`, and `scale` fields.</td></tr></tbody></table>

#### Example

<table id="bkmrk-transform-input-a-tr-0"><tbody><tr><td style="white-space: nowrap;">**Transform** input</td><td>A Transform at position `[10, 5, 0]`, no rotation, normal scale.</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`{"translation": [10, 5, 0], "rotation": [0, 0, 0, 1], "scale": [1, 1, 1]}`</td></tr></tbody></table>

#### Tips

- **Read out one part.** Wire the **Result** into **Get Json Object Field (JsonArray)** with the field name `translation` to pull just the position back out.
- **Reverse direction.** To go back from an object to a Transform, use **Create Transform From Json Object** at the top of this page.

---

## Related

- **JSON Objects** — build the object you feed into **Create Transform From Json Object**, or read individual parts out of the object that **Transform To Json Object** produces.
- **JSON Arrays** — the `translation`, `rotation`, and `scale` values are each small JSON arrays of numbers.

# Device / Attributes

A **device attribute** is a named value saved on the **device** the experience is running on — a PC, a phone or tablet, a standalone VR headset, and so on. You give each value a name (for example `language`) and store a piece of text under it. These values belong to the device itself: they stay on it after the scene or app is closed and reopened (even across different experiences), they are *not* tied to whoever is signed in, and the person using the device can also see and change them in the viewer’s Settings.

That makes device attributes the right tool for remembering something on one particular device for next time — a chosen language, measurement units, the name of a kiosk or station, and the like. The examples on this page all use the same running example: a setting named `language` holding the text `English`.

## What's on this page

- **Set Device Attribute (String)** — save a piece of text on the device under a name.
- **Get Device Attribute (String)** — read back the text saved under a name.
- **Device Has Attribute** — check whether the device has a value saved under a name (true or false).
- **Remove Device Attribute** — delete a saved value from the device.

---

## Attributes

These four nodes are the complete set for working with a device’s saved values — store one, read it back, check whether it exists, and remove it. None of them is tied to who is signed in, and every value stays on the device for next time.

### Set Device Attribute (String)

Saves a piece of text on the device under a name you choose, so you can read it back later — even after the experience is closed and reopened.

#### What it does

This node stores a bit of text on the device the experience is running on — a PC, a phone or tablet, a standalone VR headset, and so on. You give it a name (such as `language`) and the text to store (such as `English`), and the node remembers that value on the device. If a value with that name doesn’t exist yet, it creates one; if it already exists, the new text replaces the old.

The value stays on the device, so it’s still there next time the experience runs — it’s a good way to remember a setting for next time. These values belong to the device itself, not to whoever is signed in, so they aren’t tied to a particular person. They also aren’t hidden: the person using the device can see and change them in the viewer’s Settings.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the text under, such as `language`. You can pick a name from the drop-down list of names already known on the device, or simply type a brand-new name.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text you want to store, such as `English`. If a value with this name already exists, this replaces it.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished saving the value.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The same attribute name you gave, passed straight through (handy for wiring into the next node).</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The same text you stored, passed straight through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-attribute-name-input"><tbody><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`English`</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** output</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Value** output</td><td>`English`</td></tr></tbody></table>

#### Tips

- Use this to remember a setting on the device for next time, such as the chosen `language` or measurement `units`.
- Saving again under the same name simply replaces the old text — you don’t need to remove the old value first.
- Pair it with **Get Device Attribute (String)** to read the value back later.

### Get Device Attribute (String)

Reads back a piece of text that was saved on this device under a name you choose.

#### What it does

A device attribute is a value stored on the device the experience is running on — a PC, phone, tablet, or VR headset. You give this node the name of the attribute you want, and it hands back the text currently saved under that name. These values live on the device itself, not with whoever is logged in, and they stay put after the scene or app is closed and reopened — so this node is the way to read something you remembered on this device for next time.

This node only reads; it never changes the saved value. If nothing has been saved under that name yet, you simply get back empty text — the node carries on without any error.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the value you want to read. Pick one from the drop-down, which lists names already saved on the device, or type a new name yourself. For example, `language`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The same attribute name you gave, passed straight through (handy for wiring into the next node).</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text saved under that name. If nothing is saved under that name, you get back empty text.</td></tr></tbody></table>

#### Example

<table id="bkmrk-attribute-name-input-0"><tbody><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** output</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`English`</td></tr></tbody></table>

#### Tips

- Getting empty text back usually means nothing has been saved under that name yet — on this device, set it first with **Set Device Attribute (String)**, or check with **Device Has Attribute** before reading.
- These values are saved per device and are not tied to who is logged in. The person using the device can also see and change them in the viewer’s Settings.

### Device Has Attribute

Checks whether this device already has a saved setting with a given name, and tells you yes or no.

#### What it does

This node looks on the device the experience is running on — a PC, phone, tablet, VR headset, and so on — for a saved setting with the name you give it. If a setting with that name exists, the **Result** comes back as `true`; if there is no setting with that name, it comes back as `false`. Either way the node simply reports what it found and does not change or remove anything.

These device settings live on the device itself. They are not tied to whoever is signed in, and they stay on the device after the scene or app is closed and reopened — even across different experiences. (The person using the device can also view and change them in the viewer’s Settings.) That makes this node handy for asking “has this device been set up before?” so you can decide what to do next.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the setting to look for, such as `language`. The field offers a drop-down of names already saved on the device, and you can also type a brand-new name that isn’t in the list.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished — whether the setting was found or not.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The same attribute name you gave, passed straight through (handy for wiring into the next node).</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>`true` if the device has a setting with that name, or `false` if it does not.</td></tr></tbody></table>

#### Example

<table id="bkmrk-attribute-name-input-1"><tbody><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** output</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`true` (this device has a `language` setting saved)</td></tr></tbody></table>

#### Tips

- Use this as a quick “first time on this device?” check: if **Result** is `false`, set up a default; if it’s `true`, just read the saved value.
- This node only checks for the setting — it never changes or removes it. Use Set Device Attribute to store a value and Remove Device Attribute to clear one.

### Remove Device Attribute

Deletes a saved setting from the device the experience is running on.

#### What it does

A device attribute is a small named value kept on the device itself — the PC, phone, tablet, or VR headset that is running the experience. These values stay on the device and are saved for next time, so they are still there after the app or scene is closed and reopened. They aren’t tied to who is logged in, and the person using the device can see and change them in the viewer’s Settings. This node removes one of those saved values by name.

Give it the name of the attribute you want to remove. If a value with that name is saved on the device, it is deleted; if no value with that name exists, the node simply does nothing and carries on — no error. The name you gave is passed straight through on the output, so you can keep wiring the flow forward.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the device value to remove, such as `language`. You can pick a name from the drop-down list of values already saved on the device, or type a name yourself.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The same attribute name you gave, passed straight through (handy for wiring into the next node).</td></tr></tbody></table>

#### Example

<table id="bkmrk-attribute-name-input-2"><tbody><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`language`</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** output</td><td>`language`</td></tr></tbody></table>

#### Tips

- It’s safe to remove a name that may not be there — if nothing is saved under that name, the node just moves on without an error.
- Removing a value only affects this device. Saved values on other devices are not touched.

# SceneNode \ Transform \ Scale

These nodes read and change the **size** of a 3D object. Size is given as three numbers — X, Y, and Z — each a **multiplier** of the object’s original size: `1` means unchanged, `2` means twice as big, `0.5` means half. Most come in two forms: a **world** version that uses the object’s size in the whole scene, and a **(Local)** version measured relative to its parent or group. Changing an object’s size never moves it or turns it.

## What's on this page

- **Read the size** — find out how large an object currently is.
- **Change the size** — resize an object, instantly or smoothly over time.

---

## Read the size

These read an object’s current size without changing anything.

### Get Node Scale

Reads how large an object currently is in the scene and gives you its size along each axis as separate numbers.

#### What it does

This node looks at an object you point it to and reports its current size in the whole scene. You get three numbers back — one for the X axis, one for Y, and one for Z. Each number is a multiplier of the object’s original (authored) size: `1` means unchanged, `2` means twice as big, and `0.5` means half size.

It only reads the size — it doesn’t resize the object or change anything else in the scene. The same object is also passed straight through, so you can keep working with it in the nodes that follow.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object whose size you want to read. Connect the object you picked earlier in the flow.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object passed through, so you can chain more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The object’s current size along the X axis, as a multiplier of its original size (`1` = unchanged).</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The object’s current size along the Y axis, as a multiplier of its original size.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The object’s current size along the Z axis, as a multiplier of its original size.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-cr"><tbody><tr><td>**SceneNode** input</td><td>A crate you placed in the scene</td></tr><tr><td>**X** output</td><td>`2`</td></tr><tr><td>**Y** output</td><td>`2`</td></tr><tr><td>**Z** output</td><td>`0.5`</td></tr></tbody></table>

#### Tips

- A value of `1` on an axis means that axis is at the object’s original size. Values above `1` are larger; values below `1` are smaller.
- This reports the object’s overall size in the whole scene, so if the object sits inside a group that has been resized, that resizing is included in the result.

---

### Get Node Scale (Local)

Reads how big an object currently is, measured relative to its parent or group.

#### What it does

This node looks at one object in your scene and tells you its current size along each axis (X, Y, and Z). Each value is a multiplier of the object’s original, authored size: `1` means unchanged, `2` means twice as big, and `0.5` means half size. It is not a measurement in meters and not a percentage.

The size you get back is the **local** size — measured relative to the object’s parent or group. If that parent or group is resized, this local value stays the same. (If the object has no parent or group, its local size and its size in the whole scene are the same.) This node only reads the size; it doesn’t change the object or affect anything else in your scene.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object whose size you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object passed straight through, so you can chain more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the X axis (`1` = original size).</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Y axis (`1` = original size).</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Z axis (`1` = original size).</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the-"><tbody><tr><td>**SceneNode** input</td><td>The crate you placed in the scene</td></tr><tr><td>**X** output</td><td>`2`</td></tr><tr><td>**Y** output</td><td>`0.5`</td></tr><tr><td>**Z** output</td><td>`1.5`</td></tr></tbody></table>

#### Tips

- A value of `1` on every axis means the object is still at its original, authored size.
- To read the object’s size in the whole scene instead of relative to its parent or group, use the matching node without “(Local)” in its name.

---

## Change the size

These resize an object. The plain versions change it instantly; the **(Animated)** versions grow or shrink it smoothly over a number of seconds.

### Set Node Scale

Resizes an object in your scene by setting how big it is along each axis.

#### What it does

This node changes the size of the object you give it. You set three numbers — X, Y, and Z — and each one is a multiplier of the object’s original, authored size: `1` leaves that axis unchanged, `2` makes it twice as big, and `0.5` makes it half size. The change happens instantly.

The size you set here is the object’s overall size in the whole scene. The same object passes straight out the other side, so you can keep working with it in the next node. Only the object you connect is affected — nothing else in your scene moves or resizes.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to resize.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the X axis. `1` keeps it the same, `2` doubles it, `0.5` halves it.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Y axis. `1` keeps it the same.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Z axis. `1` keeps it the same.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object, passed through so you can chain more nodes.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X multiplier you set, passed through.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y multiplier you set, passed through.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z multiplier you set, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-cr-0"><tbody><tr><td>**SceneNode** input</td><td>A crate object in your scene</td></tr><tr><td>**X** input</td><td>`2`</td></tr><tr><td>**Y** input</td><td>`2`</td></tr><tr><td>**Z** input</td><td>`0.5`</td></tr><tr><td>**SceneNode** output</td><td>The same crate, now twice as big on X and Y and half its size on Z</td></tr></tbody></table>

#### Tips

- Use the same number for X, Y, and Z to resize the object evenly without changing its shape.
- To return an object to its original size, set all three values back to `1`.

---

### Set Node Scale (Animated)

Smoothly resizes a 3D object to a new size over a set number of seconds.

#### What it does

This node changes the size of the object you give it, gliding from its current size to the new size over the time you choose instead of snapping there instantly. The size is set as a multiplier of the object’s original (authored) size: `1` leaves it unchanged, `2` makes it twice as big, and `0.5` makes it half as big. You can set a different multiplier for each axis (X, Y, Z), so the object can grow more along one axis than another.

The new size is the object’s absolute size in the whole scene. Only the object you connect is resized — nothing else in your scene is touched. The object is passed straight through the output so you can keep building on it after the resize.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to start the resize.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The 3D object you want to resize.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the X axis, where `1` keeps the original size, `2` doubles it, and `0.5` halves it. Defaults to `1`.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Y axis, in the same way as X. Defaults to `1`.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Z axis, in the same way as X. Defaults to `1`.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How many seconds the smooth resize should take. Defaults to `2`. Must be zero or more.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires so the flow can continue once the resize has been applied.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you passed in, so you can connect more nodes to keep working with it.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X size multiplier you set, passed along for reuse.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y size multiplier you set, passed along for reuse.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z size multiplier you set, passed along for reuse.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>The duration in seconds you set, passed along for reuse.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--0"><tbody><tr><td>**SceneNode** input</td><td>The crate you want to grow</td></tr><tr><td>**X** input</td><td>`2`</td></tr><tr><td>**Y** input</td><td>`2`</td></tr><tr><td>**Z** input</td><td>`2`</td></tr><tr><td>**Duration** input</td><td>`1.5`</td></tr><tr><td>**SceneNode** output</td><td>The same crate, now growing to twice its size over 1.5 seconds</td></tr></tbody></table>

#### Tips

- Use the same value for X, Y, and Z to resize the object evenly; use different values to stretch it more along one axis.
- A `Duration` of `0` resizes the object instantly — for a normal smooth resize, use the non-animated **Set Node Scale** node instead, which always changes the object instantly.
- Remember the values are multipliers, not measurements: `1` means “keep the original size,” not one meter.

---

### Set Node Scale (Local)

Resizes a 3D object by setting how much bigger or smaller it is than its original size, measured relative to its parent or group.

#### What it does

This node sets the object’s scale along its X, Y, and Z axes. Each value is a multiplier of the object’s original (authored) size: `1` leaves that axis unchanged, `2` makes it twice as big, and `0.5` makes it half size. The scale replaces whatever size the object had before — it isn’t added on top.

The size is “local,” meaning it’s measured relative to the object’s parent or group: if that parent or group is later moved, turned, or resized, this local value stays the same. If the object has no parent or group, its local and world size are the same. Only the object you connect is affected — other objects in the scene are left alone.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The 3D object you want to resize.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the X axis (`1` = original size, `2` = twice as big, `0.5` = half size). Defaults to `1`.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Y axis. Defaults to `1`.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Z axis. Defaults to `1`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object passed straight through, so you can chain more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X multiplier you set, handy for feeding into the next node.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y multiplier you set.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z multiplier you set.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--1"><tbody><tr><td>**SceneNode** input</td><td>The crate you want to enlarge</td></tr><tr><td>**X** input</td><td>`2`</td></tr><tr><td>**Y** input</td><td>`2`</td></tr><tr><td>**Z** input</td><td>`0.5`</td></tr><tr><td>**SceneNode** output</td><td>The same crate, now twice as big on X and Y and half as tall on Z</td></tr></tbody></table>

#### Tips

- To resize evenly in all directions, set X, Y, and Z to the same value.
- Setting all three to `1` returns the object to its original authored size.

---

### Set Node Scale (Local, Animated)

Smoothly resizes an object in your scene over a set number of seconds, relative to the size it was given when the scene was built.

#### What it does

This node changes how big an object is, gently growing or shrinking it from its current size to a new size over the time you choose. The X, Y, and Z values are multipliers of the object’s original (authored) size: `1` leaves that direction unchanged, `2` makes it twice as big, and `0.5` makes it half as big. You can use different values for each axis to stretch the object, or the same value on all three to resize it evenly.

The size is set in “local” terms — measured relative to the object’s parent or group. If that parent or group is later moved, turned, or resized, this local size stays the same. (If the object has no parent or group, its local size and its size in the whole scene are the same thing.) Only the object you connect is affected; nothing else in the scene changes.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to start the resize.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to resize. You can connect more than one, and each will be resized.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the X axis. `1` keeps it the same, `2` doubles it, `0.5` halves it.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Y axis, in the same way as X.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The size multiplier along the Z axis, in the same way as X.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How many seconds the smooth resize should take. Use a larger value for a slower change. (The non-animated version of this node changes the size instantly.)</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has applied the resize, so the flow can continue.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object (or objects) passed straight through, so you can connect more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**X**</td><td style="white-space: nowrap;">Number</td><td>The X size multiplier you provided, passed through for reuse.</td></tr><tr><td style="white-space: nowrap;">**Y**</td><td style="white-space: nowrap;">Number</td><td>The Y size multiplier you provided, passed through for reuse.</td></tr><tr><td style="white-space: nowrap;">**Z**</td><td style="white-space: nowrap;">Number</td><td>The Z size multiplier you provided, passed through for reuse.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>The number of seconds you provided, passed through for reuse.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-bo"><tbody><tr><td>**SceneNode** input</td><td>A box object in your scene</td></tr><tr><td>**X** input</td><td>`2`</td></tr><tr><td>**Y** input</td><td>`2`</td></tr><tr><td>**Z** input</td><td>`0.5`</td></tr><tr><td>**Duration** input</td><td>`1.5` — the box grows to its new size over one and a half seconds</td></tr><tr><td>**SceneNode** output</td><td>The same box, ready to pass on to the next node</td></tr></tbody></table>

#### Tips

- Use the same value for X, Y, and Z to resize an object evenly without changing its shape.
- A value of `1` on an axis leaves that direction at its original size, so you can resize in just one or two directions.
- To resize instantly with no smooth motion, use the non-animated version of this node instead.

# SceneNode \ Transform \ Rotation

These nodes read and change how a 3D object is **turned** in your scene. An object’s rotation is given as three numbers — **Pitch**, **Yaw**, and **Roll** — measured in degrees (90 = a quarter turn). Most come in two forms: a **world** version that uses the object’s orientation in the whole scene, and a **(Local)** version measured relative to the object’s parent or group. Changing an object’s rotation never moves it or resizes it.

## What's on this page

- **Read the rotation** — find out which way an object is currently turned.
- **Change the rotation** — turn an object to a new orientation (instantly or smoothly over time), or reset it to how it started.

---

## Read the rotation

These read an object’s current orientation without changing anything — handy for storing it, comparing it, or feeding it into other nodes.

### Get Node Rotation

Reads how an object is currently turned in your scene and gives you back its three rotation values.

#### What it does

This node looks at an object you choose and tells you its current orientation — how far it is turned — as three separate numbers: **Pitch**, **Yaw**, and **Roll**. Each value is measured in degrees, where `90` is a quarter turn and `180` is a half turn.

The numbers describe the object’s orientation in the whole scene (its absolute, world orientation). Reading the rotation only measures the object — it doesn’t turn it, and it doesn’t affect any other objects.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object whose rotation you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object passed straight through, so you can connect more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The object’s Pitch turn, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The object’s Yaw turn, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The object’s Roll turn, in degrees.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-do"><tbody><tr><td>**SceneNode** input</td><td>A door in your scene</td></tr><tr><td>**Pitch** output</td><td>`0`</td></tr><tr><td>**Yaw** output</td><td>`90`</td></tr><tr><td>**Roll** output</td><td>`0`</td></tr></tbody></table>

#### Tips

- Use this to check which way an object is facing before you decide how far to turn it.
- You only need the outputs you care about — for example, connect just **Yaw** and leave the others unused.

---

### Get Node Rotation (Local)

Reads how far an object is currently turned, measured relative to its parent or group.

#### What it does

This node looks at a single object in your scene and tells you its current turn as three numbers — Pitch, Yaw, and Roll — each measured in degrees (for example, `90` is a quarter turn and `180` is a half turn).

The rotation you get back is the object’s *local* turn: it is measured relative to the object’s parent or group. If that parent or group is later moved, turned, or resized, this local value stays the same. (If the object isn’t inside a parent or group, its local turn and its turn in the whole scene are the same.) This node only reads the value — it doesn’t turn the object or change anything else in your scene.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object whose current turn you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object passed straight through, so you can connect more nodes to it.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The object’s Pitch turn, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The object’s Yaw turn, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The object’s Roll turn, in degrees.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-do-0"><tbody><tr><td>**SceneNode** input</td><td>A door in your scene</td></tr><tr><td>**Pitch** output</td><td>`0`</td></tr><tr><td>**Yaw** output</td><td>`45`</td></tr><tr><td>**Roll** output</td><td>`0`</td></tr></tbody></table>

#### Tips

- Use this when you want to react to how an object is currently turned — for example, checking whether a door or valve has been turned far enough.
- To read the object’s turn in the whole scene instead of relative to its parent or group, use the matching node without “(Local)” in its name.

---

## Change the rotation

These turn an object to a new orientation. The plain versions change it instantly; the **(Animated)** versions glide to the new angle over a number of seconds. **Reset Rotation** returns an object to the orientation it had when the scene first loaded.

### Set Node Rotation

Turns a 3D object to face a specific direction in your scene.

#### What it does

This node sets the rotation of an object to the exact Pitch, Yaw, and Roll values you provide. The values are measured in degrees, where 90 is a quarter turn and 180 is a half turn. Whatever way the object was facing before, it now faces exactly the direction these three values describe.

The rotation is set in the whole scene, so the object ends up oriented the same way no matter where it sits or what group it belongs to. Only the object (or objects) you connect are affected — nothing else in the scene moves or turns. The same object is then passed straight out again, so you can keep working with it in the nodes that follow.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object (or objects) you want to turn.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch turn, in degrees. Leave at `0` for no Pitch turn.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw turn, in degrees. Leave at `0` for no Yaw turn.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll turn, in degrees. Leave at `0` for no Roll turn.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object (or objects) passed through, so you can chain more nodes.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch value you set, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw value you set, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll value you set, in degrees.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-si"><tbody><tr><td>**SceneNode** input</td><td>A signpost in your scene</td></tr><tr><td>**Pitch** input</td><td>`0`</td></tr><tr><td>**Yaw** input</td><td>`90`</td></tr><tr><td>**Roll** input</td><td>`0`</td></tr><tr><td>**SceneNode** output</td><td>The same signpost, now turned to its new orientation</td></tr></tbody></table>

#### Tips

- This sets the object to an exact orientation rather than turning it by an amount. Setting all three to `0` returns the object to facing straight along the scene’s default direction.

---

### Set Node Rotation (Animated)

Smoothly turns a 3D object to a new orientation over a set number of seconds.

#### What it does

This node turns one or more objects to face a new direction, set by three turn amounts measured in degrees: Pitch, Yaw, and Roll. Instead of snapping into place instantly, the object eases into its new orientation over the time you choose, so the motion looks smooth on screen.

The orientation you give is the object’s absolute orientation in the whole scene, not relative to any parent or group. The object keeps its current position and size — only its rotation changes — and other objects in the scene are left untouched.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to start the turn.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object (or objects) you want to turn.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch turn, in degrees (for example, `90` is a quarter turn). Leave at `0` for no turn on this axis.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw turn, in degrees. Leave at `0` for no turn on this axis.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll turn, in degrees. Leave at `0` for no turn on this axis.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How long the smooth turn takes, in seconds. Use a larger value for a slower, gentler turn. Must be zero or more.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires so the flow can continue once the turn has been applied.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object (or objects) passed through, so you can chain more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch value you gave, passed through for reuse.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw value you gave, passed through for reuse.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll value you gave, passed through for reuse.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>The Duration value, passed through for reuse.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-a-si-0"><tbody><tr><td>**SceneNode** input</td><td>A signpost object in your scene</td></tr><tr><td>**Pitch** input</td><td>`0`</td></tr><tr><td>**Yaw** input</td><td>`90`</td></tr><tr><td>**Roll** input</td><td>`0`</td></tr><tr><td>**Duration** input</td><td>`2`</td></tr><tr><td>**SceneNode** output</td><td>The same signpost, now smoothly turned to its new orientation over 2 seconds</td></tr></tbody></table>

#### Tips

- The turn amounts set the object’s final orientation in the scene — they are not added to its current angle each time the node runs.
- To turn an object instantly with no animation, use the non-animated version of this node instead.

---

### Set Node Rotation (Local)

Turns a 3D object to a specific orientation, measured relative to its parent or group.

#### What it does

This node sets how much an object is turned, using three values measured in degrees: Pitch, Yaw, and Roll. The turn is applied instantly — the object snaps to the orientation you give it.

The values are “local,” meaning they are measured relative to the object’s parent or group. If that parent or group is later moved, turned, or resized, this local orientation stays the same relative to it. If the object isn’t inside a parent or group, its local orientation is the same as its orientation in the whole scene. Only the object you connect is affected — other objects in the scene are left alone.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The 3D object you want to turn. You can connect more than one object, and each will be turned the same way.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch turn, in degrees (for example, `90` for a quarter turn). Leave at `0` for no turn on this one.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw turn, in degrees. Leave at `0` for no turn on this one.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll turn, in degrees. Leave at `0` for no turn on this one.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>Passes the same object (or objects) through, so you can chain more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch value you set, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw value you set, in degrees.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll value you set, in degrees.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the-"><tbody><tr><td>**SceneNode** input</td><td>The `Door` object</td></tr><tr><td>**Pitch** input</td><td>`0`</td></tr><tr><td>**Yaw** input</td><td>`90`</td></tr><tr><td>**Roll** input</td><td>`0`</td></tr><tr><td>**SceneNode** output</td><td>The same `Door` object, now turned, ready to pass to the next node</td></tr></tbody></table>

#### Tips

- This node sets the orientation outright — it doesn’t add to the current turn. Each value replaces what was there before.
- The turn happens instantly. If you want the object to turn smoothly over time, use the animated version of this node instead.

---

### Set Node Rotation (Local, Animated)

Smoothly turns an object to a new rotation over a set number of seconds, measured relative to its parent or group.

#### What it does

This node sets an object’s local rotation to the Pitch, Yaw, and Roll values you give it, all measured in degrees (for example, `90` is a quarter turn and `180` is a half turn). “Local” means the rotation is measured relative to the object’s parent or group: if that parent or group is later moved, turned, or resized, this object’s local rotation stays the same. If the object isn’t part of any parent or group, its local and world rotation are the same.

Because this is the animated version, the object turns smoothly to the new rotation over the number of seconds you set in Duration, rather than snapping to it instantly (the non-animated version changes it at once). Only the object you connect is affected — nothing else in the scene moves.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to start the turn.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to rotate. You can connect more than one object to rotate them all the same way.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch part of the target rotation, in degrees. Defaults to `0`.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw part of the target rotation, in degrees. Defaults to `0`.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll part of the target rotation, in degrees. Defaults to `0`.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>How many seconds the smooth turn should take. Must be zero or more; defaults to `2`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires so the flow can continue once the turn has been applied.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object (or objects) passed straight through, so you can connect more nodes after this one.</td></tr><tr><td style="white-space: nowrap;">**Pitch**</td><td style="white-space: nowrap;">Number</td><td>The Pitch value you set, passed through.</td></tr><tr><td style="white-space: nowrap;">**Yaw**</td><td style="white-space: nowrap;">Number</td><td>The Yaw value you set, passed through.</td></tr><tr><td style="white-space: nowrap;">**Roll**</td><td style="white-space: nowrap;">Number</td><td>The Roll value you set, passed through.</td></tr><tr><td style="white-space: nowrap;">**Duration**</td><td style="white-space: nowrap;">Number</td><td>The Duration value you set, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--0"><tbody><tr><td>**SceneNode** input</td><td>The `Door` object</td></tr><tr><td>**Pitch** input</td><td>`0`</td></tr><tr><td>**Yaw** input</td><td>`90`</td></tr><tr><td>**Roll** input</td><td>`0`</td></tr><tr><td>**Duration** input</td><td>`1.5`</td></tr><tr><td>**SceneNode** output</td><td>The same `Door` object, now smoothly turning to its new rotation over 1.5 seconds</td></tr></tbody></table>

#### Tips

- This node sets the rotation to an exact value rather than adding to the current one — the object ends up at the Pitch, Yaw, and Roll you give, wherever it started.
- Set Duration to `0` if you want the rotation applied right away with no smooth turn.
- Leave any of Pitch, Yaw, or Roll at `0` to keep that part of the rotation flat.

---

### Reset Rotation

Turns an object back to the way it was originally facing when the scene first loaded.

#### What it does

Every object remembers the orientation it started with when your scene opened. As your training plays, an object might get tipped, spun, or knocked over — by the user, by a physics step, or by other nodes. **Reset Rotation** snaps the object back to that original starting orientation, with no need to remember or type in any angles yourself.

The **Direction** choice lets you pick how much to reset. **All Directions** puts the object back exactly as it started. **Up Direction Only** stands the object back upright (as it originally stood) but leaves it facing whichever way it is currently turned — handy for setting a fallen item back on its feet without changing where it’s pointing. The object’s position and size are left alone; only its rotation changes, and no other object is affected.

#### Inputs

<table id="bkmrk-port-type-what-to-co-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output. The reset happens the moment this fires.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object (or objects) you want to set back to its original orientation. You can connect more than one.</td></tr><tr><td style="white-space: nowrap;">**Direction**</td><td style="white-space: nowrap;">Choice</td><td>How much to reset. Choose **All Directions** to restore the full original orientation, or **Up Direction Only** to stand the object upright again while keeping the way it is currently facing.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished, so you can continue to the next step.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object (or objects) passed straight through, so you can chain more nodes onto it.</td></tr><tr><td style="white-space: nowrap;">**Direction**</td><td style="white-space: nowrap;">Choice</td><td>The same choice you picked, passed through unchanged.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-%3Ccha"><tbody><tr><td>**SceneNode** input</td><td>`<Chair>` (an object that has been knocked over)</td></tr><tr><td>**Direction** input</td><td>`Up Direction Only`</td></tr><tr><td>**SceneNode** output</td><td>`<Chair>`, now standing upright again, still facing the same way it was</td></tr></tbody></table>

#### Tips

- Reset Rotation always returns to the orientation the object had when the scene first loaded — not to a flat, zeroed-out angle. If an object started out tilted, that original tilt is what comes back.
- Use **Up Direction Only** for things like setting a tipped-over tool or chair back on its feet while keeping the direction the user had turned it.
- This only changes rotation. To also return an object to its starting spot, pair it with a node that resets position.

# User \ Observe

These two nodes let one participant in a shared VR session **follow along with** another — for example so a trainee can shadow an instructor, or an instructor can keep an eye on a trainee. Start with **Observe User** and end with **Stop Observing**.

---

### Observe User

Lets one participant start watching another participant in a shared VR session — following along with what that person is doing.

#### What it does

In a session with more than one participant, this node makes the chosen **Observer** begin observing the chosen **Observed User**, so the observer can follow that person around the scene. It’s the natural partner of the **Stop Observing** node: observing carries on until you stop it (or start observing someone else). A common use is letting an instructor or a new participant follow an expert as they move through a training scene.

This only changes what the observer is following — it doesn’t move, change, or affect the person being observed in any way. Both participants come straight back out of the node, so you can keep working with either of them in the nodes that follow.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**Observer**</td><td style="white-space: nowrap;">User</td><td>The participant who will start watching. Choose **Host Only** for just the host, or **All Users** to have everyone start observing. Defaults to **Host Only**.</td></tr><tr><td style="white-space: nowrap;">**Observed User**</td><td style="white-space: nowrap;">User</td><td>The participant to be watched. This is always the **Host Only** participant.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once observing has started.</td></tr><tr><td style="white-space: nowrap;">**Observer**</td><td style="white-space: nowrap;">User</td><td>The same observer you chose, passed along so you can use them in the next node.</td></tr><tr><td style="white-space: nowrap;">**Observed User**</td><td style="white-space: nowrap;">User</td><td>The same observed participant, passed along so you can use them in the next node.</td></tr></tbody></table>

#### Example

<table id="bkmrk-observer-input-all-u"><tbody><tr><td style="white-space: nowrap;">**Observer** input</td><td>`All Users` — everyone starts observing</td></tr><tr><td style="white-space: nowrap;">**Observed User** input</td><td>`Host Only` — the host is the one being watched</td></tr><tr><td style="white-space: nowrap;">**Observer** output</td><td>The same participants, ready to chain into another user node</td></tr></tbody></table>

#### Tips

- Pair this with the **Stop Observing** node when you want a participant to stop following and return to controlling their own view.
- To switch who someone is following, just run **Observe User** again with a different observed participant — you don’t need to stop first.

---

### Stop Observing

Ends the “follow another person” view for a participant, returning them to their own viewpoint.

#### What it does

When a participant is observing someone else — seeing the scene through that other person’s eyes — this node stops that following. The chosen participant goes back to controlling and seeing their own view again.

This is the partner to the “Observe User” node, which starts the following. Use Stop Observing to release a participant once they no longer need to follow along. It only changes who that participant is watching; it doesn’t move anyone, change the scene, or affect the person who was being watched.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Observer**</td><td style="white-space: nowrap;">User</td><td>Choose which participant stops following: **Host Only** or **All Users**. This is the person whose view returns to normal. You can also wire in a User passed along from an earlier node.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the participant has stopped observing, so you can continue to the next node.</td></tr><tr><td style="white-space: nowrap;">**Observer**</td><td style="white-space: nowrap;">User</td><td>Passes the same participant along, so you can chain more user nodes after this one.</td></tr></tbody></table>

#### Example

<table id="bkmrk-observer-input-host-"><tbody><tr><td style="white-space: nowrap;">**Observer** input</td><td>`Host Only`</td></tr><tr><td style="white-space: nowrap;">**Observer** output</td><td>The same participant, now back to their own view — ready to pass to the next user node.</td></tr></tbody></table>

#### Tips

- Pair this with the “Observe User” node: one starts the following, this one ends it.
- Pick **All Users** to bring everyone back to their own view at the same time — handy at the end of a guided walkthrough.

# SceneNode \ Attributes

Every object in your scene can carry extra pieces of information called **attributes** — small named values you attach to an object and read back later. Attributes can also be grouped into named **categories**, which lets one object keep separate attributes that share a name. The nodes on this page let you add, read, check for, and remove attributes, both on their own and inside a category.

Attributes are saved with the object. Reading one never changes it; setting or removing one changes only that single attribute and leaves the rest of the object untouched. There are also event nodes that react the moment an attribute is added, changed, or removed on an object — those are documented on the **Node Attribute Events** page.

## Get a node attribute

### Get Node Attribute (String)

Reads a named attribute from a scene object and gives it back as a piece of text.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a piece of text. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold text. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the-"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`label`</td></tr><tr><td>**Result** output</td><td>`Forklift A`</td></tr></tbody></table>

### Get Node Attribute (Number)

Reads a named attribute from a scene object and gives it back as a number.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a number. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a number. If it is missing, or what is stored cannot be read as a number, the node stops with an error instead of giving you a result — so check with **Node Has Attribute** first if you are not sure.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--0"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`maxLoad`</td></tr><tr><td>**Value** output</td><td>`1500`</td></tr></tbody></table>

### Get Node Attribute (Boolean)

Reads a named attribute from a scene object and gives it back as a true / false value.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a true / false value. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a true / false value. If it is missing, or what is stored cannot be read as a true / false value, the node stops with an error instead of giving you a result — so check with **Node Has Attribute** first if you are not sure.

Saved values of `true`, `yes` or `on` are read as true, and `false`, `no` or `off` are read as false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--1"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`inspected`</td></tr><tr><td>**Result** output</td><td>`true`</td></tr></tbody></table>

### Get Node Attribute (SceneNode)

Reads a named attribute from a scene object and gives it back as a scene node.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a scene node. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a scene node. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--2"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`assignedTo`</td></tr><tr><td>**Result** output</td><td>`<Operator>`</td></tr></tbody></table>

### Get Node Attribute (SceneState)

Reads a named attribute from a scene object and gives it back as a scene state.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a scene state. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a scene state. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--3"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`savedView`</td></tr><tr><td>**Result** output</td><td>`<FrontView>`</td></tr></tbody></table>

### Get Node Attribute (Sequence)

Reads a named attribute from a scene object and gives it back as a sequence.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a sequence. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a sequence. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--4"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`startupRoutine`</td></tr><tr><td>**Result** output</td><td>`<PowerOn>`</td></tr></tbody></table>

### Get Node Attribute (Variable)

Reads a named attribute from a scene object and gives it back as a variable.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node looks for the attribute called the name you provide on the object you connect and hands its value back as a variable, ready to pass on to any node that works with variables. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-5"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Variable</td><td>The value stored in the attribute, handed back as a variable.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--5"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`serviceCount`</td></tr><tr><td>**Result** output</td><td>a variable holding `12`</td></tr></tbody></table>

## Set a node attribute

### Set Node Attribute (String)

Saves a piece of text onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores a piece of text in it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-6"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--6"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`label`</td></tr><tr><td>**Value** input</td><td>`Forklift A`</td></tr></tbody></table>

### Set Node Attribute (Number)

Saves a number onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores a number in it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-7"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--7"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`maxLoad`</td></tr><tr><td>**Value** input</td><td>`1500`</td></tr></tbody></table>

### Set Node Attribute (Boolean)

Saves a true / false value onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores a true / false value in it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-8"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--8"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`inspected`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`true`</td></tr></tbody></table>

### Set Node Attribute (SceneNode)

Saves a scene node onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores a scene node in it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-9"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--9"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`assignedTo`</td></tr><tr><td>**Value** input</td><td>`<Operator>`</td></tr></tbody></table>

### Set Node Attribute (SceneState)

Saves a scene state onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores a scene state in it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-10"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--10"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`savedView`</td></tr><tr><td>**Value** input</td><td>`<FrontView>`</td></tr></tbody></table>

### Set Node Attribute (Sequence)

Saves a sequence onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores a sequence in it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-11"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--11"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`startupRoutine`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`<PowerOn>`</td></tr></tbody></table>

### Set Node Attribute (Variable)

Saves the value held in a variable onto a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. This node attaches the attribute called the name you provide to the object you connect and stores the value held in the variable you give it. If the object already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Variable</td><td>The variable whose value you want to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-12"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Variable</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--12"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`serviceCount`</td></tr><tr><td>**Value** input</td><td>a variable holding `12`</td></tr></tbody></table>

## Check or remove a node attribute

### Node Has Attribute

Checks whether a scene object has an attribute with a given name.

#### What it does

This node looks at the object you connect and tells you whether it already has an attribute saved under the name you provide. You get back **true** if it does and **false** if it does not. It only checks — nothing on the object is changed.

It is handy to run before reading or changing an attribute, to be sure it is there.

#### Inputs

<table id="bkmrk-port-type-what-to-co-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to check.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to look for.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-13"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>**True** if the attribute exists, otherwise **false**.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--13"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`inspected`</td></tr><tr><td>**Result** output</td><td>**true** — the attribute exists</td></tr></tbody></table>

### Remove Node Attribute

Deletes a named attribute from a scene object.

#### What it does

This node removes the attribute saved under the name you provide from the object you connect. That one attribute and its value are deleted from the object; everything else about the object stays the same.

If the object has no attribute with that name, nothing happens.

#### Inputs

<table id="bkmrk-port-type-what-to-co-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to remove the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to remove.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-14"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--14"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`tempNote`</td></tr></tbody></table>

## Get a node attribute in a category

### Get Node Attribute in Category (String)

Reads a named attribute kept in a category on a scene object and gives it back as a piece of text.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect and hands its value back as a piece of text. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold text. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-15"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-15"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The text stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--15"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`label`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>`Forklift A`</td></tr></tbody></table>

### Get Node Attribute in Category (Number)

Reads a named attribute kept in a category on a scene object and gives it back as a number.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect and hands its value back as a number. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a number. If it is missing, or what is stored cannot be read as a number, the node stops with an error instead of giving you a result — so check with **Node Has Attribute In Category** first if you are not sure.

#### Inputs

<table id="bkmrk-port-type-what-to-co-16"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-16"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Number</td><td>The number stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--16"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`maxLoad`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>`1500`</td></tr></tbody></table>

### Get Node Attribute in Category (Boolean)

Reads a named attribute kept in a category on a scene object and gives it back as a true / false value.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect and hands its value back as a true / false value. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a true / false value. If it is missing, or what is stored cannot be read as a true / false value, the node stops with an error instead of giving you a result — so check with **Node Has Attribute In Category** first if you are not sure.

Saved values of `true`, `yes` or `on` are read as true, and `false`, `no` or `off` are read as false.

#### Inputs

<table id="bkmrk-port-type-what-to-co-17"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-17"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--17"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`inspected`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>`true`</td></tr></tbody></table>

### Get Node Attribute in Category (SceneNode)

Reads a named attribute kept in a category on a scene object and gives it back as a scene node.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect and hands its value back as a scene node. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a scene node. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-18"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-18"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--18"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`assignedTo`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>`<Operator>`</td></tr></tbody></table>

### Get Node Attribute in Category (SceneState)

Reads a named attribute kept in a category on a scene object and gives it back as a scene state.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect and hands its value back as a scene state. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a scene state. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-19"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-19"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--19"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`savedView`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>`<FrontView>`</td></tr></tbody></table>

### Get Node Attribute in Category (Sequence)

Reads a named attribute kept in a category on a scene object and gives it back as a sequence.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect and hands its value back as a sequence. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist and hold a sequence. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-20"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-20"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence stored in the attribute.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--20"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`startupRoutine`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>`<PowerOn>`</td></tr></tbody></table>

### Get Node Attribute in Category (Variable)

Reads a named attribute kept in a category on a scene object and gives it back as a variable.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node looks for the attribute called the name you provide inside the category you name, on the object you connect, and hands its value back as a variable. It only reads the object — it does not change the object or the attribute in any way.

The attribute should already exist. If it is missing, you get an empty result rather than an error, so it is still worth checking with **Node Has Attribute In Category** first.

#### Inputs

<table id="bkmrk-port-type-what-to-co-21"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to read the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute you want to read.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category the attribute is kept in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-21"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Variable</td><td>The value stored in the attribute, handed back as a variable.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--21"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`serviceCount`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>a variable holding `12`</td></tr></tbody></table>

## Set a node attribute in a category

### Set Node Attribute in Category (String)

Saves a piece of text into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores a piece of text in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-22"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-22"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--22"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`label`</td></tr><tr><td style="white-space: nowrap;">**Category** input</td><td>`Maintenance`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`Forklift A`</td></tr></tbody></table>

### Set Node Attribute in Category (Number)

Saves a number into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores a number in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-23"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The number to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-23"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Number</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--23"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`maxLoad`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Value** input</td><td>`1500`</td></tr></tbody></table>

### Set Node Attribute in Category (Boolean)

Saves a true / false value into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores a true / false value in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-24"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The true / false value to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-24"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">True / false</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--24"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`inspected`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Value** input</td><td>`true`</td></tr></tbody></table>

### Set Node Attribute in Category (SceneNode)

Saves a scene node into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores a scene node in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-25"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The scene node to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-25"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene node</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--25"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`assignedTo`</td></tr><tr><td style="white-space: nowrap;">**Category** input</td><td>`Maintenance`</td></tr><tr><td style="white-space: nowrap;">**Value** input</td><td>`<Operator>`</td></tr></tbody></table>

### Set Node Attribute in Category (SceneState)

Saves a scene state into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores a scene state in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-26"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The scene state to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-26"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Scene state</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--26"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`savedView`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Value** input</td><td>`<FrontView>`</td></tr></tbody></table>

### Set Node Attribute in Category (Sequence)

Saves a sequence into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores a sequence in it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-27"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The sequence to save a link to.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-27"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Sequence</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--27"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`startupRoutine`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Value** input</td><td>`<PowerOn>`</td></tr></tbody></table>

### Set Node Attribute in Category (Variable)

Saves the value held in a variable into a category on a scene object as a named attribute.

#### What it does

Every object in your scene can carry extra pieces of information called **attributes**, each one saved under a name you choose. Attributes can also be grouped into named **categories**, so a single object can keep separate attributes that share a name in different categories. This node attaches the attribute called the name you provide, inside the category you name, to the object you connect and stores the value held in the variable you give it. If that category already has an attribute with that name, its value is replaced; if not, the attribute is created.

The value you provide is also sent straight back out, so you can keep using it further along.

#### Inputs

<table id="bkmrk-port-type-what-to-co-28"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to add or change the attribute on.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name to save the attribute under.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to keep the attribute in.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Variable</td><td>The variable whose value you want to store.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-28"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Variable</td><td>The same value you stored, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--28"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`serviceCount`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Value** input</td><td>a variable holding `12`</td></tr></tbody></table>

## Check, list, or remove attributes in a category

### Node Has Attribute In Category

Checks whether a scene object has an attribute with a given name inside a category.

#### What it does

This node looks at the object you connect and tells you whether it already has an attribute saved under the name you provide inside the category you name. You get back **true** if it does and **false** if it does not. It only checks — nothing on the object is changed.

#### Inputs

<table id="bkmrk-port-type-what-to-co-29"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to check.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to look for.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to look in.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-29"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>**True** if the attribute exists in that category, otherwise **false**.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--29"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td style="white-space: nowrap;">**Attribute Name** input</td><td>`inspected`</td></tr><tr><td style="white-space: nowrap;">**Category** input</td><td>`Maintenance`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>**true** — the attribute exists</td></tr></tbody></table>

### Get Node Attribute Category Names

Lists the names of the attributes kept inside a category on a scene object.

#### What it does

Attributes on an object can be grouped into named **categories**. This node looks at the object you connect and gives you back the names of the attributes that are stored inside the category you name. The names come back as a list of separate pieces of text, so you can connect a node that steps through a list to handle them one at a time. It only reads the object — nothing is changed.

#### Inputs

<table id="bkmrk-port-type-what-to-co-30"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to look at.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category whose attribute names you want.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-30"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">Text</td><td>The names of the attributes found in that category, returned as a list of separate pieces of text. Connect a node that steps through a list to read them one by one.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--30"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr><tr><td>**Result** output</td><td>a list of names — e.g. `inspected`, `maxLoad`, `assignedTo`</td></tr></tbody></table>

### Remove Node Attribute From Category

Deletes a named attribute that is kept in a category on a scene object.

#### What it does

This node removes the attribute saved under the name you provide, inside the category you name, from the object you connect. That one attribute and its value are deleted from that category; everything else about the object stays the same.

If no attribute with that name exists in the category, nothing happens.

#### Inputs

<table id="bkmrk-port-type-what-to-co-31"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s **Execute** output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The scene object you want to remove the attribute from.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The name of the attribute to remove.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The name of the category to remove it from.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-31"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same object you connected, passed straight through so you can keep using it.</td></tr><tr><td style="white-space: nowrap;">**Attribute Name**</td><td style="white-space: nowrap;">Text</td><td>The attribute name you provided, passed through.</td></tr><tr><td style="white-space: nowrap;">**Category**</td><td style="white-space: nowrap;">Text</td><td>The category name you provided, passed through.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-the--31"><tbody><tr><td>**SceneNode** input</td><td>the `<Forklift>` object</td></tr><tr><td>**Attribute Name** input</td><td>`tempNote`</td></tr><tr><td>**Category** input</td><td>`Maintenance`</td></tr></tbody></table>

# SceneNode \ Assembly

These nodes work with a part’s **assembly state** in a VR assembly. In SimLab’s assembly system a part moves through three stages — think of a screw: all the way out (**fully disassembled**), dropped into place but not tightened (**partially assembled**), or tightened all the way down (**fully assembled**). One node reads a part’s current state; the other sets a part to a state you choose.

These are run-once actions — they do their work the moment they are triggered. To *continuously watch* a part and react the instant it becomes assembled or taken apart, use the assembly **state** nodes on the **Assembly** page; for assembly **events**, see the **Events** page.

## What’s on this page

- **Get Node Assembly State** — read a part’s current state as text (Fully Assembled, Partially Assembled, or Fully Disassembled).
- **Set Node Assembly State** — set a part to a chosen state.

---

### Get Node Assembly State

Checks one part in a VR assembly and tells you, as a short piece of text, how far along it is — fully together, fully apart, or somewhere in between.

#### What it does

Give this node a part from your scene and run it, and it reports that part’s current assembly state. In SimLab’s assembly system a part moves through three stages — think of a screw: all the way out (fully apart), dropped into place but not yet tightened (partway together), or tightened down (fully together). The node hands you back one of three words for exactly that: `Fully Assembled`, `Fully Disassembled`, or `Partially Assembled`.

It only reads the part’s state — it never moves, tightens, or changes the part in any way. Because the answer comes back as text, you can show it on screen, compare it, or branch on it to drive the rest of your scene.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output. The node checks the part’s state the moment this fires.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to check — for example a `Bolt_01` object from your assembly. The node reports on this part’s own assembly state.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished. Wire it to whatever should happen next.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same part you connected, passed straight back out unchanged so you can keep wiring from it to the next node.</td></tr><tr><td style="white-space: nowrap;">**State**</td><td style="white-space: nowrap;">Text</td><td>The part’s current state as text — one of `Fully Assembled`, `Fully Disassembled`, or `Partially Assembled`. Show it on screen, or compare it to decide what your scene does next.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Bolt_01` — the same part, handed back so you can keep wiring from it</td></tr><tr><td style="white-space: nowrap;">**State** output</td><td>`Partially Assembled` — the bolt has been dropped into place but not yet tightened all the way down</td></tr></tbody></table>

#### Tips

- A part that is dropped into place but not tightened comes back as `Partially Assembled` — `Fully Assembled` means the part is both in place *and* secured.
- Because the answer is text, compare it against one of the three exact words (such as `Fully Assembled`) when you want your scene to react to a particular state.
- This node reads the state at the moment you run it. To react the instant a part becomes fully together or fully apart instead, use the matching state nodes on the **Assembly** page.

---

### Set Node Assembly State

Forces a part in your scene into a chosen assembly state — fully assembled, fully disassembled, or partially assembled.

#### What it does

Pick a part (a scene node) and a state, and this node sets that part to the state you chose. Use `Fully Assembled` to mark it as completely put together, `Fully Disassembled` to mark it as fully taken apart, or `Partially Assembled` for the in-between stage. This is handy for setting up a starting condition — for example, putting a model into its fully disassembled state at the beginning of a training exercise so the trainee can build it up.

The part you pass in is handed straight back out unchanged, so you can keep wiring more steps onto the same part right after this one.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part whose assembly state you want to set. You can connect more than one part to set them all at once.</td></tr><tr><td style="white-space: nowrap;">**State**</td><td style="white-space: nowrap;">Choice</td><td>The state to apply: `Fully Assembled`, `Fully Disassembled`, or `Partially Assembled`. Defaults to `Fully Assembled`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The same part you connected, passed straight back out unchanged so you can keep wiring from it.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-engi"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Engine_Block`</td></tr><tr><td style="white-space: nowrap;">**State** input</td><td>`Fully Disassembled` — sets the engine to its fully taken-apart state at the start of the lesson</td></tr><tr><td style="white-space: nowrap;">**SceneNode** output</td><td>`Engine_Block` — the same part, handed back so you can chain the next step onto it</td></tr></tbody></table>

#### Tips

- Use this to set up a known starting point — for example, fully assembled to begin a disassembly drill, or fully disassembled to begin an assembly drill.
- `Partially Assembled` marks the part as neither fully together nor fully apart, which is useful for picking up a scenario midway through.

# Variable

Nodes for working with **variables** — the named values your scene keeps and reuses, each holding a number, a piece of text, or a time.

### Cast Variable

Checks whether a variable holds the kind of value you expect, and only passes it along when it does.

#### What it does

A variable can hold different kinds of values — a number, some text, or a time. This node looks at the variable you give it and compares its actual kind to the kind you pick in **SubType**. If they match, you get the same variable back, unchanged. If they don’t match, you get nothing back.

Think of it as a safety check: it lets a value continue only when it is the type you were counting on. It never changes the original variable — it simply hands the same value through, or holds it back.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Variable**</td><td style="white-space: nowrap;">Variable</td><td>The variable you want to check.</td></tr><tr><td style="white-space: nowrap;">**SubType**</td><td style="white-space: nowrap;">Choice</td><td>The kind of value you expect the variable to hold. Pick `Number`, `String` (text), or `Time`.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the node has finished.</td></tr><tr><td style="white-space: nowrap;">**Variable**</td><td style="white-space: nowrap;">Variable</td><td>The same variable, passed straight through when its kind matches the chosen SubType. If the kind does not match, you get nothing here.</td></tr></tbody></table>

#### Example

<table id="bkmrk-variable-input-a-var"><tbody><tr><td>**Variable** input</td><td>A variable holding `42`</td></tr><tr><td>**SubType** input</td><td>`Number`</td></tr><tr><td>**Variable** output</td><td>The same variable holding `42` (the kinds match). Had you chosen `String` instead, nothing would come out.</td></tr></tbody></table>

#### Tips

- Use this before a step that only makes sense for one kind of value — the value continues only when it is the type you picked.
- This node checks the kind of value; it does not convert it. A number stays a number — it is simply allowed through or held back.

# Cloud \ Dynamic Attributes

The **Dynamic Cloud Attribute** nodes save and read small pieces of text in SimLab’s cloud, so a VR experience can remember information between sessions and across devices — a person’s progress, a saved choice, a score, and so on.

They are the flexible counterpart to the older **Get Cloud Attribute** and **Set Cloud Attribute** nodes. The difference is how a saved value is identified. The older nodes use a single fixed **name** that you type into the node. These nodes instead identify each value by a **Key** — a structured value (a JSON object) that can hold one field or several, which you build with the JSON Object nodes. Because a key can carry several pieces of information at once (for example a category *and* a level), one node can manage a whole family of related values, and the **Search** node can find many of them at once by matching only part of a key.

## What’s on this page

- **Set Dynamic Cloud Attribute** — save a value, creating it or replacing what was there.
- **Soft Set Dynamic Cloud Attribute (String)** — save a value only if nothing is stored under that key yet.
- **Get Dynamic Cloud Attribute** — read back the value saved under a key.
- **Search Dynamic Cloud Attribute** — find every value whose key matches the fields you give.
- **Check Dynamic Cloud Attribute Exists** — check whether a value is saved under a key, without reading it.
- **Remove Dynamic Cloud Attribute** — delete the value saved under a key.

## How these nodes work

All six nodes share the same few ideas.

### The Key

Every value is filed under a **Key** — a JSON object you build with the JSON Object nodes. A key can hold a single field or several (for example `{ "category": "progress", "level": "2" }`). To read, check, or remove a value later, give the same Key you saved it under. A Key cannot be empty.

### Who the value belongs to — Data Owner

Each node has a **Data Owner** choice that decides whose data the value is part of:

- **User** — the data of the individual person running the experience. Each person has their own separate values.
- **Publisher** — data that belongs to the experience’s publisher, the account that created and published the experience. This data is part of the experience itself rather than any single person’s own data.

### They talk to the cloud

Because these nodes contact a server, they wait for the cloud to answer before carrying on: the **Execute** output fires only once the cloud has replied — whether the request worked or not. Every node has a **Success** output that is true only when the request genuinely worked; always send it into a **Branch** and trust the result only on the “true” side. The experience must be running from a signed-in account for cloud data to work.

## Saving values

### Set Dynamic Cloud Attribute

Saves a piece of text in SimLab’s cloud so your experience can remember it later, even after the person closes it or switches to another device.

#### What it does

This node stores the text you give it under a **Key** that you build with the JSON Object nodes. The Key is how the saved value is found again later — instead of one fixed name, you can put several pieces of information into the Key (such as a category and a level) so that one node can manage a whole family of saved values.

If nothing has been saved under that Key yet, a new value is created. If something is already saved under that exact same Key, its text is replaced with the new text. Other saved values, under different Keys, are left untouched. Because this node talks to the cloud, it waits for the cloud to answer before continuing, and it reports whether the save genuinely worked through the **Success** output. For cloud data to work, the experience must be running from a signed-in account.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Key**</td><td style="white-space: nowrap;">JSON object</td><td>The Key that identifies this saved value, built with the JSON Object nodes. It can hold one or several name/value fields. The Key cannot be empty.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text you want to save under this Key.</td></tr><tr><td style="white-space: nowrap;">**Data Owner**</td><td style="white-space: nowrap;">Choice</td><td>Who this saved value belongs to. Choose **User** to save it for the individual person running the experience (their own data), or **Publisher** to save it on the experience’s publisher account — the account that created and published the experience.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the cloud has answered, whether the save worked or not. Always check **Success** before trusting the result.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>True only when the value was genuinely saved; false if something went wrong. Wire this into a Branch so your experience can react to either case.</td></tr></tbody></table>

#### Example

<table id="bkmrk-key-input-a-json-obj"><tbody><tr><td>**Key** input</td><td>a JSON object like `{ "category": "progress", "level": "2" }`</td></tr><tr><td>**Value** input</td><td>`completed`</td></tr><tr><td>**Data Owner** input</td><td>`User`</td></tr><tr><td>**Success** output</td><td>`true` once the value has been saved</td></tr></tbody></table>

#### Tips

- Build the Key with the JSON Object nodes before this node runs, and use the same Key later when you want to read the value back.
- To play it safe, send the **Success** output into a Branch — continue only when it is true, and show a message or retry when it is false.
- Saving again with the very same Key replaces the old text, so you can use this node to keep an up-to-date value (like a person’s latest progress).

### Soft Set Dynamic Cloud Attribute (String)

Saves a piece of text in the cloud under a key you build yourself — but only the first time, so it never overwrites a value that is already stored there.

#### What it does

This node stores a bit of text in SimLab’s cloud so your experience can remember it between sessions and across devices. Instead of a fixed name typed into the node, the saved value is identified by a **Key** — a JSON object you build with the JSON Object nodes. The key can carry one field or several (for example a category and a level), so a single node can manage a whole family of saved values.

The word “Soft” is the important part: this node only writes when nothing is saved under that key yet. If a value is already there, it is left exactly as it is — nothing is overwritten. Use this when you want to set a starting value once and then leave it alone. Only the value under this one key is affected; everything else you have saved stays untouched.

Because the node talks to the cloud, it waits for the cloud to answer before moving on. Always check the **Success** result (wire it into a Branch) before trusting that the value is in place. A `true` result means that after this node the key holds a value — either the text you just wrote, or the one that was already there. The experience must be running from a signed-in account for cloud data to work.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to run the node.</td></tr><tr><td style="white-space: nowrap;">**Key**</td><td style="white-space: nowrap;">JSON object</td><td>The key that identifies this saved value — a JSON object you build with the JSON Object nodes. It can hold one field or several (for example a category and a level). It cannot be empty.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The text to save — but only if nothing is stored under this key yet.</td></tr><tr><td style="white-space: nowrap;">**Data Owner**</td><td style="white-space: nowrap;">Choice</td><td>Who the saved value belongs to. Choose **User** to save it for the individual person running the experience (their own data), or **Publisher** to save it on the experience’s publisher account — the account that created and published the experience.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the cloud has answered, whether the call worked or not. Check Success before continuing.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>True when the key holds a value after this node runs — either the text you just saved, or the one that was already there. False means the cloud could not be reached or you are not signed in.</td></tr></tbody></table>

#### Example

<table id="bkmrk-key-input-a-json-obj-0"><tbody><tr><td>**Key** input</td><td>a JSON object such as `{ "category": "progress", "level": "1" }`</td></tr><tr><td>**Value** input</td><td>`not started`</td></tr><tr><td>**Data Owner** input</td><td>`User`</td></tr><tr><td>**Success** output</td><td>`true` — the starting status is now saved (or was already saved from a previous run)</td></tr></tbody></table>

#### Tips

- Use this node to set a one-time starting value, like a person’s initial progress. If you instead want to change a value every time, use the **Set Dynamic Cloud Attribute** node, which always overwrites.
- Build the Key with the JSON Object nodes before this node runs, and keep it consistent so you can read the same value back later.
- Always wire Success into a Branch so your experience can react if the cloud could not be reached.

## Reading and finding values

### Get Dynamic Cloud Attribute

Reads back a piece of saved text from SimLab’s cloud, looking it up by the key it was saved under.

#### What it does

This node fetches a value that was previously saved to the cloud and hands it back to you as text. Instead of identifying the saved value by a fixed name typed into the node, you identify it with a **Key** — a JSON object you build with the JSON Object nodes. Because a key can hold one or several name/value fields, a single node can look up a whole family of saved values (for example, the saved status for a different level each time).

Reading a value never changes it — this node only looks, it doesn’t save anything, and other saved values are left untouched. Because it talks to a server, the node waits for the cloud to answer before it continues. The **Execute** output fires once the cloud has replied, whether or not it found anything, so always check the **Success** output (wire it into a Branch) before trusting the result. The experience must be running from a signed-in account for cloud data to work.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Key**</td><td style="white-space: nowrap;">JSON object</td><td>The key that identifies the saved value you want to read. Build it with the JSON Object nodes — it can carry one or several name/value fields. It must match the key the value was saved under, and it cannot be empty.</td></tr><tr><td style="white-space: nowrap;">**Data Owner**</td><td style="white-space: nowrap;">Choice</td><td>Who the saved value belongs to. Choose **User** to read data saved for the individual person running the experience, or **Publisher** to read data that belongs to the experience’s publisher — the account that created and published the experience.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the cloud has answered, whether the call worked or not. Continue your flow from here.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>`true` only when the value was found and read back successfully. It is `false` if the call failed or if no saved value matched the key. Check this before using the result.</td></tr><tr><td style="white-space: nowrap;">**Value**</td><td style="white-space: nowrap;">Text</td><td>The saved text that was read back. It is empty when Success is `false`.</td></tr></tbody></table>

#### Example

<table id="bkmrk-key-input-%7B-%22categor"><tbody><tr><td>**Key** input</td><td>`{ "category": "progress", "level": "3" }`</td></tr><tr><td>**Data Owner** input</td><td>`User`</td></tr><tr><td>**Success** output</td><td>`true`</td></tr><tr><td>**Value** output</td><td>`completed`</td></tr></tbody></table>

#### Tips

- Build the same key here that you used when saving the value with the **Set Dynamic Cloud Attribute** node — if the key doesn’t match, nothing is found and Success comes back `false`.
- Always send the Success output into a Branch so your flow can react cleanly when a value is missing or the cloud couldn’t be reached.

### Search Dynamic Cloud Attribute

Finds every value saved in SimLab’s cloud whose key matches the fields you give it, so you can look up a whole group of related saved values at once.

#### What it does

Each value you save in the cloud is filed under a Key — a set of name/value fields you build with the JSON Object nodes (for example a category and a level). This node lets you search by only *part* of a key: you supply a Partial Key with just the fields you care about, and it returns every saved value whose key contains those fields. For example, give it just the category and you get back every value saved under that category, across all the levels.

You get back two matching lists: one with the full keys of everything it found, and one with the saved text for each, lined up in the same order — the first key goes with the first value, the second with the second, and so on. Because this node talks to the cloud, it waits for the cloud to answer before moving on, and it tells you through the Success output whether the lookup actually worked. Searching only reads your saved values; it never changes them.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Partial Key**</td><td style="white-space: nowrap;">JSON object</td><td>The fields to search for, built with the JSON Object nodes. Include only the parts of the key you want to match on — every saved value whose key contains these fields is returned. This must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Data Owner**</td><td style="white-space: nowrap;">Choice</td><td>Who the saved values belong to. Choose **User** to search the data of the individual person running the experience, or **Publisher** to search data that belongs to the experience’s publisher — the account that created and published the experience.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the cloud has answered, whether the search worked or not. Always check Success before using the result.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>True only when the cloud genuinely answered the search. If it is false, both lists come back empty.</td></tr><tr><td style="white-space: nowrap;">**Keys**</td><td style="white-space: nowrap;">JSON array</td><td>A list of the full keys of every saved value that matched, one entry per match.</td></tr><tr><td style="white-space: nowrap;">**Values**</td><td style="white-space: nowrap;">JSON array</td><td>A list of the saved text for each match, in the same order as Keys — the first value goes with the first key, and so on.</td></tr></tbody></table>

#### Example

<table id="bkmrk-partial-key-input-a-"><tbody><tr><td>**Partial Key** input</td><td>a JSON object holding just `{ "category": "progress" }` — matching every value saved under that category</td></tr><tr><td>**Data Owner** input</td><td>`User`</td></tr><tr><td>**Success** output</td><td>`true`</td></tr><tr><td>**Keys** output</td><td>a list such as `[ {"category":"progress","level":"1"}, {"category":"progress","level":"2"} ]`</td></tr><tr><td>**Values** output</td><td>a list such as `[ "completed", "in progress" ]` — lined up with the keys above</td></tr></tbody></table>

#### Tips

- Wire Success into a Branch node and only read the Keys and Values lists when it is true.
- The two lists always match up by position, so step through them together when you process the results.
- The more fields you put in the Partial Key, the narrower the search; include fewer fields to find a wider group of saved values.

### Check Dynamic Cloud Attribute Exists

Asks SimLab’s cloud whether a saved value with a given key already exists, without reading or changing it.

#### What it does

This node looks up whether a value you previously saved in the cloud is there or not. You hand it a Key — a JSON object you build with the JSON Object nodes — and it reports back “yes, something is saved under this key” or “no, nothing is saved here yet.” It does not return the saved value itself, and it never changes anything; it only checks.

Because this node talks to the cloud, it waits for the cloud to answer before moving on. The result comes back in two parts: **Success** tells you whether the check itself worked, and **Exists** tells you whether a value was found. Always check **Success** first (wire it into a Branch) — if the call did not work, the **Exists** answer cannot be trusted. The experience must be running from a signed-in account for cloud data to work.

#### Inputs

<table id="bkmrk-port-type-what-to-co-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output to run the check.</td></tr><tr><td style="white-space: nowrap;">**Key**</td><td style="white-space: nowrap;">JSON object</td><td>The key that identifies the saved value you want to look for. Build it with the JSON Object nodes — it can hold one or several name/value fields. It must not be empty.</td></tr><tr><td style="white-space: nowrap;">**Data Owner**</td><td style="white-space: nowrap;">Choice</td><td>Who the saved value belongs to. Choose **User** to look in the data saved for the individual person running the experience, or **Publisher** to look in data that belongs to the experience’s publisher — the account that created and published the experience.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-3"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the cloud has answered, whether the check worked or not. Continue your flow from here.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>True only when the check genuinely worked. If it is false (for example, the account was not signed in), ignore the Exists result.</td></tr><tr><td style="white-space: nowrap;">**Exists**</td><td style="white-space: nowrap;">True / false</td><td>True if a saved value was found for this key, false if nothing is saved under it yet. Only meaningful when Success is true.</td></tr></tbody></table>

#### Example

<table id="bkmrk-key-input-a-json-obj-1"><tbody><tr><td>**Key** input</td><td>a JSON object like `{ "category": "progress", "level": "fire-safety-1" }`</td></tr><tr><td>**Data Owner** input</td><td>`User`</td></tr><tr><td>**Success** output</td><td>`true` — the cloud answered correctly</td></tr><tr><td>**Exists** output</td><td>`true` — progress is already saved for this level</td></tr></tbody></table>

#### Tips

- Use this node to decide whether to load existing progress or start fresh — check Exists, then branch to either read the saved value or save a new one.
- Build the same Key the same way every time you save and check, so the check finds the right value.

## Removing values

### Remove Dynamic Cloud Attribute

Deletes one saved value from the cloud — the one whose Key you provide.

#### What it does

Every Dynamic Cloud value is saved under a Key — a bundle of name/value fields you build with the JSON Object nodes (for example a category and a level). This node looks up the value saved under the Key you give it and removes it from the cloud. Only that one value is affected; every other saved value stays exactly as it was.

Because this node talks to the cloud, it waits for the cloud to answer before it continues. When the answer comes back, the **Success** output tells you whether it worked. Deleting a value that was already gone still counts as a success — the end result is the same: there is nothing saved under that Key. A real problem (such as not being signed in) gives Success as false. Always send Success into a Branch and only trust the outcome when it is true. The experience must be running from a signed-in account for cloud data to work.

#### Inputs

<table id="bkmrk-port-type-what-to-co-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Wire this from the previous node’s Execute output.</td></tr><tr><td style="white-space: nowrap;">**Key**</td><td style="white-space: nowrap;">JSON object</td><td>The Key that identifies the saved value you want to remove. Build it with the JSON Object nodes — it can hold one field or several. It must match the Key the value was saved under, and it cannot be empty.</td></tr><tr><td style="white-space: nowrap;">**Data Owner**</td><td style="white-space: nowrap;">Choice</td><td>Who the saved value belongs to. Choose **User** to remove a value saved for the individual person running the experience, or **Publisher** to remove a value that belongs to the experience’s publisher — the account that created and published the experience.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-4"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Execute**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the cloud has answered — whether the removal worked or not. Continue your steps from here.</td></tr><tr><td style="white-space: nowrap;">**Success**</td><td style="white-space: nowrap;">True / false</td><td>True when the value was removed (or was already gone), false if something went wrong, such as not being signed in. Check this before trusting the result.</td></tr></tbody></table>

#### Example

<table id="bkmrk-key-input-%7B-%22categor-0"><tbody><tr><td>**Key** input</td><td>`{ "category": "progress", "level": "3" }`</td></tr><tr><td>**Data Owner** input</td><td>`User`</td></tr><tr><td>**Success** output</td><td>`true` — the saved progress for that level has been removed</td></tr></tbody></table>

#### Tips

- The Key here must match the one used when the value was saved. If the fields don’t line up, the cloud finds nothing to remove.
- Removing a value that doesn’t exist is safe — Success is still true, so you don’t need to check first.
- Wire Success into a Branch so your experience can react if the removal couldn’t be completed.

# States



# Node Is Grabbed

### ![State_Node_Grabbed.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/state-node-grabbed.png) Node Is Grabbed

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/1itimage.png)

The **Node Is Grabbed** node enables the user to check if the assigned node is grabbed with **OnTrue/OnFalse** ports to execute responses or **Output Boolean** port that is compatible with event nodes.

#### Examples

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-09/scaled-1680-/97Qimage.png)

In this example, a **Node Is Grabbed** node is used to check if the node assigned is grabbed. Once the object named **Activate** is triggered, the sound named Instructions will play, and the object named Key will show up and become grabbable. Once the object named **Key** is grabbed, the sequence named **Door\_Open** will play.



---

# Watch Boolean Expression

### ![State_Expression_Boolean.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/state-expression-boolean.png) Watch Boolean Expression

![Ceiling Node.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/5dMimage.png)

The **Watch Boolean Expression** node enables the user to check the value of specific variable(s) with **OnTrue/OnFalse** ports to execute responses or **Output Boolean** port that is compatible with event nodes.

#### Examples

![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/Of8image.png)

In this example, a **Watch Boolean Expression** node is used to check the value of **a string variable** to determine if it is true or false, depending on the result, the object named Activate can be triggered. Once the event is triggered, the object named Table will be shown during the VR Experience.


![image.png](https://simlab-soft.com/help/uploads/images/gallery/2024-08/scaled-1680-/1PWimage.png)

In this example, a **Watch Boolean Expression** node is used to check the value of **a number variable** to determine if it is true or false, depending on the result, the object named Activate can be triggered. Once the event is triggered, the object named Table will be shown during the VR Experience.


---

# Boolean

These nodes work with **true/false** values — the yes/no answers your scene produces, such as whether a door is open, a switch is on, or a trainee is standing in the right place. An operator takes one or two of these true/false values and works out a new one, so you can combine several conditions into a single answer and react to it.

## What's on this page

- **And Operation** — the answer is true only when *both* values are true.
- **Or Operation** — the answer is true when *at least one* value is true.
- **Not Operation** — flips a single value to its opposite.

The **And** and **Or** nodes hand you the answer in two ways at once: a true/false **Result** you can read whenever you like, and two triggers — **OnTrue** and **OnFalse** — that fire at the moment the answer changes. Use whichever suits your scene.

---

## True / false logic

### And Operation

Checks two true/false values and tells you whether *both* of them are true.

#### What it does

This node looks at two true/false values you feed in and combines them: the result is true only when **both** are true. If either one is false — or both are — the result is false. Think of it as the word “and” in everyday speech: the door is unlocked *and* the trainee is wearing a helmet.

The node keeps watching both inputs and updates as they change. The **Result** output always holds the current answer, ready to read at any time. The two trigger outputs fire only at the moment the answer flips: **OnTrue** fires the instant the combined answer becomes true, and **OnFalse** fires the instant it becomes false. If an input changes but the overall answer stays the same, neither trigger fires.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Boolean A**</td><td style="white-space: nowrap;">True / false</td><td>The first true/false value you want to check — for example, whether a switch is on.</td></tr><tr><td style="white-space: nowrap;">**Boolean B**</td><td style="white-space: nowrap;">True / false</td><td>The second true/false value to check alongside the first — for example, whether a safety guard is closed. Both must be true for the result to be true.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment both values become true. Wire this to whatever should happen when the combined answer turns true.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the answer turns false — that is, when at least one of the two values stops being true. Wire this to whatever should happen when the combined answer turns false.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>The current combined answer: true when both values are true, otherwise false. You can read this at any time.</td></tr></tbody></table>

#### Example

<table id="bkmrk-boolean-a-input-mach"><tbody><tr><td style="white-space: nowrap;">**Boolean A** input</td><td>Machine power is on — `true`</td></tr><tr><td style="white-space: nowrap;">**Boolean B** input</td><td>Safety guard starts open (`false`), then the trainee closes it (`true`)</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>Fires the instant the guard closes — now both are true, so the answer flips to true and this trigger fires once (you could use it to start the machine)</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`true`</td></tr></tbody></table>

#### Tips

- Use the **Result** output when you just need the current answer somewhere else; use **OnTrue** / **OnFalse** when you want something to happen the moment the answer changes.
- The triggers fire only on a change. If both values are already true when your scene starts, **OnTrue** won’t fire until the answer leaves and returns to true.
- Need to check that *either* value is true instead of both? Use the **Or Operation** node. Need to flip a single true/false value? Use the **Not Operation** node.

### Or Operation

Checks two true/false values and tells you whether at least one of them is true.

#### What it does

This node looks at its two true/false inputs and works out a single combined answer. The combined answer is **true** whenever at least one of the inputs is true, and only becomes **false** when both inputs are false. You can read this answer at any time from the Result output.

The node keeps watching both inputs and re-checks the answer whenever either one changes. The moment the combined answer flips to true, the **OnTrue** trigger fires once; the moment it flips back to false, the **OnFalse** trigger fires once. If an input changes but the overall answer stays the same, neither trigger fires.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Boolean A**</td><td style="white-space: nowrap;">True / false</td><td>The first true/false value to check — for example whether a door is open.</td></tr><tr><td style="white-space: nowrap;">**Boolean B**</td><td style="white-space: nowrap;">True / false</td><td>The second true/false value to check — for example whether a window is open.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the combined answer becomes true — that is, when at least one input has just turned true. Connect this to whatever should happen when that switch-on moment occurs.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the combined answer becomes false — that is, when both inputs have just become false. Connect this to whatever should happen when that switch-off moment occurs.</td></tr><tr><td style="white-space: nowrap;">**Result**</td><td style="white-space: nowrap;">True / false</td><td>The current combined answer: true if at least one input is true, false only when both are false. You can read this at any time.</td></tr></tbody></table>

#### Example

<table id="bkmrk-boolean-a-input-door"><tbody><tr><td style="white-space: nowrap;">**Boolean A** input</td><td>Door is open — `false`</td></tr><tr><td style="white-space: nowrap;">**Boolean B** input</td><td>Window is open — changes from `false` to `true`</td></tr><tr><td style="white-space: nowrap;">**Result** output</td><td>`true` (at least one is now open)</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>Fires once, because the combined answer just flipped from false to true — you could use it to start a “something is open” warning.</td></tr></tbody></table>

#### Tips

- Use **Result** when you just want the current answer to feed into another node, and use **OnTrue** / **OnFalse** when you want something to happen the moment the answer changes.
- The triggers fire only on a change. If the answer is already true and an input change keeps it true, **OnTrue** will not fire again.
- If you need the answer to be true only when *both* inputs are true, use the **And Operation** node instead.

### Not Operation

Flips a true/false value to its opposite.

#### What it does

This node takes a single true/false value and gives you back the reverse. If the value coming in is true, the result is false. If it comes in as false, the result is true.

It’s handy when you want to react to the opposite of something — for example, doing something only when a door is *not* open, or when a switch is *not* turned on. The value you connect is not changed; you simply get a new, flipped result out.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Input**</td><td style="white-space: nowrap;">True / false</td><td>The true/false value you want to flip — for example, whether a light is on or whether an object is visible.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**Output**</td><td style="white-space: nowrap;">True / false</td><td>The opposite of what you connected: `false` when the input is true, and `true` when the input is false.</td></tr></tbody></table>

#### Example

<table id="bkmrk-input-true-%28the-door"><tbody><tr><td style="white-space: nowrap;">**Input**</td><td>`true` (the door is open)</td></tr><tr><td style="white-space: nowrap;">**Output**</td><td>`false` — so “the door is not open” is false</td></tr></tbody></table>

#### Tips

- Use this when you want to act on the opposite of a condition without setting up a separate check — for example, to know when something is *not* happening.

---

## Related

- **Branch** — use the **Result** from any of these nodes to send your scene down one path or another.
- Chain these three together to build a bigger check — for example, flip a value with **Not Operation** before feeding it into **And Operation** or **Or Operation**.

# Assembly

The nodes on this page report on SimLab’s **VR assembly** system. They are **states**: each one keeps an eye on a single part and continuously reports a simple true/false answer about where that part is in the assembly — for example “is it this part’s turn to be put on?” or “is this part fully assembled?” A state is not an action you run once and finish; it is a live condition the scene keeps checking the whole time it is playing.

In a VR assembly, parts go together in a set order, and each part has a state of its own — think of a screw: all the way *out* (taken apart), *seated in place but not tightened* (partway together), or *tightened* (fully together). The nodes below let your scene react to where a part is in that process — whether it is this part’s turn to be added or removed, and whether a part is completely assembled or completely apart.

Every one of these nodes gives you the same three things to work with:

- **OnTrue** — a trigger that fires the moment the answer becomes true.
- **OnFalse** — a trigger that fires the moment the answer becomes false.
- **Output Boolean** — the current true/false value, ready to read at any time or to send into a **Branch** node.

The two triggers fire only when the answer *changes* — not over and over while it stays the same. These nodes only watch and report; they never move, assemble, or change anything in your scene.

## What's on this page

- **Node Can Assemble** — is it this part’s turn to be put on next?
- **Node Can Disassemble** — is it this part’s turn to be taken off next?
- **Node Fully Assembled** — is this part completely assembled (in place and secured)?
- **Node Fully Disassembled** — is this part completely taken apart (all the way out)?

Looking for other state nodes — checking whether two objects overlap, or whether the viewer is overlapping an object? See the **States** page.

---

### Node Can Assemble

Reports whether a part in a VR assembly is currently allowed to be put on next — that is, whether it is this part’s turn in the assembly order.

#### What it does

In a VR assembly, every part has to go on in a set order, and some parts can only be added once the parts before them are already in place. This node watches one part and keeps answering a simple yes/no question: is it this part’s turn yet? The answer is `true` as long as everything that must come before this part has already been assembled, so it is now ready to be put on. While some earlier part is still missing, the answer is `false`.

It only watches and reports — it never assembles the part or changes anything in the scene. You connect what should happen on the “ready” side and the “not yet” side, and read the current answer whenever you like.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to check — for example a `Bolt_01` object from your assembly. The node reports whether this part is currently allowed to be assembled next.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the part becomes ready to assemble — that is, when the last part that had to come before it is finally in place. Wire this to whatever should happen when it is this part’s turn, such as highlighting it or showing a hint.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the part is no longer ready — for example if an earlier part is removed again, so it stops being this part’s turn. Wire this to whatever should happen when the part is not yet ready.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean**</td><td style="white-space: nowrap;">True / false</td><td>The current answer, ready to read at any time: `true` while the part is allowed to be assembled next, `false` while it is not yet its turn. Send this into a Branch node, or use it anywhere you need the current yes/no value.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**Output Boolean** output</td><td>`true` — the `Housing` and `Gear` that come before `Bolt_01` are already assembled, so it is now the bolt’s turn</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>Fires the instant `Gear` is seated — the bolt is now ready, so you could highlight it to guide the trainee to fit it next</td></tr></tbody></table>

#### Tips

- Use the **Output Boolean** when you just need the current answer somewhere else (for example in a Branch); use **OnTrue** / **OnFalse** when you want something to happen the moment a part becomes ready or stops being ready.
- The triggers fire only on a change. If the part is already ready when your scene starts, **OnTrue** won’t fire until the answer leaves and returns to true.
- This node only reports readiness — it never assembles the part. Combine it with your assembly steps to guide the trainee through the parts in the right order.

### Node Can Disassemble

Reports whether a part is currently allowed to be taken off next in a VR assembly — that is, whether every part that has to come off before it has already been removed, so it’s now this part’s turn.

#### What it does

In a VR assembly, parts come apart in a set order — the pieces on top have to be removed before the ones underneath. This node watches one part and answers a simple live question: “Is it this part’s turn to be taken off?” The answer is true when all the parts that must be removed ahead of it are already off, and false while something on top of it is still attached.

This node only watches and reports — it never takes the part off or changes anything in the scene. The answer updates on its own as the assembly is taken apart, so you can use it to know exactly when a part becomes ready to remove.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The part you want to watch — for example a bolt or a panel. The node reports whether this part is currently allowed to be taken off next.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires the moment the part becomes ready to be taken off — the instant it becomes this part’s turn. Wire it to whatever should happen then, such as highlighting the part or showing a “remove this” hint. It fires once at that moment, not continuously.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires the moment the part is no longer the one allowed to come off next. Wire it to whatever should happen then, such as turning off a highlight. It fires once at that moment.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean**</td><td style="white-space: nowrap;">True / false</td><td>The current answer as a true/false value — true while it’s this part’s turn to be removed, false otherwise. You can read it at any time or send it into a Branch node.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt-0"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>fires when the cover above `Bolt_01` has been removed and it’s now the bolt’s turn to come off</td></tr><tr><td style="white-space: nowrap;">**OnFalse** output</td><td>fires if `Bolt_01` is no longer the next part allowed to be removed</td></tr><tr><td style="white-space: nowrap;">**Output Boolean** output</td><td>`true` once the bolt is ready to be taken off</td></tr></tbody></table>

#### Tips

- Use **OnTrue** to guide the user — for example, light up the next part the moment it becomes removable so they always know what to take off next.
- This node reports readiness only; it does not take the part off. Pair it with your normal grab-and-remove interaction to act on the part itself.
- Send the **Output Boolean** into a Branch node when you want a check elsewhere in your logic to react to whether a part is ready to be removed.

### Node Fully Assembled

Watches one object and reports whether it is completely assembled — fully in place *and* secured.

#### What it does

This node keeps an eye on the object you connect and answers a simple yes/no question while your scene runs: is this object fully assembled? In SimLab’s assembly system a part moves through three stages — think of a screw. With the screw all the way out, the part is disassembled. Once it is dropped into place but not yet tightened, it is only partially assembled. When it is finally tightened down, it is fully assembled. This node reports **true** only at that last stage, when the object is completely in place and secured. As long as the object is still loose, only seated, or not yet positioned, the answer stays **false**.

It only watches and reports — it never moves, tightens, or changes the object in any way. You use its answer to drive the rest of your scene: play a confirmation sound when a part is fully assembled, show a warning while it still isn’t, or feed the current answer into a Branch node.

#### Inputs

<table id="bkmrk-port-type-what-to-co-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to watch — the part whose assembly you care about, such as `Bolt_01`. The node reports on this object’s own assembly state.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-1"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the moment the object becomes fully assembled. Wire it to whatever should happen when the part is finished — a success chime, a checkmark, the next step in your guide.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the moment the object stops being fully assembled — for example if it is loosened or taken back apart. Wire it to whatever should happen when the part is no longer complete.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean**</td><td style="white-space: nowrap;">True / false</td><td>The current answer — `true` while the object is fully assembled, `false` otherwise. You can read it at any time or send it straight into a Branch node.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt-1"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>Fires when `Bolt_01` is tightened all the way down — play a confirmation sound and mark the step complete.</td></tr><tr><td style="white-space: nowrap;">**OnFalse** output</td><td>Fires if `Bolt_01` is later loosened or removed.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean** output</td><td>`true` once the bolt is fully assembled, `false` while it is still loose or only seated.</td></tr></tbody></table>

#### Tips

- A part that is only dropped into place but not tightened still counts as **false** here — this node reports true only when the part is both in place and secured.
- **OnTrue** and **OnFalse** each fire just once, right at the moment the answer changes. If you instead need to react to the answer continuously, read **Output Boolean** — it always holds the current value.

### Node Fully Disassembled

Reports whether the object you connect is completely taken apart — all the way out of place, not just loosened.

#### What it does

Connect one object and this node keeps a live yes/no answer to the question “is this part fully disassembled?” In an assembly scene a part can be in three states — think of a screw: all the way out (**fully disassembled**), dropped into place but not tightened (**partially assembled**), or tightened down (**fully assembled**). The answer here is **true** only when the object is all the way out, and **false** while it is partially assembled or fully assembled.

The node only watches and reports — it never moves the object or changes anything in the scene. The answer can flip at any time as the user works: each time it flips, one of the two triggers fires, and a true/false value is always available to read.

#### Inputs

<table id="bkmrk-port-type-what-to-co-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object you want to watch — the part whose assembly state you care about, for example a `Bolt_01`. The node reports on this object’s own state.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-2"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the object becomes fully disassembled — the instant it comes all the way out of place. Wire this to whatever should happen when the part is completely removed.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once at the moment the answer turns false — that is, the instant the object is no longer fully out (it has been seated back into place, even loosely). Wire this to whatever should happen when the part is back in.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean**</td><td style="white-space: nowrap;">True / false</td><td>The current answer, ready to read at any time: **true** while the object is fully disassembled, **false** otherwise. Send it into a Branch node, or use it anywhere a true/false value is needed.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-bolt-2"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`Bolt_01`</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>Fires the instant `Bolt_01` is backed all the way out — you could use it to mark the disassembly step complete.</td></tr><tr><td style="white-space: nowrap;">**OnFalse** output</td><td>Fires the instant `Bolt_01` is seated back into place — even just dropped in, before tightening.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean** output</td><td>`true` while the bolt is fully out, `false` once it is seated or tightened.</td></tr></tbody></table>

#### Tips

- Use **Output Boolean** when you just need the current answer somewhere else; use **OnTrue** / **OnFalse** when you want something to happen the moment the part comes out or goes back in.
- The triggers fire only on a change. If the part is already fully out when your scene starts, **OnTrue** won’t fire until it is put back and then removed again.
- “Partially assembled” (in place but not tightened) still reports **false** here — this node turns true only when the part is all the way out. To react to the tightened, fully-in state instead, use the matching fully-assembled state node.

# Overlap

The nodes on this page are **states**. Each one keeps an eye on part of your scene and continuously reports a simple true/false answer about it — for example “are these two objects touching?” or “is the viewer standing inside this area?” A state is not an action you run once and finish; it is a live condition the scene keeps checking the whole time it is playing.

Every one of these nodes gives you the same three things to work with:

- **OnTrue** — a trigger that fires the moment the answer becomes true.
- **OnFalse** — a trigger that fires the moment the answer becomes false.
- **Output Boolean** — the current true/false value, ready to read at any time or to send into a **Branch** node.

The two triggers fire only when the answer *changes* — not over and over while it stays the same. These nodes only watch and report; they never move, assemble, or change anything in your scene.

This page covers the **overlap** states. For states that follow a part through a **VR assembly** — whether it can be put on or taken off, or is fully assembled — see the **Assembly** page.

---

## Overlap

These nodes report whether things are sharing the same space in your scene. **Overlap** means two volumes intersect — they are touching or passing through one another. One node compares two objects you choose; the other compares an object against the **viewer** (the person moving through the scene in VR).

### Nodes Overlap

Watches two objects in your scene and reports whether they are overlapping in space — that is, whether their 3D shapes share the same area.

#### What it does

You give this node two objects from your scene. It keeps watching them while your scene runs and answers one simple yes/no question: are these two objects overlapping right now? The answer is true whenever the two objects’ 3D volumes share the same space, and false whenever they are apart.

This node only watches and reports — it never moves, changes, or touches the objects themselves. It gives you a true/false answer plus two triggers so you can make something happen the moment the two objects start touching, or the moment they come apart.

#### Inputs

<table id="bkmrk-port-type-what-to-co"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**SceneNode A**</td><td style="white-space: nowrap;">Scene node</td><td>The first object to check — for example a `Gear`. It must be a different object from SceneNode B. The viewer’s start position cannot be used here; to test the viewer against an object, use the User Overlap Node instead.</td></tr><tr><td style="white-space: nowrap;">**SceneNode B**</td><td style="white-space: nowrap;">Scene node</td><td>The second object to check — for example a `Housing`. It must be a different object from SceneNode A. The viewer’s start position cannot be used here either.</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the instant the two objects start overlapping. Wire it to whatever should happen the moment they come together.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the instant the two objects stop overlapping and move apart. Wire it to whatever should happen the moment they separate.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean**</td><td style="white-space: nowrap;">True / false</td><td>The current answer: true while the two objects are overlapping, false while they are apart. You can read it at any time or feed it into a Branch node.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-a-input-ge"><tbody><tr><td>**SceneNode A** input</td><td>`Gear`</td></tr><tr><td>**SceneNode B** input</td><td>`Housing`</td></tr><tr><td>**OnTrue** output</td><td>Fires the moment the `Gear` slides into the `Housing` and they begin to overlap</td></tr><tr><td>**OnFalse** output</td><td>Fires the moment the `Gear` is pulled back out and the two no longer overlap</td></tr><tr><td>**Output Boolean** output</td><td>`true` while the `Gear` is inside the `Housing`</td></tr></tbody></table>

#### Tips

- OnTrue and OnFalse each fire just once, at the moment the answer changes — they do not keep firing while the two objects stay overlapping. If you need to act on the ongoing state rather than the moment it changes, read the Output Boolean instead.
- The two objects must be different. Pick two separate scene objects for SceneNode A and SceneNode B.
- To check whether the viewer is overlapping an object, use the User Overlap Node — the viewer’s start position is not accepted here.

### User Overlap Node

This node reports whether the person viewing the scene is currently sharing the same space as a chosen object — in other words, whether the viewer is standing in or passing through it.

#### What it does

You give it one object from your scene. While the scene runs, the node keeps watching the viewer’s position and answers a single live question: is the viewer overlapping that object right now? The answer is `true` while the viewer’s space and the object’s space share the same area, and `false` the rest of the time.

This node only watches and reports — it never moves, hides, or changes the object or the viewer in any way. You decide what happens by wiring its outputs to other nodes. The two triggers fire at the moment the answer changes: one the instant the viewer steps into the object, the other the instant they step back out. The true / false output always holds the current answer, so you can read it whenever you like.

#### Inputs

<table id="bkmrk-port-type-what-to-co-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What to connect</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**SceneNode**</td><td style="white-space: nowrap;">Scene node</td><td>The object in your scene you want to test the viewer against — for example a doorway, a safety zone, or a part such as `Housing`. The node reports `true` while the viewer is sharing the same space as this object. (The viewer start position cannot be used here.)</td></tr></tbody></table>

#### Outputs

<table id="bkmrk-port-type-what-you-g-0"><thead><tr><th style="white-space: nowrap;">Port</th><th style="white-space: nowrap;">Type</th><th>What you get</th></tr></thead><tbody><tr><td style="white-space: nowrap;">**OnTrue**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the moment the viewer starts overlapping the object. Wire it to whatever should happen when the viewer steps in — play a sound, show a message, open a door.</td></tr><tr><td style="white-space: nowrap;">**OnFalse**</td><td style="white-space: nowrap;">Trigger</td><td>Fires once the moment the viewer stops overlapping the object. Wire it to whatever should happen when the viewer leaves — the matching “step out” reaction.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean**</td><td style="white-space: nowrap;">True / false</td><td>The current answer as a `true` / `false` value: `true` while the viewer is inside the object, `false` otherwise. Read it directly or send it into a Branch node to choose between two paths.</td></tr></tbody></table>

#### Example

<table id="bkmrk-scenenode-input-rest"><tbody><tr><td style="white-space: nowrap;">**SceneNode** input</td><td>`RestrictedZone`</td></tr><tr><td style="white-space: nowrap;">**OnTrue** output</td><td>Fires when the viewer walks into `RestrictedZone` — wire it to a warning sound.</td></tr><tr><td style="white-space: nowrap;">**OnFalse** output</td><td>Fires when the viewer leaves `RestrictedZone` — wire it to stop the warning.</td></tr><tr><td style="white-space: nowrap;">**Output Boolean** output</td><td>`true` while the viewer is inside the zone, `false` when they are outside</td></tr></tbody></table>

#### Tips

- Use **OnTrue** and **OnFalse** as a matched pair when you want one reaction as the viewer enters and another as they leave — for example showing and then hiding a hint panel.
- When you only need to check the answer at a specific point (rather than react the instant it changes), feed **Output Boolean** into a Branch node instead.
- Pick an object whose space is big enough to comfortably contain the viewer, such as a room or a marked floor area, so the overlap is easy to trigger.

# Interactive GLTF Responses

Responses that are supported and displayed in the Interactive GLTF Viewer but are not currently used in the VR Viewer.

# Call JS Function

#### [![Response_JSFunction_Call.png](https://simlab-soft.com/help/uploads/images/gallery/2026-06/scaled-1680-/Wsbresponse-jsfunction-call.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-06/Wsbresponse-jsfunction-call.png) Call JS Function

The Call JS Function node enables the execution of custom JavaScript functions in the gener  
ated Interactive WebGL HTML file after exporting a scene. The following steps explain how to configure and use this node:

1. Add these nodes to the interactive gltf diagram as an example.[![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-06/scaled-1680-/PYmimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-06/PYmimage.png)
2. Export to Interactive WebGL. [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-06/scaled-1680-/Uylimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-06/Uylimage.png)
3. After exporting the scene to interactive WebGL, open the generated Interactive WebGL HTML file and implement the `test` function referenced by the **Call JS Function** node. This function will be executed when the node is triggered (As shown in the example below, the `test` JavaScript function will displays an alert popup containing the string **"test"**). [![image.png](https://simlab-soft.com/help/uploads/images/gallery/2026-06/scaled-1680-/ExXimage.png)](https://simlab-soft.com/help/uploads/images/gallery/2026-06/ExXimage.png)