using System.Collections; using System.Text; using UnityEngine; using UnityEngine.UIElements; namespace LiveOpsExamples { public static class UiDebugProbe { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] private static void Install() { new GameObject("UiDebugProbe").AddComponent(); } private sealed class Probe : MonoBehaviour { private PanelRenderer _panelRenderer; private VisualElement _root; private IEnumerator Start() { yield return null; yield return null; _panelRenderer = FindFirstObjectByType(); if (_panelRenderer == null) { Debug.Log("[UiProbe] PanelRenderer: NOT FOUND"); } else { _panelRenderer.RegisterUIReloadCallback(OnUIReload); } if (_root == null) { Dump("after-scene-load"); } while (true) { yield return new WaitForSecondsRealtime(10f); Dump("periodic"); } } private void OnDestroy() { if (_panelRenderer != null) { _panelRenderer.UnregisterUIReloadCallback(OnUIReload); } } private void OnUIReload(PanelRenderer renderer, VisualElement root) { _root = root; Dump("ui-reload"); } private void Dump(string tag) { var sb = new StringBuilder(); sb.AppendLine($"[UiProbe] --- {tag} ---"); sb.AppendLine($"screen={Screen.width}x{Screen.height}"); if (_panelRenderer == null) { sb.AppendLine("PanelRenderer: NOT FOUND"); Debug.Log(sb.ToString()); return; } var ps = _panelRenderer.panelSettings; sb.AppendLine(ps == null ? "panelSettings: NULL" : $"panelSettings={ps.name} scaleMode={ps.scaleMode} ref={ps.referenceResolution.x}x{ps.referenceResolution.y} match={ps.match} scale={ps.scale}"); if (_root == null) { sb.AppendLine("root: NULL (reload callback not fired yet)"); Debug.Log(sb.ToString()); return; } sb.AppendLine($"root worldBound={_root.worldBound} children={_root.childCount}"); var uiRoot = _root.childCount > 0 ? _root[0] : null; sb.AppendLine($"uiRoot={uiRoot?.name} children={uiRoot?.childCount}"); if (uiRoot != null) { foreach (var child in uiRoot.Children()) { Describe(sb, child); } } var renderers = FindObjectsByType(FindObjectsSortMode.None); sb.AppendLine($"panelRenderers={renderers.Length} panel={(_root.panel == null ? "null" : "ok")}"); Describe(sb, _root.Q("hud-score")); Describe(sb, _root.Q("hud-timer-fill")); Describe(sb, _root.Q("session-card")); Describe(sb, _root.Q("remote-config")); Describe(sb, _root.Q("event-log-scroll")); var controller = FindFirstObjectByType(); sb.AppendLine(controller == null ? "controller: NOT FOUND" : $"controller phase={controller.Phase} activeModal={controller.ActiveModal} status='{controller.StatusMessage}'"); var cam = Camera.main; sb.AppendLine(cam == null ? "camera: NOT FOUND" : $"camera rect={cam.rect} targetTexture={(cam.targetTexture == null ? "null" : cam.targetTexture.name)} enabled={cam.enabled} clearFlags={cam.clearFlags} time={Time.time:0.#} timeScale={Time.timeScale}"); Debug.Log(sb.ToString()); } private static void Describe(StringBuilder sb, VisualElement element) { if (element == null) { sb.AppendLine(" "); return; } var r = element.resolvedStyle; sb.AppendLine($" {element.name}: display={r.display} visibility={r.visibility} opacity={r.opacity} " + $"size={r.width:0.#}x{r.height:0.#} worldBound={element.worldBound} classes='{string.Join(",", element.GetClasses())}'"); } } } }