enhanced UDP audio sender/receiver scripts with metrics for packet tracking and improved NPC assignment logic

This commit is contained in:
tom.hempel
2025-10-23 03:08:51 +02:00
parent 6a99392e34
commit 73b921fc9b
13 changed files with 751 additions and 12 deletions

View File

@ -28,6 +28,14 @@ namespace Convai.Scripts.Runtime.Multiplayer
// Events
public Action<bool> OnAudioReceiving;
// Metrics for debug UI
private int _totalPacketsReceived = 0;
private DateTime _lastPacketReceivedTime;
public int TotalPacketsReceived => _totalPacketsReceived;
public float TimeSinceLastReceive => _lastPacketReceivedTime != default ?
(float)(DateTime.UtcNow - _lastPacketReceivedTime).TotalSeconds : -1f;
public int ListenPort => listenPort;
// Network components
private UdpClient _udpListener;
private IPEndPoint _remoteEndPoint;
@ -107,6 +115,17 @@ namespace Convai.Scripts.Runtime.Multiplayer
_cancellationTokenSource = new CancellationTokenSource();
}
StartListening();
// Immediately try to assign an enabled NPC
if (useActiveNPC && targetNPC == null)
{
var currentActiveNPC = FindEnabledConvaiNPC();
if (currentActiveNPC != null)
{
targetNPC = currentActiveNPC;
ConvaiLogger.Info($"🔄 UDP Audio Receiver assigned target NPC on enable: {targetNPC.characterName} (on {targetNPC.gameObject.name})", ConvaiLogger.LogCategory.Character);
}
}
}
private void OnDestroy()
@ -135,6 +154,47 @@ namespace Convai.Scripts.Runtime.Multiplayer
{
StopTalkingSimulation();
}
// Continuously update target NPC if using active NPC mode
if (useActiveNPC)
{
var currentActiveNPC = FindEnabledConvaiNPC();
// Update whenever the active NPC changes (including null → NPC or NPC → different NPC)
if (currentActiveNPC != targetNPC)
{
targetNPC = currentActiveNPC;
if (targetNPC != null)
{
ConvaiLogger.Info($"🔄 UDP Audio Receiver updated target NPC to: {targetNPC.characterName} (on {targetNPC.gameObject.name})", ConvaiLogger.LogCategory.Character);
}
else
{
ConvaiLogger.Info($"🔄 UDP Audio Receiver cleared target NPC", ConvaiLogger.LogCategory.Character);
}
}
}
}
/// <summary>
/// Finds an enabled ConvaiNPC in the scene (doesn't rely on ConvaiNPCManager raycasting)
/// </summary>
private ConvaiNPC FindEnabledConvaiNPC()
{
// Find all ConvaiNPC components in the scene (including inactive GameObjects)
var allNPCs = FindObjectsOfType<ConvaiNPC>(true);
// Return the first one that's on an active GameObject
foreach (var npc in allNPCs)
{
if (npc.gameObject.activeInHierarchy && npc.enabled)
{
return npc;
}
}
return null;
}
private void InitializeNetwork()
@ -151,10 +211,10 @@ namespace Convai.Scripts.Runtime.Multiplayer
private void InitializeConvai()
{
// Get target NPC
// Get target NPC by finding enabled NPCs in the scene
if (useActiveNPC)
{
targetNPC = ConvaiNPCManager.Instance?.GetActiveConvaiNPC();
targetNPC = FindEnabledConvaiNPC();
}
if (targetNPC == null)
@ -163,7 +223,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
}
else
{
ConvaiLogger.Info($"UDP Audio Receiver V2 initialized with NPC: {targetNPC.characterName}", ConvaiLogger.LogCategory.Character);
ConvaiLogger.Info($"UDP Audio Receiver V2 initialized with NPC: {targetNPC.characterName} (on {targetNPC.gameObject.name})", ConvaiLogger.LogCategory.Character);
}
}
@ -238,6 +298,10 @@ namespace Convai.Scripts.Runtime.Multiplayer
var packet = packetData.Value;
_lastPacketTime = Time.time;
// Update metrics
_totalPacketsReceived++;
_lastPacketReceivedTime = DateTime.UtcNow;
if (enableDebugLogging)
{
if (packet.isEndSignal)
@ -299,10 +363,10 @@ namespace Convai.Scripts.Runtime.Multiplayer
if (_isReceivingAudio) return;
MainThreadDispatcher.Instance.RunOnMainThread(() => {
// Update target NPC if using active NPC
// Update target NPC by finding enabled NPCs in the scene
if (useActiveNPC)
{
targetNPC = ConvaiNPCManager.Instance?.GetActiveConvaiNPC();
targetNPC = FindEnabledConvaiNPC();
}
if (targetNPC == null)
@ -324,7 +388,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
// This is the KEY! Simulate a talk key press to trigger normal Convai flow
ConvaiInputManager.Instance.talkKeyInteract?.Invoke(true);
ConvaiLogger.Info($"🎤 Started talking simulation for {targetNPC.characterName} (remote player audio)", ConvaiLogger.LogCategory.Character);
ConvaiLogger.Info($"🎤 Started talking simulation for {targetNPC.characterName} (on {targetNPC.gameObject.name}) (remote player audio)", ConvaiLogger.LogCategory.Character);
});
}