> ## Documentation Index
> Fetch the complete documentation index at: https://xrlive.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Wire Action Controller

> Connect each declared control to Blueprint logic using Find Control by Name and Assign On Slider Value

With the controls declared in `UICategories`, the next step is to connect them to Blueprint logic inside `BP_Settings`. This module covers how the connection pattern works and walks through wiring the two slider controls — **Horizontal move** and **Vertical move** — to the Cube's transform.

<Note>
  The checkbox, color picker, and dropdown controls follow the same base pattern described here. Their specific wiring will be covered in dedicated modules as they are built.
</Note>

***

## How the connection pattern works

Every operator control is wired with the same three-step structure inside the EventGraph of `BP_Settings`:

<Steps>
  <Step title="Find Control by Name">
    Get a reference to the `xrlive_UIpanel` component and call **Find Control by Name**, passing the exact name of the control as declared in `UICategories`. Internally, this node searches the control array and returns a Widget Controller Object Reference for that specific control.
  </Step>

  <Step title="Assign the event (bind)">
    From the **Return Value** of `Find Control by Name`, call the assign node that matches the control type — for sliders this is **Assign On Slider Value**. Connect a custom event to its **Event** pin. This registers the custom event as the handler that runs every time the operator moves the slider.
  </Step>

  <Step title="Handle the value in the custom event">
    Inside the custom event, use the **Value Modification** output pin (a float carrying the current slider position) to drive the target property — in this case the Cube's relative location on the corresponding axis.
  </Step>
</Steps>

<Tip>
  `Find Control by Name` returns a generic Widget Controller reference. The assign nodes (**Assign On Slider Value**, **Assign On Checkbox Value**, etc.) are methods on that reference specific to each control type. You will only see the correct assign node when the control type matches.
</Tip>

***

## Step 1 — Wire the Horizontal Move slider

Open `BP_Settings` and go to the **EventGraph** tab.

### 1.1 — Call Find Control by Name

In the Components panel, drag the **xrlive\_UIpanel** component into the EventGraph to create a reference node. Drag off its output pin, search for **Find Control by Name**, and select it.

In the **Name** field of the node, type the control name exactly as declared — `Horizontal move`.

<Frame caption="Find Control by Name — target set to xrlive_UIpanel, name field filled with Horizontal move">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-find-control-node.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=021afdfa1f682990f8ae86c26185d1eb" alt="Blueprint EventGraph showing the xrlive_UIpanel reference connected to Find Control by Name, with the Name field containing Horizontal move" width="1920" height="1040" data-path="images/sdk/first-visual/wire-find-control-node.png" />
</Frame>

### 1.2 — Bind the slider event

Drag off the **Return Value** pin of `Find Control by Name` and search for **Assign On Slider Value**. Select it. This creates both the bind node and a connected **Custom Event** node automatically.

Rename the custom event to something descriptive — for example, `OnSliderValue_HorizontalMove`.

<Frame caption="Bind Event to On Slider Value — custom event connected and named">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-bind-event.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=dcf8ee60f245a7e492e4a30bab1649d3" alt="Blueprint EventGraph showing Find Control by Name connected to Bind Event to On Slider Value, with the custom event OnSliderValue_HorizontalMove attached to the Event pin" width="1920" height="1040" data-path="images/sdk/first-visual/wire-bind-event.png" />
</Frame>

The custom event exposes two output pins:

* **Control Name** — the string identifier of the control that triggered the event
* **Value Modification** — the current float value of the slider (between Min Value and Max Value as set in UICategories)

### 1.3 — Drive the Cube's X position

Drag the **Cube** component from the Components panel into the EventGraph. Drag off its output pin and search for **Set Relative Location**.

Right-click the **New Location** pin of `Set Relative Location` and choose **Split Struct Pin** — this exposes X, Y, and Z as individual float inputs.

Connect **Value Modification** from the custom event to **New Location X**.

To preserve the current Y and Z positions when only X changes, drag the **Cube** component again, call **Get Relative Location**, split that struct as well, and connect **Relative Location Y** → **New Location Y** and **Relative Location Z** → **New Location Z**.

<Frame caption="Horizontal move fully wired — Value Modification drives New Location X, Y and Z preserved from current position">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-horizontal-complete.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=6e74f351111253b228db2075056b7240" alt="Blueprint EventGraph showing the complete Horizontal move chain: xrlive_UIpanel → Find Control by Name → Bind Event to On Slider Value → OnSliderValue_HorizontalMove custom event → Cube Set Relative Location with Value Modification connected to New Location X" width="1920" height="1040" data-path="images/sdk/first-visual/wire-horizontal-complete.png" />
</Frame>

***

## Step 2 — Wire the Vertical Move slider

