using System.Collections; using System.IO; using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; using UnityEngine.TextCore.Text; using UnityEngine.UIElements; namespace Luneraria.UI.Tests { /// /// U3A decision probe: a UI Toolkit panel renders into a texture in batch mode, with the plate /// drawing, all glyphs and the three font weights (Regular, Regular with a 0.25 px outline for /// the G3 weight 560, Bold). Writes tools/out/ui-spike.png (docs/port/screenshots/u3/00). /// public sealed class UiToolkitProbeTests { sealed class Plate : VisualElement { readonly LunePlateStyle _style; public Plate(LunePlateStyle style) { _style = style; style.ApplyPadding(this); generateVisualContent += context => LunePlates.Draw(context, new Rect(0, 0, layout.width, layout.height), _style); } } sealed class Glyph : VisualElement { public Glyph(string name, Color color, float edge) { this.style.width = edge; this.style.height = edge; generateVisualContent += context => LuneGlyphs.Draw(context.painter2D, name, new Rect(0, 0, layout.width, layout.height), color); } } static Label Text(string value, FontAsset font, float size, Color color, float outline = 0f, float spacing = 0f) { var label = new Label(value); label.style.unityFontDefinition = FontDefinition.FromSDFFont(font); label.style.fontSize = size; label.style.color = color; label.style.letterSpacing = spacing; label.style.marginLeft = 0; label.style.paddingLeft = 0; if (outline > 0f) { label.style.unityTextOutlineWidth = outline; label.style.unityTextOutlineColor = color; } label.style.textShadow = new TextShadow { offset = new Vector2(0f, 1f), blurRadius = 1f, color = new Color(0f, 0f, 0f, .55f) }; return label; } [UnityTest] public IEnumerator PanelRendersIntoTexture() { #if UNITY_EDITOR var assets = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Luneraria/Settings/LuneUi.asset"); #else LuneUiAssets assets = null; #endif Assert.IsNotNull(assets); var target = new RenderTexture(1920, 1080, 0, RenderTextureFormat.ARGB32); var settings = ScriptableObject.CreateInstance(); settings.themeStyleSheet = assets.Theme; settings.targetTexture = target; settings.scaleMode = PanelScaleMode.ScaleWithScreenSize; settings.referenceResolution = new Vector2Int(1600, 960); settings.screenMatchMode = PanelScreenMatchMode.Expand; settings.clearColor = true; settings.colorClearValue = new Color(.28f, .36f, .22f, 1f); var host = new GameObject("UiSpike"); var document = host.AddComponent(); document.panelSettings = settings; yield return null; VisualElement root = document.rootVisualElement; var panel = new Plate(LunePlateStyle.Hud(LuneUiTheme.SlateTop, LuneUiTheme.SlateBottom, LuneUiTheme.Edge, 1f, 6f, 12f, 10f)); panel.style.position = Position.Absolute; panel.style.left = 12; panel.style.top = 12; panel.style.width = 760; root.Add(panel); panel.Add(Text("WELLE 21", assets.Display, 30, LuneUiTheme.Hex("f4e6c4"), 0f, 3f)); panel.Add(Text("DEIN ANCIENT · BLAU", assets.TextBold, 14, LuneUiTheme.BronzeLight, 0f, 2f)); panel.Add(Text("Regular 400: Einheiten mit „Grotte“ entsenden. 12.000 / 12.000", assets.Text, 15, LuneUiTheme.Text)); panel.Add(Text("Regular + 0,25 Kontur: Einheiten mit „Grotte“ entsenden. 12.000 / 12.000", assets.Text, 15, LuneUiTheme.Text, .25f)); panel.Add(Text("Regular + 0,45 Kontur: Einheiten mit „Grotte“ entsenden. 12.000 / 12.000", assets.Text, 15, LuneUiTheme.Text, .45f)); panel.Add(Text("Bold 700: Einheiten mit „Grotte“ entsenden. 12.000 / 12.000", assets.TextBold, 15, LuneUiTheme.Text)); panel.Add(Text("235", assets.TextBold, 24, LuneUiTheme.Gold)); var glyphs = new VisualElement(); glyphs.style.flexDirection = FlexDirection.Row; glyphs.style.flexWrap = Wrap.Wrap; glyphs.style.marginTop = 8; panel.Add(glyphs); foreach (string name in LuneGlyphs.Names) { var glyph = new Glyph(name, name.StartsWith("emblem_1") || name == "shape_1" ? LuneUiTheme.Team[1] : name.StartsWith("emblem_0") || name == "shape_0" ? LuneUiTheme.Team[0] : LuneUiTheme.Text, 28f); glyph.style.marginRight = 6; glyph.style.marginBottom = 6; glyphs.Add(glyph); } var buttons = new VisualElement(); buttons.style.flexDirection = FlexDirection.Row; panel.Add(buttons); var primary = new Plate(LunePlateStyle.Menu(LuneUiTheme.Hex("e8c47e"), LuneUiTheme.Hex("b98a4a"), LuneUiTheme.Hex("fff0cc"), 1.5f, 9f, 30f, 15f)); primary.Add(Text("BEREIT", assets.Display, 22, LuneUiTheme.Ink, 0f, 2f)); buttons.Add(primary); var card = new Plate(LunePlateStyle.Hud(LuneUiTheme.Hex("19222c"), LuneUiTheme.Hex("10161d"), LuneUiTheme.Hex("34424f"), 1f, 7f, 6f, 6f)); card.style.width = 116; card.style.height = 132; card.style.marginLeft = 10; buttons.Add(card); for (int frame = 0; frame < 6; frame++) yield return null; RenderTexture.active = target; var image = new Texture2D(1920, 1080, TextureFormat.RGBA32, false); image.ReadPixels(new Rect(0, 0, 1920, 1080), 0, 0); image.Apply(); RenderTexture.active = null; string file = Path.Combine(Path.GetDirectoryName(Application.dataPath), "tools/out/ui-spike.png"); Directory.CreateDirectory(Path.GetDirectoryName(file)); File.WriteAllBytes(file, image.EncodeToPNG()); Color corner = image.GetPixel(1900, 20); Color panelPixel = image.GetPixel(100, 1080 - 100); Debug.Log("LUNE_SPIKE corner " + corner + " panel " + panelPixel + " layout " + panel.layout); Object.Destroy(host); Assert.Greater(panel.layout.height, 50f); } } }