diff --git a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioReceiver.cs b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioReceiver.cs index 10b62d8..4db3174 100644 --- a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioReceiver.cs +++ b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioReceiver.cs @@ -234,10 +234,13 @@ namespace Convai.Scripts.Runtime.Multiplayer try { - _udpListener = new UdpClient(listenPort); + // Create UDP client with port reuse to allow sharing with UDPPeerDiscovery + _udpListener = new UdpClient(); + _udpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + _udpListener.Client.Bind(new IPEndPoint(IPAddress.Any, listenPort)); _isListening = true; - ConvaiLogger.Info($"Simple UDP Audio Receiver V2 listening on port {listenPort}", ConvaiLogger.LogCategory.Character); + ConvaiLogger.Info($"Simple UDP Audio Receiver V2 listening on port {listenPort} (shared)", ConvaiLogger.LogCategory.Character); // Start listening for incoming packets _ = ListenForAudioPackets(_cancellationTokenSource.Token); diff --git a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioSender.cs b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioSender.cs index 418de1c..a7ab0ae 100644 --- a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioSender.cs +++ b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiSimpleUDPAudioSender.cs @@ -487,7 +487,7 @@ namespace Convai.Scripts.Runtime.Multiplayer _localSamples.Clear(); } - ConvaiLogger.Info("Started recording for UDP transmission (Simple)", ConvaiLogger.LogCategory.Character); + ConvaiLogger.Info($"🎤 Started recording for UDP transmission to {targetIP}:{targetPort}", ConvaiLogger.LogCategory.Character); OnRecordingStateChanged?.Invoke(true); // Send START control and wait briefly for ACK to ensure receiver is ready diff --git a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechReceiver.cs b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechReceiver.cs index 193c3fc..89ed8b8 100644 --- a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechReceiver.cs +++ b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechReceiver.cs @@ -201,10 +201,13 @@ namespace Convai.Scripts.Runtime.Multiplayer try { - _udpListener = new UdpClient(listenPort); + // Create UDP client with port reuse to allow sharing with UDPPeerDiscovery + _udpListener = new UdpClient(); + _udpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + _udpListener.Client.Bind(new IPEndPoint(IPAddress.Any, listenPort)); _isListening = true; - ConvaiLogger.Info($"UDP Speech Receiver listening on port {listenPort}", ConvaiLogger.LogCategory.Character); + ConvaiLogger.Info($"UDP Speech Receiver listening on port {listenPort} (shared)", ConvaiLogger.LogCategory.Character); // Start listening for incoming packets _ = ListenForSpeechPackets(_cancellationTokenSource.Token); diff --git a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechSender.cs b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechSender.cs index f66c285..ec45a7e 100644 --- a/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechSender.cs +++ b/Unity-Master/Assets/Scripts/Multiplayer/ConvaiUDPSpeechSender.cs @@ -207,18 +207,23 @@ namespace Convai.Scripts.Runtime.Multiplayer private void SubscribeToNPCEvents() { - if (sourceNPC?.AudioManager != null) + if (sourceNPC == null) { - // Hook into the character talking events - sourceNPC.AudioManager.OnCharacterTalkingChanged += HandleCharacterTalkingChanged; - sourceNPC.AudioManager.OnAudioTranscriptAvailable += HandleTranscriptAvailable; - - ConvaiLogger.Info($"UDP Speech Sender subscribed to NPC: {sourceNPC.characterName}", ConvaiLogger.LogCategory.Character); + ConvaiLogger.Warn("SubscribeToNPCEvents: sourceNPC is null", ConvaiLogger.LogCategory.Character); + return; } - else + + if (sourceNPC.AudioManager == null) { - ConvaiLogger.Warn("No source NPC available for speech transmission", ConvaiLogger.LogCategory.Character); + ConvaiLogger.Warn($"SubscribeToNPCEvents: AudioManager is null for {sourceNPC.characterName}", ConvaiLogger.LogCategory.Character); + return; } + + // Hook into the character talking events + sourceNPC.AudioManager.OnCharacterTalkingChanged += HandleCharacterTalkingChanged; + sourceNPC.AudioManager.OnAudioTranscriptAvailable += HandleTranscriptAvailable; + + ConvaiLogger.Info($"✅ UDP Speech Sender subscribed to NPC: {sourceNPC.characterName} (on {sourceNPC.gameObject.name}), AudioManager: {sourceNPC.AudioManager.name}", ConvaiLogger.LogCategory.Character); } private void HandleCharacterTalkingChanged(bool isTalking) @@ -227,11 +232,13 @@ namespace Convai.Scripts.Runtime.Multiplayer if (isTalking) { + ConvaiLogger.Info($"🔊 NPC {sourceNPC.characterName} started talking, monitoring audio clips...", ConvaiLogger.LogCategory.Character); // Start monitoring for audio clips StartCoroutine(MonitorAudioClips()); } else { + ConvaiLogger.Info($"🔊 NPC {sourceNPC.characterName} stopped talking", ConvaiLogger.LogCategory.Character); // End speech transmission _ = SendFinalPacket(); } @@ -247,9 +254,20 @@ namespace Convai.Scripts.Runtime.Multiplayer private IEnumerator MonitorAudioClips() { - if (sourceNPC?.AudioManager == null) yield break; + if (sourceNPC?.AudioManager == null) + { + ConvaiLogger.Warn("MonitorAudioClips: AudioManager is null", ConvaiLogger.LogCategory.Character); + yield break; + } AudioSource audioSource = sourceNPC.AudioManager.GetComponent(); + if (audioSource == null) + { + ConvaiLogger.Warn("MonitorAudioClips: AudioSource is null", ConvaiLogger.LogCategory.Character); + yield break; + } + + ConvaiLogger.Info($"🔊 Started monitoring audio clips on {audioSource.name}", ConvaiLogger.LogCategory.Character); AudioClip lastClip = null; while (sourceNPC.IsCharacterTalking) @@ -258,6 +276,7 @@ namespace Convai.Scripts.Runtime.Multiplayer { // New clip detected! lastClip = audioSource.clip; + ConvaiLogger.Info($"🔊 Detected new audio clip: {lastClip.name}, length: {lastClip.length:F2}s", ConvaiLogger.LogCategory.Character); // Only send if we haven't sent this clip before if (!_sentClips.Contains(lastClip)) @@ -268,13 +287,19 @@ namespace Convai.Scripts.Runtime.Multiplayer string transcript = GetRecentTranscript(); // Send this clip + ConvaiLogger.Info($"🔊 Transmitting audio clip to {targetIP}:{targetPort}", ConvaiLogger.LogCategory.Character); _ = TransmitAudioClip(lastClip, transcript); } + else + { + ConvaiLogger.Info($"🔊 Clip already sent, skipping", ConvaiLogger.LogCategory.Character); + } } yield return new WaitForSeconds(0.1f); // Check every 100ms } + ConvaiLogger.Info($"🔊 Stopped monitoring audio clips (NPC stopped talking)", ConvaiLogger.LogCategory.Character); // Clear sent clips when done _sentClips.Clear(); } diff --git a/Unity-Master/ProjectSettings/EditorBuildSettings.asset b/Unity-Master/ProjectSettings/EditorBuildSettings.asset index fb169eb..290a860 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:1ae56a0aa5e5fcd905f8d677138aa623b5c695c0f95a066ae70847afb086ef01 +oid sha256:57814a7518569d818e2d6fd8ddb8c5543ec9a81bdd1b5c6266f4d9f5ea9eaf31 size 1111 diff --git a/Unity-Master/ProjectSettings/ProjectSettings.asset b/Unity-Master/ProjectSettings/ProjectSettings.asset index 5687f99..a8004b2 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:e3021b170955d24126c440f68eacf051f182187e316381b898403f6bba7b1271 +oid sha256:9fbb1f7b761b58869e3f1adcbabe77be01115d75cefd557c504b4fb3aa50b129 size 24723