diff --git a/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs b/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs
index 492d1ab..b3774b8 100644
--- a/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs
+++ b/Unity-Master/Assets/Scripts/Multiplayer/SharedUDPListener.cs
@@ -93,6 +93,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
ConvaiLogger.Info($" - Voice Audio: 0xC0A1", ConvaiLogger.LogCategory.Character);
ConvaiLogger.Info($" - NPC Speech: 0xC0A3", ConvaiLogger.LogCategory.Character);
ConvaiLogger.Info($" - Avatar Sync: 0xC0A0", ConvaiLogger.LogCategory.Character);
+ ConvaiLogger.Info($" - Experiment Control: JSON (text-based)", ConvaiLogger.LogCategory.Character);
// Start listening for all packets
_ = ListenForPackets(_cancellationTokenSource.Token);
diff --git a/Unity-Master/Assets/Scripts/VRExperimentController.cs b/Unity-Master/Assets/Scripts/VRExperimentController.cs
index bbc6020..05810af 100644
--- a/Unity-Master/Assets/Scripts/VRExperimentController.cs
+++ b/Unity-Master/Assets/Scripts/VRExperimentController.cs
@@ -2,9 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
-using System.Net.Sockets;
using System.Text;
-using System.Threading;
using UnityEngine;
using Newtonsoft.Json;
@@ -34,8 +32,6 @@ public class VRExperimentController : MonoBehaviour
[SerializeField] private bool enableDebugLogging = true;
// Network components
- private UdpClient udpClient;
- private Thread udpListenerThread;
private bool isListening = false;
private int udpPort;
@@ -197,70 +193,40 @@ public class VRExperimentController : MonoBehaviour
{
try
{
- if (allowPortSharing)
+ // Wait for shared listener to be ready
+ if (Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance == null)
{
- // Create UDP client with port reuse for local testing
- udpClient = new UdpClient();
- udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, udpPort));
- }
- else
- {
- // Standard UDP client binding
- udpClient = new UdpClient(udpPort);
+ LogError("SharedUDPListener not found! Make sure it's in the scene.");
+ return;
}
- udpListenerThread = new Thread(new ThreadStart(UDPListenerLoop));
- udpListenerThread.IsBackground = true;
+ // Subscribe to shared listener
+ Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance.OnPacketReceived += HandlePacketReceived;
isListening = true;
- udpListenerThread.Start();
- LogMessage($"UDP Experiment Control Listener started on port {udpPort} (filtering JSON messages only, Port sharing: {allowPortSharing})");
+ LogMessage($"UDP Experiment Control Listener subscribed to shared listener on port {udpPort} (filtering JSON messages only)");
}
catch (Exception e)
{
- if (allowPortSharing)
- {
- LogError($"Failed to start UDP listener with port sharing: {e.Message}");
- LogMessage("Trying with different port...");
- TryAlternativePort();
- }
- else
- {
- LogError($"Failed to start UDP listener: {e.Message}");
- }
+ LogError($"Failed to subscribe to shared UDP listener: {e.Message}");
}
}
///
- /// Try alternative ports for local testing
+ /// Handle packet received from shared listener
///
- private void TryAlternativePort()
+ private void HandlePacketReceived(byte[] data, IPEndPoint senderEndPoint)
{
- // Try a few alternative ports for local testing
- int[] alternativePorts = { 1222, 1223, 1224, 1225, 1226 };
+ // Check if this is an experiment control message (JSON)
+ if (!IsExperimentControlMessage(data)) return;
- foreach (int port in alternativePorts)
+ string message = Encoding.UTF8.GetString(data);
+
+ // Add message to queue for main thread processing
+ lock (queueLock)
{
- try
- {
- udpClient = new UdpClient(port);
- udpListenerThread = new Thread(new ThreadStart(UDPListenerLoop));
- udpListenerThread.IsBackground = true;
- isListening = true;
- udpListenerThread.Start();
-
- LogMessage($"UDP Experiment Control Listener started on alternative port {port}");
- return;
- }
- catch (Exception)
- {
- // Try next port
- continue;
- }
+ messageQueue.Enqueue(message);
}
-
- LogError("Failed to start UDP listener on any available port");
}
///
@@ -270,59 +236,15 @@ public class VRExperimentController : MonoBehaviour
{
isListening = false;
- if (udpClient != null)
+ // Unsubscribe from shared listener
+ if (Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance != null)
{
- udpClient.Close();
- udpClient = null;
- }
-
- if (udpListenerThread != null && udpListenerThread.IsAlive)
- {
- udpListenerThread.Join(1000); // Wait up to 1 second
- if (udpListenerThread.IsAlive)
- {
- udpListenerThread.Abort();
- }
- udpListenerThread = null;
+ Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance.OnPacketReceived -= HandlePacketReceived;
}
LogMessage("UDP Listener stopped");
}
- ///
- /// UDP listener loop (runs in separate thread)
- ///
- private void UDPListenerLoop()
- {
- while (isListening)
- {
- try
- {
- IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, udpPort);
- byte[] data = udpClient.Receive(ref remoteEndPoint);
-
- // Check if this looks like a JSON experiment control message
- if (IsExperimentControlMessage(data))
- {
- string message = Encoding.UTF8.GetString(data);
-
- // Add message to queue for main thread processing
- lock (queueLock)
- {
- messageQueue.Enqueue(message);
- }
- }
- // If it's not an experiment control message (likely avatar data), ignore it
- }
- catch (Exception e)
- {
- if (isListening) // Only log if we're still supposed to be listening
- {
- LogError($"UDP Listener error: {e.Message}");
- }
- }
- }
- }
///
/// Check if the received data is an experiment control message (JSON) vs avatar data (binary)
@@ -684,9 +606,9 @@ public class VRExperimentController : MonoBehaviour
///
private int GetActualListenPort()
{
- if (udpClient?.Client?.LocalEndPoint != null)
+ if (Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance != null)
{
- return ((IPEndPoint)udpClient.Client.LocalEndPoint).Port;
+ return Convai.Scripts.Runtime.Multiplayer.SharedUDPListener.Instance.ListenPort;
}
return udpPort;
}
diff --git a/Unity-Master/ProjectSettings/EditorBuildSettings.asset b/Unity-Master/ProjectSettings/EditorBuildSettings.asset
index 290a860..fb169eb 100644
--- a/Unity-Master/ProjectSettings/EditorBuildSettings.asset
+++ b/Unity-Master/ProjectSettings/EditorBuildSettings.asset
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:57814a7518569d818e2d6fd8ddb8c5543ec9a81bdd1b5c6266f4d9f5ea9eaf31
+oid sha256:1ae56a0aa5e5fcd905f8d677138aa623b5c695c0f95a066ae70847afb086ef01
size 1111
diff --git a/Unity-Master/ProjectSettings/ProjectSettings.asset b/Unity-Master/ProjectSettings/ProjectSettings.asset
index a8004b2..5687f99 100644
--- a/Unity-Master/ProjectSettings/ProjectSettings.asset
+++ b/Unity-Master/ProjectSettings/ProjectSettings.asset
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9fbb1f7b761b58869e3f1adcbabe77be01115d75cefd557c504b4fb3aa50b129
+oid sha256:e3021b170955d24126c440f68eacf051f182187e316381b898403f6bba7b1271
size 24723