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

@ -51,6 +51,16 @@ namespace Convai.Scripts.Runtime.Multiplayer
public Action<bool> OnSpeechTransmission;
public Action<string> OnSpeechSent;
// Metrics for debug UI
private int _totalClipsSent = 0;
private DateTime _lastClipSentTime;
public int TotalClipsSent => _totalClipsSent;
public float TimeSinceLastSend => _lastClipSentTime != default ?
(float)(DateTime.UtcNow - _lastClipSentTime).TotalSeconds : -1f;
public string CurrentTargetIP => targetIP;
public int CurrentTargetPort => targetPort;
public bool UsingDiscovery => NetworkConfig.Instance?.useAutoDiscovery ?? false;
private void Start()
{
// Get network config from global instance
@ -92,6 +102,53 @@ namespace Convai.Scripts.Runtime.Multiplayer
CleanupNetwork();
}
private void Update()
{
// Continuously update source NPC if using active NPC mode
if (useActiveNPC)
{
var currentActiveNPC = FindEnabledConvaiNPC();
if (currentActiveNPC != sourceNPC)
{
// Cleanup old subscriptions
CleanupNPCSubscriptions();
// Update to new NPC
sourceNPC = currentActiveNPC;
SubscribeToNPCEvents();
if (sourceNPC != null)
{
ConvaiLogger.Info($"🔄 UDP Speech Sender updated source NPC to: {sourceNPC.characterName} (on {sourceNPC.gameObject.name})", ConvaiLogger.LogCategory.Character);
}
else
{
ConvaiLogger.Info($"🔄 UDP Speech Sender cleared source 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 HandlePeerDiscovered(string peerIP)
{
targetIP = peerIP;
@ -128,7 +185,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
private void InitializeConvai()
{
// Prefer local ConvaiNPC on the same GameObject, then fall back to active NPC
// Prefer local ConvaiNPC on the same GameObject, then fall back to finding enabled NPC
var localNPC = GetComponent<ConvaiNPC>();
if (localNPC != null)
{
@ -136,7 +193,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
}
else if (useActiveNPC)
{
sourceNPC = ConvaiNPCManager.Instance?.GetActiveConvaiNPC();
sourceNPC = FindEnabledConvaiNPC();
}
SubscribeToNPCEvents();
@ -259,6 +316,10 @@ namespace Convai.Scripts.Runtime.Multiplayer
// Only increment sequence after the entire clip is sent
_speechSequence++;
// Update metrics
_totalClipsSent++;
_lastClipSentTime = DateTime.UtcNow;
OnSpeechSent?.Invoke(transcript);
if (enableDebugLogging)