using Marro.PacManUdon; using Newtonsoft.Json.Linq; using UdonSharp; using UnityEngine; using VRC.SDKBase; using VRC.Udon; public class NetworkManagerSyncTester : UdonSharpBehaviour { [SerializeField] NetworkManager networkManager1; [SerializeField] GridMover[] gridMovers1; [SerializeField] NetworkManager networkManager2; [SerializeField] GridMover[] gridMovers2; [SerializeField] Animator debugImageToIndicateSynced; private float captureTime; private Vector2[] positions; public void Update() { if (!networkManager1.Synced || !networkManager2.Synced) { positions = null; return; } if (positions == null) { positions = GetPositions(gridMovers1); captureTime = networkManager1.SyncedTime; } var remoteTime = networkManager2.SyncedTime; if (captureTime > remoteTime) { return; } if (captureTime < remoteTime) { Debug.Log($"{nameof(NetworkManagerSyncTester)} Skipping check"); positions = null; return; } bool equal = IsEqual(remoteTime); SetIndicator(equal); positions = null; } private bool IsEqual(float remoteTime) { var positions2 = GetPositions(gridMovers2); for (int i = 0; i < positions.Length; i++) { var gridMover1 = gridMovers1[i]; var gridMover1Position = positions[i]; var gridMover2 = gridMovers2[i]; var gridMover2Position = positions2[i]; var equal = gridMover1Position == gridMover2Position; if (!equal) { Debug.LogWarning($"{nameof(NetworkManagerSyncTester)} Desync found:\n{gridMover1.name} {gridMover1Position} (at {captureTime}) != {gridMover2.name} {gridMover2Position} (at {remoteTime})"); networkManager1.Pause(); networkManager2.Pause(); return false; } } return true; } private void SetIndicator(bool value) { if (debugImageToIndicateSynced != null) { debugImageToIndicateSynced.SetFloat("Color", value ? 1 : 0); } } private Vector2[] GetPositions(GridMover[] gridMovers) { var length = gridMovers.Length; var positions = new Vector2[length]; for (int i = 0; i < length; i++) { positions[i] = gridMovers[i].GetPosition(); } return positions; } }