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;
}
}
}