The Vertical Move slider follows the exact same pattern, with two differences: the control name is `Vertical move` and the value drives **New Location Y** instead of X.

### 2.1 — Add a second Find Control by Name

Drag `xrlive_UIpanel` into the EventGraph again. Call **Find Control by Name** and set the Name to `Vertical move`.

### 2.2 — Bind Assign On Slider Value

Drag off **Return Value** and search for **Assign On Slider Value**. When the context menu appears, select **Assign On Slider Value** from the Events section.

<Frame caption="Assign On Slider Value search — select the Events entry, not the Audio Reactive variants">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-assign-search.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=a2ea882cc5518d4f65e486e5b8ab03eb" alt="Blueprint context menu showing the search results for assign on slider, with Assign On Slider Value highlighted in the Events section" width="1920" height="1040" data-path="images/sdk/first-visual/wire-assign-search.png" />
</Frame>

Rename the custom event to `OnSliderValue_VerticalMove`.

### 2.3 — Drive the Cube's Y position

Repeat the `Set Relative Location` setup: split the struct, connect **Value Modification** → **New Location Y**, and preserve X and Z from the current relative location.

<Frame caption="Vertical move fully wired — Value Modification drives New Location Y">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-vertical-complete.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=9c77db4bdfa949e391a7ba6ebc90cd20" alt="Blueprint EventGraph showing the Vertical move chain: xrlive_UIpanel → Find Control by Name (Vertical move) → Bind Event to On Slider Value → OnSliderValue_VerticalMove → Cube Set Relative Location with Value Modification on New Location Y" width="1920" height="1040" data-path="images/sdk/first-visual/wire-vertical-complete.png" />
</Frame>

***

## Step 3 — Wire the Visibility checkbox

The checkbox uses the same base pattern — `Find Control by Name` → bind node → custom event — but the assign node and output pins differ from sliders.

### 3.1 — Call Find Control by Name

Drag `xrlive_UIpanel` into the EventGraph. Call **Find Control by Name** and set the **Name** field to `Visibility`.

<Frame caption="Find Control by Name — name field set to Visibility, Details panel confirms Xrlive Checkbox type">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-check-find-control.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=a8716baa9330b50ae27a3f795c431e23" alt="Blueprint EventGraph showing xrlive_UIpanel connected to Find Control by Name with the Name field set to Visibility. The Details panel on the right shows Category 2 with an Xrlive Checkbox element named Visibility." width="1920" height="1040" data-path="images/sdk/first-visual/wire-check-find-control.png" />
</Frame>

### 3.2 — Bind the checkbox event

Drag off the **Return Value** pin and search for **Bind Event to On Check Change**. Select it. A custom event node is created automatically.

Rename the custom event to `OnCheckChange_Visibility`.

<Frame caption="Bind Event to On Check Change — custom event OnCheckChange_Visibility connected to the Event pin">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-check-bind-event.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=5a1f848fb7c415ddd6c129d4c8b0a172" alt="Blueprint EventGraph showing Find Control by Name connected to Bind Event to On Check Change, with the custom event OnCheckChange_Visibility attached to the Event pin. The custom event exposes Control Name and Checked output pins." width="1920" height="1040" data-path="images/sdk/first-visual/wire-check-bind-event.png" />
</Frame>

The custom event exposes two output pins:

* **Control Name** — the string identifier of the control
* **Checked** — a boolean: `true` when the checkbox is checked, `false` when unchecked

### 3.3 — Invert the value and drive Set Hidden in Game

The checkbox is labeled **Visibility** — when it is checked the Cube should be visible. However, **Set Hidden in Game** expects the inverse: `true` means hidden, `false` means shown. To reconcile these, a **NOT Boolean** node is placed between `Checked` and `New Hidden`.

Drag the **Cube** component into the EventGraph and call **Set Hidden in Game**.

Between the custom event and `Set Hidden in Game`:

1. Drag off the **Checked** pin and search for **NOT Boolean**. Select it.
2. Connect the output of **NOT** to the **New Hidden** pin of `Set Hidden in Game`.
3. Connect the **Cube** reference to the **Target** pin of `Set Hidden in Game`.
4. Connect the execution pin from the custom event to the execution pin of `Set Hidden in Game`.

<Frame caption="Visibility fully wired — Checked passes through NOT Boolean before reaching Set Hidden in Game on the Cube">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-check-complete.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=d723c717373abcad8b8268a0305433d7" alt="Blueprint EventGraph showing the complete Visibility chain: xrlive_UIpanel → Find Control by Name (Visibility) → Bind Event to On Check Change → OnCheckChange_Visibility custom event → NOT Boolean → Set Hidden in Game on the Cube" width="1920" height="1040" data-path="images/sdk/first-visual/wire-check-complete.png" />
</Frame>

