Añadir estimulación olfativa a aplicaciones 3D, realidad virtual (VR) y simuladores crea un nivel de inmersión sin precedentes. Integrar la tecnología de olor digital de Olorama en motores de videojuegos interactivos como Unity y Unreal Engine 5 es rápido, ligero y se gestiona directamente por la red local mediante mensajes UDP. Tanto si desarrollas simulaciones de VR como instalaciones interactivas, los generadores de aromas profesionales de Olorama permiten a los desarrolladores activar aromas realistas con latencia cero.
Esta guía técnica cubre la especificación completa de la API, el código fuente y la configuración paso a paso para ambos motores, siguiendo los estándares del software de aromas de Olorama.
Especificación de la API UDP de Olorama
Todos los dispositivos de aromas de Olorama escuchan por defecto en el puerto UDP 5010 usando la IP de difusión (broadcast) 192.168.1.255.
Estructura del comando
Un mensaje estándar para activar un aroma de Olorama sigue este formato de cadena:
OUT, 03, 0200, 1, 04000, 1000Desglose de parámetros
| Parámetro | Ejemplo | Rango / Valor | Descripción |
|---|---|---|---|
| ID de aroma | 03 | 1 – 10 | Canal de aroma de destino en tu dispositivo Olorama. |
| Intensidad | 0200 | 100 – 500 ms (rec. 100 o 200) | Duración o fuerza de la difusión. |
| Ventilador | 1 | 0 o 1 | Estado del ventilador (1 = ON, 0 = OFF). |
| Tiempo de ventilador | 04000 | 4000 – 7000 ms (recomendado) | Duración activa del ventilador, en milisegundos. |
| Interno | 1000 | 1000 (constante) | Valor constante requerido por el firmware de Olorama. Mantenlo en 1000. |
1. Integración de aromas en Unity (C#)
Integrar el hardware de Olorama en Unity requiere un sencillo script en C# que usa System.Net.Sockets.
Paso 1: Crea OloramaUDPSender.cs
Guarda el siguiente script de C# dentro de tu proyecto de Unity (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"; // IP de difusión (broadcast)
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}");
}
}
}
Paso 2: Uso en Unity
- Adjunta
OloramaUDPSender.csa cualquierGameObjectde tu escena. - Llama a
SendScentMessagedesde una zona de activación (trigger), un listener de eventos o un botón de la interfaz:
// Ejemplo: activa el aroma #3 de Olorama con 200 ms de intensidad y 4000 ms de ventilador
GetComponent<OloramaUDPSender>().SendScentMessage(3, 200, true, 4000);
2. Integración de aromas en Unreal Engine 5 (C++)
En Unreal Engine 5 puedes exponer un Actor de C++ personalizado a Blueprints usando la librería nativa de sockets de Unreal para controlar tus dispositivos Olorama.
Paso 1: Añade las dependencias de módulo (Build.cs)
Abre Source/YourProject/YourProject.Build.cs y añade "Sockets" y "Networking" a 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", // NECESARIO para el UDP de Olorama
"Networking" // NECESARIO para el UDP de Olorama
});
}
}
Importante: haz clic derecho sobre tu archivo .uproject y selecciona Generate Visual Studio project files después de modificar Build.cs.
Paso 2: Crea 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:
// Función invocable desde Blueprint para lanzar la emisión de aroma de Olorama
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;
};
Paso 3: Crea 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;
}
}
Paso 4: Uso en Unreal Engine 5
- Arrastra el Actor
AOloramaUDPSendera tu escena de Unreal. - Desde Blueprints, llama al nodo Send Scent Message.
Consideraciones técnicas y configuración de red
- Requisitos de LAN: asegúrate de que tu equipo de renderizado (PC o visor de VR) y el hardware de Olorama estén conectados a la misma subred de la red local.
- Configuración del firewall: verifica que el puerto UDP 5010 esté abierto y permitido en los firewalls del equipo.
- VR móvil / autónomo (Meta Quest): al compilar para Android o builds autónomas de Quest en Unity/Unreal, asegúrate de habilitar los permisos
INTERNETyACCESS_NETWORK_STATEen la configuración de tu proyecto.
Para más información sobre cómo integrar el hardware de Olorama en proyectos profesionales, visita nuestra página de Tecnología de Olor para Realidad Virtual o contacta con el equipo técnico de Olorama para soporte de SDK a medida.