Adding olfactory stimulation to 3D applications, Virtual Reality (VR), and simulators creates an unprecedented level of immersion. Integrating Olorama Digital Scent Technology into interactive game engines like Unity and Unreal Engine 5 is fast, lightweight, and handled directly over the local network via UDP messages. Whether you are developing VR simulations or interactive installations, Olorama professional scent generators allow developers to trigger realistic scents with zero latency.
This technical guide covers the complete API specification, source code, and step-by-step setup for both game engines using Olorama Scent Software standards.
Olorama UDP API Specification
All Olorama scent devices listen by default on UDP Port 5010 using broadcast IP 192.168.1.255.
Command Structure
A standard Olorama scent trigger message follows this string format:
OUT, 03, 0200, 1, 04000, 1000Parameter Breakdown
| Parameter | Example | Range / Value | Description |
|---|---|---|---|
| Scent ID | 03 | 1 – 10 | Target scent channel in your Olorama device. |
| Intensity | 0200 | 100 – 500 ms (rec. 100 or 200) | Diffusion duration or strength. |
| Fan | 1 | 0 or 1 | Fan state (1 = ON, 0 = OFF). |
| Fan Time | 04000 | 4000 – 7000 ms (recommended) | Active duration for the fan, in milliseconds. |
| Internal | 1000 | 1000 (constant) | Constant value required by Olorama firmware. Keep set to 1000. |
1. Unity Scent Integration (C#)
Integrating Olorama hardware into Unity requires a simple C# script using System.Net.Sockets.
Step 1: Create OloramaUDPSender.cs
Save the following C# script inside your Unity project (Assets/Scripts/OloramaUDPSender.cs):
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class OloramaUDPSender : MonoBehaviour
{
[Header("Olorama UDP Settings")]
public string targetIP = "192.168.1.255"; // Broadcast IP
public int targetPort = 5010;
public void SendScentMessage(int scentID, int intensity = 200, bool fanOn = true, int fanTimeMs = 4000)
{
scentID = Mathf.Clamp(scentID, 1, 10);
intensity = Mathf.Clamp(intensity, 100, 500);
fanTimeMs = Mathf.Clamp(fanTimeMs, 1000, 9000);
string message = $"OUT, {scentID:00}, {intensity:0000}, {(fanOn ? 1 : 0)}, {fanTimeMs:00000}, 1000";
Debug.Log($"[Olorama] Sending UDP: {message}");
try
{
using (UdpClient client = new UdpClient())
{
client.EnableBroadcast = true;
byte[] data = Encoding.UTF8.GetBytes(message);
client.Send(data, data.Length, new IPEndPoint(IPAddress.Parse(targetIP), targetPort));
}
}
catch (System.Exception ex)
{
Debug.LogError($"[Olorama] UDP Send failed: {ex.Message}");
}
}
}
Step 2: Usage in Unity
- Attach
OloramaUDPSender.csto anyGameObjectin your scene. - Call
SendScentMessagefrom a trigger zone, event listener, or UI button:
// Example: Trigger Olorama Scent #3 with 200ms intensity and 4000ms fan duration
GetComponent<OloramaUDPSender>().SendScentMessage(3, 200, true, 4000);
2. Unreal Engine 5 Scent Integration (C++)
For Unreal Engine 5, you can expose a custom C++ Actor to Blueprints using Unreal’s native sockets library to control your Olorama devices.
Step 1: Add Module Dependencies (Build.cs)
Open Source/YourProject/YourProject.Build.cs and append "Sockets" and "Networking" to PublicDependencyModuleNames:
using UnrealBuildTool;
public class YourProject : ModuleRules
{
public YourProject(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[]
{
"Core",
"CoreUObject",
"Engine",
"InputCore",
"Sockets", // REQUIRED for Olorama UDP
"Networking" // REQUIRED for Olorama UDP
});
}
}
Important: Right-click your .uproject file and select Generate Visual Studio project files after modifying Build.cs.
Step 2: Create OloramaUDPSender.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Sockets.h"
#include "SocketSubsystem.h"
#include "Networking.h"
#include "OloramaUDPSender.generated.h"
UCLASS()
class YOURPROJECT_API AOloramaUDPSender : public AActor
{
GENERATED_BODY()
public:
AOloramaUDPSender();
protected:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
// Blueprint callable function to trigger Olorama scent release
UFUNCTION(BlueprintCallable, Category = "Olorama")
void SendScentMessage(int32 ScentID, int32 IntensityMs = 200, bool bFanOn = true, int32 FanTimeMs = 4000);
private:
bool InitSocket();
void CloseSocket();
FString TargetIP = TEXT("192.168.1.255");
int32 TargetPort = 5010;
FSocket* UDPSocket;
};
Step 3: Create OloramaUDPSender.cpp
#include "OloramaUDPSender.h"
#include "Engine/Engine.h"
AOloramaUDPSender::AOloramaUDPSender()
{
PrimaryActorTick.bCanEverTick = false;
UDPSocket = nullptr;
}
void AOloramaUDPSender::BeginPlay()
{
Super::BeginPlay();
InitSocket();
}
void AOloramaUDPSender::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
CloseSocket();
Super::EndPlay(EndPlayReason);
}
bool AOloramaUDPSender::InitSocket()
{
UDPSocket = FUdpSocketBuilder(TEXT("OloramaSocket"))
.AsReusable()
.AsNonBlocking()
.WithBroadcast();
if (!UDPSocket)
{
UE_LOG(LogTemp, Error, TEXT("[Olorama] UDP socket creation failed"));
return false;
}
UE_LOG(LogTemp, Log, TEXT("[Olorama] UDP socket initialized on port %d"), TargetPort);
return true;
}
void AOloramaUDPSender::SendScentMessage(int32 ScentID, int32 IntensityMs, bool bFanOn, int32 FanTimeMs)
{
if (!UDPSocket)
{
UE_LOG(LogTemp, Warning, TEXT("[Olorama] Socket not initialized"));
return;
}
ScentID = FMath::Clamp(ScentID, 1, 10);
IntensityMs = FMath::Clamp(IntensityMs, 100, 500);
FanTimeMs = FMath::Clamp(FanTimeMs, 1000, 9000);
FString Message = FString::Printf(TEXT("OUT, %02d, %04d, %d, %05d, 1000"),
ScentID, IntensityMs, bFanOn ? 1 : 0, FanTimeMs);
UE_LOG(LogTemp, Log, TEXT("[Olorama] Sending UDP: %s"), *Message);
FTCHARToUTF8 Converter(*Message);
int32 BytesSent = 0;
TSharedRef<FInternetAddr> RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
bool bIsValid;
RemoteAddr->SetIp(*TargetIP, bIsValid);
RemoteAddr->SetPort(TargetPort);
if (bIsValid)
{
UDPSocket->SendTo((uint8*)Converter.Get(), Converter.Length(), BytesSent, *RemoteAddr);
}
else
{
UE_LOG(LogTemp, Error, TEXT("[Olorama] Invalid IP address: %s"), *TargetIP);
}
}
void AOloramaUDPSender::CloseSocket()
{
if (UDPSocket)
{
UDPSocket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(UDPSocket);
UDPSocket = nullptr;
}
}
Step 4: Usage in Unreal Engine 5
- Drag the
AOloramaUDPSenderActor into your Unreal scene. - From Blueprints, call the Send Scent Message node.
Technical Considerations & Network Setup
- LAN Requirements: Ensure your rendering host (PC or VR headset) and the Olorama hardware are connected to the same local network subnet.
- Firewall Configuration: Verify that UDP Port 5010 is open and allowed through host firewalls.
- Mobile / Standalone VR (Meta Quest): When compiling for Android or standalone Quest builds in Unity/Unreal, ensure
INTERNETandACCESS_NETWORK_STATEpermissions are enabled in your project settings.
For more information about integrating Olorama hardware into professional projects, visit our VR Smell Technology page or contact the Olorama technical team for custom SDK support.