<Note>
  The NOT Boolean is not mandatory — it is here because the control is named Visibility, so the operator expects checked = visible. If you named your control Hidden and wanted checked to mean hidden, you would connect Checked directly to New Hidden without the NOT node.
</Note>

***

## Step 4 — Wire the Color control

The color control requires an extra step before touching the EventGraph: the Cube needs a material that accepts a dynamic color at runtime. In Unreal Engine, this is done by creating a **Dynamic Material Instance** from a material that has a **Vector Parameter** exposed.

### 4.1 — Create the material

In the Content Browser, navigate to the plugin's **Materials** folder (or create one). Right-click → **Material**, name it `M_MeshMat`, and open it.

Inside the Material Graph:

1. Right-click on an empty area and search for **Vector Parameter**. Place one.
2. In the **Details** panel set **Parameter Name** to `Color`.
3. Connect the output pin of the `Color` node to the **Base Color** input of the material output node.
4. Press **Apply** and **Save**.

<Frame caption="M_MeshMat material graph — Color Vector Parameter connected to Base Color, default value shown as pink">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-color-material-graph.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=51e1a6a155fd6a1e48673df6490b2253" alt="Unreal Engine Material Graph showing a Vector Parameter node named Color with a pink default value connected to the Base Color pin of the M_MeshMat material output node. The material preview sphere on the left reflects the color." width="1920" height="1040" data-path="images/sdk/first-visual/wire-color-material-graph.png" />
</Frame>

<Note>
  The parameter name `Color` must match exactly the string used later in the **Set Vector Parameter Value** node. Any difference in casing or spacing will cause the color change to have no effect at runtime.
</Note>

### 4.2 — Set up the BeginPlay chain

Open `BP_Settings` and go to the **EventGraph**. This chain runs once at startup to create the dynamic material instance and apply it to the Cube.

After the existing BeginPlay logic (or branching from `Event BeginPlay`):

1. Add **Create Dynamic Material Instance**. Set **Parent** to `M_MeshMat`.
2. Drag the **Return Value** pin, promote it to a variable, and name the variable `MaterialRef`. This stores the instance so it can be accessed from the color event handler.
3. Add **Set Material** targeting the **Cube** component. Connect:
   * `Cube` → **Target**
   * `MaterialRef` GET → **Material**
   * Leave **Element Index** at `0`.

<Frame caption="BeginPlay chain — Create Dynamic Material Instance stores the result in MaterialRef, then Set Material applies it to the Cube">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-color-beginplay.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=2fe97f18065224c32ba78061056fb901" alt="Blueprint EventGraph showing Create Dynamic Material Instance with M_MeshMat as Parent, Return Value connected to SET MaterialRef, then Set Material node with Cube as Target, Element Index 0, and MaterialRef as Material." width="1920" height="1040" data-path="images/sdk/first-visual/wire-color-beginplay.png" />
</Frame>

### 4.3 — Bind the color event and wire Set Vector Parameter Value

Still in the BeginPlay chain, add the binding for the color control. After the existing `Find Control by Name` / `Bind Event` calls:

1. Drag `xrlive_UIpanel` into the EventGraph. Call **Find Control by Name** and set **Name** to `Color`.
2. From **Return Value**, search for **Bind Event to On Color Picked**. Select it. A custom event `OnColorPicked_Color` is created with `Control Name` and `Color` (LinearColor) output pins.

Inside the `OnColorPicked_Color` custom event:

3. Drag the **MaterialRef** variable into the EventGraph to create a GET node.
4. From **MaterialRef**, search for **Set Vector Parameter Value**. Select it.
5. Set **Parameter Name** to `Color`.
6. Connect the **Color** output pin of the custom event to the **Value** input of `Set Vector Parameter Value`.

<Frame caption="Complete EventGraph — top row is the BeginPlay chain (bind + create DMI + set material), bottom row is the color event handler (MaterialRef → Set Vector Parameter Value)">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-color-set-param.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=21c5f727b98052ea69ba19d507175a2c" alt="Blueprint EventGraph showing two rows: the top row with xrlive_UIpanel → Find Control by Name (Color) → Bind Event to On Color Picked → Create Dynamic Material Instance → SET MaterialRef → Set Material on Cube, and the bottom row with the OnColorPicked_Color custom event → MaterialRef GET → Set Vector Parameter Value with Parameter Name Color and Value connected to the Color output pin." width="1920" height="1040" data-path="images/sdk/first-visual/wire-color-set-param.png" />
</Frame>

***

## Step 5 — Wire the Shape dropdown

The dropdown differs from the other controls in how the event value is handled: instead of driving a single property, the `Selected Item` string is used to branch execution with a **Switch on String** node, and each branch applies a different Static Mesh to the Cube.

### 5.1 — Bind the dropdown event

