> For the complete documentation index, see [llms.txt](https://docs.ovrtechnology.com/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ovrtechnology.com/home/ovr-plugin-unreal/using-plugin-establishing-connection.md).

# Using Plugin

Current Blueprint and C++ workflow for connecting Omara hardware and playing one-shot or spatial scent interactions.

The plugin exposes OVR ION/Omara discovery, connection lifecycle, telemetry, scent playback, and spatial scent behavior to Blueprint and C++.

### Runtime setup

* Use one OVR connection manager for each local game process that owns physical scent hardware.
* Enable **Show Plugin Content** and use the included `/OvrUtilities/BP/BP_OVRConnnectionManager` Blueprint, or create a manager from the native class.
* Add an **Olfactory Epithelium** component to the locally controlled pawn or character that receives spatial scent interactions.
* Treat **connected** and **device ready** as separate states. Odor playback is gated by the device-ready pipeline.
* In multiplayer, keep hardware objects local and nonreplicated. Replicate gameplay intent, then let each client drive its own local device.

### Connection methods

#### Companion WebSocket

On Windows and macOS, the manager can try the OVR Companion bridge first. The default endpoint is `ws://127.0.0.1:8080`. If the bridge is unavailable, direct native transports remain available.

Blueprints can call **Connect Companion Bridge**, **Retry Companion Bridge**, and **Disconnect Companion Bridge** and observe the Companion events. BLE, serial, and Companion share connection ownership so only one transport controls the hardware at a time.

#### Direct BLE

Create a BLE scanner, bind its advertisement/device-found event before starting the scan, and connect the returned device. Advertisements are asynchronous, so binding before the scan is important.

Android/Quest also exposes system Companion Device pairing. Picker cancellation, timeout, missing data/device, and disabled Location Services are reported through **On BLE Companion Pairing Failed** with a reason string.

#### USB serial

Windows x64 supports direct serial discovery and connection. Use the manager's serial auto-connect settings or the **Create Serial Device** Blueprint API. Automatic Omara adapter detection checks the Silicon Labs CP210x identifier `VID_10C4/PID_EA60`; **Probe All COM Ports** is available when broader discovery is needed.

Call **Disconnect Active Transport** when the game must explicitly release whichever transport owns the device.

### Important events

Bind the events needed by the game, especially:

* connect and disconnect
* **On Device Ready State Changed**
* **On Battery Percent Changed**
* **On Disconnected With Reason**
* **On BLE Companion Pairing Failed** on Android
* **On Serial Auto Connect Failed** on Windows
* **On Play Odor Not Ready** when playback is requested before the device is ready

### Odor playback

Use **Play Odor Normalized** for intensity from `0.0` to `1.0`, or **Play Odor Byte** for intensity from `0` to `255`. **Play Odor** remains available for Blueprint compatibility.

Create reusable `OdorAsset` data and assign it to one-shot playback or spatial Odorant components. A request made before the connected device reports ready is not sent to the hardware and broadcasts **On Play Odor Not Ready** instead.

### Spatial odorants

Geometric attenuation supports **sphere, capsule, box, and cone** shapes. Niagara particle integration and burst/diffusion are separate optional behaviors, not additional attenuation shapes.

For a Niagara-driven odorant:

1. Select the Niagara actor/component through `NiagaraActorToOdorize` or `NiagaraFXName`.
2. Create a Niagara user object parameter named `OVRObject`.
3. Configure Niagara's particle export callback/module to send particle data to that object.
4. Validate the effect in Play In Editor or a packaged build with a locally controlled pawn and Olfactory Epithelium component.

Epic's Niagara plugin is required for this integration and is enabled automatically by the plugin descriptor.
