removed legacy avatar synchronization scripts and server implementation, transitioning to a new UDP-based system for improved performance and efficiency

This commit is contained in:
tom.hempel
2025-10-21 18:01:33 +02:00
parent f96c76d095
commit 18f3abbd7d
35 changed files with 162 additions and 3963 deletions

View File

@ -10,9 +10,6 @@ using UnityEngine;
public class UDPAvatarReceiver : MonoBehaviour
{
[Header("Network Configuration")]
[SerializeField] private int listenPort = 8080;
[SerializeField] private bool useGlobalNetworkConfig = true;
[SerializeField] private NetworkConfig networkConfigAsset;
[SerializeField] private bool enableReceiver = true;
[SerializeField] private byte targetPlayerID = 2; // Which player to receive data from (0 = any)
[SerializeField] private bool allowPortSharing = true; // For local testing with multiple components
@ -44,6 +41,7 @@ public class UDPAvatarReceiver : MonoBehaviour
private UdpClient udpClient;
private Thread udpListenerThread;
private bool threadRunning = false;
private int listenPort;
private Dictionary<string, Transform> boneCache;
private List<Transform> allBones; // For full data mode
private List<SkinnedMeshRenderer> allMeshes; // For full blend shapes
@ -60,6 +58,9 @@ public class UDPAvatarReceiver : MonoBehaviour
private int packetsDropped = 0;
private float lastPacketTime = 0f;
// Magic number for packet identification
private const uint AVATAR_MAGIC = 0xC0A0;
// Avatar data structure - supports both optimized and full data modes (matches broadcaster)
private struct CompactAvatarData
{
@ -87,14 +88,16 @@ public class UDPAvatarReceiver : MonoBehaviour
if (targetAvatarRoot == null)
targetAvatarRoot = transform;
// Apply global config if enabled
if (useGlobalNetworkConfig)
// Get network config from global instance
var cfg = NetworkConfig.Instance;
if (cfg != null)
{
var cfg = networkConfigAsset != null ? networkConfigAsset : NetworkConfig.Instance;
if (cfg != null)
{
listenPort = cfg.port;
}
listenPort = cfg.port;
}
else
{
Debug.LogError("NetworkConfig not found! Please ensure NetworkConfig.asset exists in Resources folder.");
listenPort = 1221;
}
CacheAvatarComponents();
@ -323,52 +326,16 @@ public class UDPAvatarReceiver : MonoBehaviour
{
try
{
// Avatar data should be binary and typically larger than JSON experiment messages
if (data.Length < 20) // Avatar data should have at least header info
// Check minimum size for magic number
if (data.Length < 4)
return false;
// Check if it looks like text/JSON (experiment control message)
// JSON messages will be valid UTF-8 text starting with '{'
try
{
string text = Encoding.UTF8.GetString(data);
if (text.TrimStart().StartsWith("{") && text.Contains("\"command\""))
{
// This is likely an experiment control message, not avatar data
return false;
}
}
catch
{
// If it fails to decode as UTF-8, it's likely binary avatar data
}
// Additional check: avatar data should start with a reasonable playerID (0-255)
// and have a structure that makes sense
using (MemoryStream stream = new MemoryStream(data))
using (BinaryReader reader = new BinaryReader(stream))
{
// Basic structure check - should be able to read at least the header
if (data.Length >= 17) // byte + uint32 + uint32 + bool + 12 bytes for Vector3
{
byte playerID = reader.ReadByte();
uint sequenceNumber = reader.ReadUInt32();
uint timestamp = reader.ReadUInt32();
bool isFullDataMode = reader.ReadBoolean();
// Basic sanity checks
if (playerID <= 10 && sequenceNumber < uint.MaxValue / 2) // Reasonable values
{
return true;
}
}
}
return false;
// Check for avatar magic number (0xC0A0)
uint magic = BitConverter.ToUInt32(data, 0);
return magic == AVATAR_MAGIC;
}
catch
{
// If any parsing fails, assume it's not valid avatar data
return false;
}
}
@ -378,6 +345,14 @@ public class UDPAvatarReceiver : MonoBehaviour
using (MemoryStream stream = new MemoryStream(data))
using (BinaryReader reader = new BinaryReader(stream))
{
// Read and validate magic number
uint magic = reader.ReadUInt32();
if (magic != AVATAR_MAGIC)
{
Debug.LogWarning($"Invalid avatar packet magic number: 0x{magic:X} (expected 0x{AVATAR_MAGIC:X})");
return default;
}
CompactAvatarData result = new CompactAvatarData
{
// Header