using System; using System.Reflection; using LiveOpsExamples; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; using Object = UnityEngine.Object; namespace LiveOpsExamples.Editor { /// /// Builds the Cozy Collector UI: a GameObject with a PanelRenderer (PanelSettings + /// CozyCollectorUI.uxml) and all panel components wired through serialized /// references. The PanelSettings asset is created programmatically when missing. /// Called from . /// public static partial class CozyCollectorBake { private const string UiFolderPath = "Assets/LiveOpsExamples/UI"; private const string UiPanelSettingsPath = UiFolderPath + "/CozyCollectorPanelSettings.asset"; private const string UiDocumentAssetPath = UiFolderPath + "/CozyCollectorUI.uxml"; private const string UiLogRowTemplatePath = UiFolderPath + "/LogRow.uxml"; private const string UiToastTemplatePath = UiFolderPath + "/ToastRow.uxml"; private const string UiShopOfferRowTemplatePath = UiFolderPath + "/ShopOfferRow.uxml"; private const string UiBackpackItemRowTemplatePath = UiFolderPath + "/BackpackItemRow.uxml"; private const string UiLeaderboardRowTemplatePath = UiFolderPath + "/LeaderboardRow.uxml"; private static void BuildUi(CozyCollectorController controller, GameWorld world) { var panelSettings = GetOrCreatePanelSettings(); var visualTree = LoadUiAsset(UiDocumentAssetPath); var uiGo = new GameObject("UI"); var panelRenderer = uiGo.AddComponent(); panelRenderer.panelSettings = panelSettings; if (visualTree != null) { panelRenderer.visualTreeAsset = visualTree; } WirePanel(uiGo.AddComponent(), panelRenderer, controller); WirePanel(uiGo.AddComponent(), panelRenderer, controller); var eventInspector = uiGo.AddComponent(); WirePanel(eventInspector, panelRenderer, controller); WireTemplate(eventInspector, "logRowTemplate", UiLogRowTemplatePath); var hud = uiGo.AddComponent(); WirePanel(hud, panelRenderer, controller); SetSceneReference(hud, "world", world); var toasts = uiGo.AddComponent(); WirePanel(toasts, panelRenderer, controller); WireTemplate(toasts, "toastTemplate", UiToastTemplatePath); WirePanel(uiGo.AddComponent(), panelRenderer, controller); WirePanel(uiGo.AddComponent(), panelRenderer, controller); var shop = uiGo.AddComponent(); WirePanel(shop, panelRenderer, controller); WireTemplate(shop, "shopOfferRowTemplate", UiShopOfferRowTemplatePath); var backpack = uiGo.AddComponent(); WirePanel(backpack, panelRenderer, controller); WireTemplate(backpack, "backpackItemRowTemplate", UiBackpackItemRowTemplatePath); var spriteLibrary = AssetDatabase.LoadAssetAtPath(SpriteLibraryPath); if (spriteLibrary == null) { Debug.LogError($"[CozyCollectorBake] Sprite library not found at {SpriteLibraryPath}. " + "Run Tools/LiveOps/Bake Cozy Collector (All) first."); } else { SetSceneReference(backpack, "spriteLibrary", spriteLibrary); } WirePanel(uiGo.AddComponent(), panelRenderer, controller); var roundResult = uiGo.AddComponent(); WirePanel(roundResult, panelRenderer, controller); WireTemplate(roundResult, "leaderboardRowTemplate", UiLeaderboardRowTemplatePath); } private static void WirePanel(MonoBehaviour panel, PanelRenderer panelRenderer, CozyCollectorController controller) { SetSceneReference(panel, "panelRenderer", panelRenderer); SetSceneReference(panel, "controller", controller); } private static void WireTemplate(MonoBehaviour panel, string fieldName, string templatePath) { var template = LoadUiAsset(templatePath); if (template != null) { SetSceneReference(panel, fieldName, template); } } private static T LoadUiAsset(string path) where T : Object { var asset = AssetDatabase.LoadAssetAtPath(path); if (asset == null) { Debug.LogError($"[CozyCollectorBake] {typeof(T).Name} not found at {path}. " + "The scene is saved with an empty reference."); } return asset; } private static PanelSettings GetOrCreatePanelSettings() { var settings = AssetDatabase.LoadAssetAtPath(UiPanelSettingsPath); if (settings != null) { return settings; } EnsureAssetFolder(UiFolderPath); settings = ScriptableObject.CreateInstance(); settings.scaleMode = PanelScaleMode.ScaleWithScreenSize; settings.referenceResolution = new Vector2Int(1600, 900); settings.screenMatchMode = PanelScreenMatchMode.MatchWidthOrHeight; settings.match = 0.5f; var defaultTheme = LoadDefaultRuntimeTheme(); if (defaultTheme != null) { settings.themeStyleSheet = defaultTheme; } AssetDatabase.CreateAsset(settings, UiPanelSettingsPath); return settings; } private static ThemeStyleSheet LoadDefaultRuntimeTheme() { var themeUtility = Type.GetType("UnityEditor.UIElements.ThemeUtility, UnityEditor.UIElementsModule"); var property = themeUtility?.GetProperty("builtInDefaultRuntimeTheme", BindingFlags.Static | BindingFlags.NonPublic); return property?.GetValue(null) as ThemeStyleSheet; } } }