From `xrlive_UIpanel`, call **Find Control by Name** and set **Name** to `Shape`. Drag off **Return Value** and search for **Bind Event to On Dropdown Selection**. The custom event `OnDropdownSelection_Shape` is created with `Control Name` and `Selected Item` (String) output pins.

<Frame caption="Bind Event to On Dropdown Selection — custom event OnDropdownSelection_Shape connected, Selected Item output pin visible">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-dropdown-bind.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=7ebecbe33e3e4146b9bc29e5f69e3bc8" alt="Blueprint EventGraph showing xrlive_UIpanel connected to Find Control by Name with Name set to Shape, then to Bind Event to On Dropdown Selection, and the custom event OnDropdownSelection_Shape with Control Name and Selected Item output pins." width="1920" height="1040" data-path="images/sdk/first-visual/wire-dropdown-bind.png" />
</Frame>

### 5.2 — Create a NewMesh variable

In the **My Blueprint** panel, create a new variable named `NewMesh` of type **Static Mesh**. This variable will temporarily hold the mesh chosen in each switch branch before it is applied to the Cube.

### 5.3 — Route selection with Switch on String

Drag off the **Selected Item** pin and search for **Switch on String**. This node creates a separate execution output for each string value you define. Click **Add pin** three times and name the cases exactly as declared in `UICategories`: `Cube`, `Sphere`, `Cylinder`.

<Frame caption="Switch on String — three cases matching the dropdown options, Default pin left disconnected">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-dropdown-switch.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=5d86034e07650063608cfc0b7dbf2941" alt="Blueprint EventGraph showing the OnDropdownSelection_Shape custom event connected to a Switch on String node. The Switch has execution output pins labeled Cube, Sphere, Cylinder, and Default. The Selection input is connected to the Selected Item pin of the custom event." width="1920" height="1040" data-path="images/sdk/first-visual/wire-dropdown-switch.png" />
</Frame>

<Note>
  The case strings in Switch on String must match the dropdown option strings exactly — same casing and spacing as declared in `UICategories`. A mismatch will cause that branch to never fire and the `Default` pin to trigger instead.
</Note>

### 5.4 — Assign the mesh for each case

For each case pin, drag the **NewMesh** variable as a SET node and assign the corresponding Static Mesh asset from `Engine/BasicShapes`:

* `Cube` pin → **SET NewMesh** = `Engine/BasicShapes/Cube`
* `Sphere` pin → **SET NewMesh** = `Engine/BasicShapes/Sphere`
* `Cylinder` pin → **SET NewMesh** = `Engine/BasicShapes/Cylinder`

<Tip>
  The Engine's BasicShapes are not visible in the Content Browser by default. Click the **Settings** button in the Content Browser toolbar and enable **Show Engine Content** to make them available.
</Tip>

### 5.5 — Apply the mesh with Set Static Mesh

Connect the execution output of all three SET nodes to a single **Set Static Mesh** node targeting the **Cube** component. Add a **NewMesh** GET node and connect it to the **New Mesh** input of `Set Static Mesh`.

<Frame caption="Shape dropdown fully wired — Switch on String fans out to three SET NewMesh nodes, all converging on a single Set Static Mesh call on the Cube">
  <img src="https://mintcdn.com/xrlive/MWrGLfDdjBHjHVNN/images/sdk/first-visual/wire-dropdown-complete.png?fit=max&auto=format&n=MWrGLfDdjBHjHVNN&q=85&s=38263355419aef49226ed8b35539fbf6" alt="Blueprint EventGraph showing the complete dropdown chain: OnDropdownSelection_Shape custom event → Switch on String (Cube / Sphere / Cylinder cases) → three SET NewMesh nodes each with a different Static Mesh assigned → a single Set Static Mesh node with Cube as Target and NewMesh GET as New Mesh." width="1920" height="1040" data-path="images/sdk/first-visual/wire-dropdown-complete.png" />
</Frame>

***

## What you have now

All five controls from Category 2 are fully wired:

* **Horizontal move** → `Set Relative Location`, X axis
* **Vertical move** → `Set Relative Location`, Y axis
* **Visibility** → `Set Hidden in Game` on the Cube (inverted through NOT Boolean)
* **Color** → `Set Vector Parameter Value` on a Dynamic Material Instance applied to the Cube
* **Shape** → `Set Static Mesh` on the Cube, switching between Cube / Sphere / Cylinder from Engine BasicShapes

<Note>
  To learn more about how each control type works in depth, see the UI Components reference:
  [Slider](/sdk/ui-components/slider) · [Checkbox](/sdk/ui-components/checkbox) · [Color Picker](/sdk/ui-components/color-picker) · [Dropdown](/sdk/ui-components/dropdown)
</Note>
