Fixed UI ordering
This commit is contained in:
@@ -164,19 +164,12 @@ namespace SplashEdit.RuntimeCode
|
|||||||
Debug.Log($"[UIExporter] Canvas '{canvas.CanvasName}' on '{canvas.gameObject.name}' " +
|
Debug.Log($"[UIExporter] Canvas '{canvas.CanvasName}' on '{canvas.gameObject.name}' " +
|
||||||
$"canvasW={canvasW} canvasH={canvasH} childCount={canvas.transform.childCount}");
|
$"canvasW={canvasW} canvasH={canvasH} childCount={canvas.transform.childCount}");
|
||||||
|
|
||||||
// Log what each collector finds
|
// Collect all UI elements in hierarchy order (depth-first, sibling index).
|
||||||
int prevCount = elements.Count;
|
// GetComponentsInChildren returns top-of-hierarchy first, but the C++
|
||||||
CollectImages(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements);
|
// renderer draws index 0 first (back). Reverse so that top-of-hierarchy
|
||||||
Debug.Log($"[UIExporter] Images: {elements.Count - prevCount}");
|
// elements are rendered last (on top), matching Unity's visual stacking.
|
||||||
prevCount = elements.Count;
|
CollectAllElementsInHierarchyOrder(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements, uniqueFonts);
|
||||||
CollectBoxes(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements);
|
elements.Reverse();
|
||||||
Debug.Log($"[UIExporter] Boxes: {elements.Count - prevCount}");
|
|
||||||
prevCount = elements.Count;
|
|
||||||
CollectTexts(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements, uniqueFonts);
|
|
||||||
Debug.Log($"[UIExporter] Texts: {elements.Count - prevCount}");
|
|
||||||
prevCount = elements.Count;
|
|
||||||
CollectProgressBars(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements);
|
|
||||||
Debug.Log($"[UIExporter] ProgressBars: {elements.Count - prevCount}");
|
|
||||||
Debug.Log($"[UIExporter] TOTAL elements: {elements.Count}");
|
Debug.Log($"[UIExporter] TOTAL elements: {elements.Count}");
|
||||||
|
|
||||||
string name = canvas.CanvasName ?? "canvas";
|
string name = canvas.CanvasName ?? "canvas";
|
||||||
@@ -258,6 +251,214 @@ namespace SplashEdit.RuntimeCode
|
|||||||
|
|
||||||
// ─── Collectors ───
|
// ─── Collectors ───
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Walk the hierarchy depth-first in sibling order, collecting every
|
||||||
|
/// PSX UI component into <paramref name="elements"/> so that draw order
|
||||||
|
/// matches the Unity scene tree (top-to-bottom = back-to-front).
|
||||||
|
/// </summary>
|
||||||
|
private static void CollectAllElementsInHierarchyOrder(
|
||||||
|
Transform root, RectTransform canvasRect,
|
||||||
|
float scaleX, float scaleY, Vector2 resolution,
|
||||||
|
List<PSXUIElementData> elements,
|
||||||
|
List<PSXFontAsset> uniqueFonts)
|
||||||
|
{
|
||||||
|
// GetComponentsInChildren iterates depth-first in sibling order —
|
||||||
|
// exactly the hierarchy ordering we want.
|
||||||
|
Transform[] allTransforms = root.GetComponentsInChildren<Transform>(true);
|
||||||
|
foreach (Transform t in allTransforms)
|
||||||
|
{
|
||||||
|
if (t == root) continue; // skip the canvas root itself
|
||||||
|
|
||||||
|
// Check each supported component type on this transform.
|
||||||
|
// A single GameObject should only have one PSX UI component,
|
||||||
|
// but we check all to be safe.
|
||||||
|
PSXUIImage img = t.GetComponent<PSXUIImage>();
|
||||||
|
if (img != null)
|
||||||
|
{
|
||||||
|
CollectSingleImage(img, canvasRect, scaleX, scaleY, resolution, elements);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSXUIBox box = t.GetComponent<PSXUIBox>();
|
||||||
|
if (box != null)
|
||||||
|
{
|
||||||
|
CollectSingleBox(box, canvasRect, scaleX, scaleY, resolution, elements);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSXUIText txt = t.GetComponent<PSXUIText>();
|
||||||
|
if (txt != null)
|
||||||
|
{
|
||||||
|
CollectSingleText(txt, canvasRect, scaleX, scaleY, resolution, elements, uniqueFonts);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSXUIProgressBar bar = t.GetComponent<PSXUIProgressBar>();
|
||||||
|
if (bar != null)
|
||||||
|
{
|
||||||
|
CollectSingleProgressBar(bar, canvasRect, scaleX, scaleY, resolution, elements);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CollectSingleImage(
|
||||||
|
PSXUIImage img, RectTransform canvasRect,
|
||||||
|
float scaleX, float scaleY, Vector2 resolution,
|
||||||
|
List<PSXUIElementData> elements)
|
||||||
|
{
|
||||||
|
RectTransform rt = img.GetComponent<RectTransform>();
|
||||||
|
if (rt == null) return;
|
||||||
|
|
||||||
|
BakeLayout(rt, canvasRect, scaleX, scaleY, resolution,
|
||||||
|
out short x, out short y, out short w, out short h,
|
||||||
|
out byte amin_x, out byte amin_y, out byte amax_x, out byte amax_y);
|
||||||
|
|
||||||
|
var data = new PSXUIElementData
|
||||||
|
{
|
||||||
|
Type = PSXUIElementType.Image,
|
||||||
|
StartVisible = img.StartVisible,
|
||||||
|
Name = TruncateName(img.ElementName),
|
||||||
|
X = x, Y = y, W = w, H = h,
|
||||||
|
AnchorMinX = amin_x, AnchorMinY = amin_y,
|
||||||
|
AnchorMaxX = amax_x, AnchorMaxY = amax_y,
|
||||||
|
ColorR = (byte)Mathf.Clamp(Mathf.RoundToInt(img.TintColor.r * 255f), 0, 255),
|
||||||
|
ColorG = (byte)Mathf.Clamp(Mathf.RoundToInt(img.TintColor.g * 255f), 0, 255),
|
||||||
|
ColorB = (byte)Mathf.Clamp(Mathf.RoundToInt(img.TintColor.b * 255f), 0, 255),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (img.PackedTexture != null)
|
||||||
|
{
|
||||||
|
PSXTexture2D tex = img.PackedTexture;
|
||||||
|
int expander = 16 / (int)tex.BitDepth;
|
||||||
|
data.TexpageX = tex.TexpageX;
|
||||||
|
data.TexpageY = tex.TexpageY;
|
||||||
|
data.ClutX = (ushort)tex.ClutPackingX;
|
||||||
|
data.ClutY = (ushort)tex.ClutPackingY;
|
||||||
|
data.U0 = (byte)(tex.PackingX * expander);
|
||||||
|
data.V0 = (byte)tex.PackingY;
|
||||||
|
data.U1 = (byte)(tex.PackingX * expander + tex.Width - 1);
|
||||||
|
data.V1 = (byte)(tex.PackingY + tex.Height - 1);
|
||||||
|
data.BitDepthIndex = tex.BitDepth switch
|
||||||
|
{
|
||||||
|
PSXBPP.TEX_4BIT => 0,
|
||||||
|
PSXBPP.TEX_8BIT => 1,
|
||||||
|
PSXBPP.TEX_16BIT => 2,
|
||||||
|
_ => 2
|
||||||
|
};
|
||||||
|
|
||||||
|
Debug.Log($"[UIImage] '{img.ElementName}' src='{(tex.OriginalTexture ? tex.OriginalTexture.name : "null")}' " +
|
||||||
|
$"bpp={(int)tex.BitDepth} W={tex.Width} H={tex.Height} QW={tex.QuantizedWidth} " +
|
||||||
|
$"packXY=({tex.PackingX},{tex.PackingY}) tpage=({tex.TexpageX},{tex.TexpageY}) " +
|
||||||
|
$"clutXY=({tex.ClutPackingX},{tex.ClutPackingY}) " +
|
||||||
|
$"UV=({data.U0},{data.V0})->({data.U1},{data.V1}) expander={expander} bitIdx={data.BitDepthIndex}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[UIImage] '{img.ElementName}' has NULL PackedTexture!");
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.Add(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CollectSingleBox(
|
||||||
|
PSXUIBox box, RectTransform canvasRect,
|
||||||
|
float scaleX, float scaleY, Vector2 resolution,
|
||||||
|
List<PSXUIElementData> elements)
|
||||||
|
{
|
||||||
|
RectTransform rt = box.GetComponent<RectTransform>();
|
||||||
|
if (rt == null) return;
|
||||||
|
|
||||||
|
BakeLayout(rt, canvasRect, scaleX, scaleY, resolution,
|
||||||
|
out short x, out short y, out short w, out short h,
|
||||||
|
out byte amin_x, out byte amin_y, out byte amax_x, out byte amax_y);
|
||||||
|
|
||||||
|
elements.Add(new PSXUIElementData
|
||||||
|
{
|
||||||
|
Type = PSXUIElementType.Box,
|
||||||
|
StartVisible = box.StartVisible,
|
||||||
|
Name = TruncateName(box.ElementName),
|
||||||
|
X = x, Y = y, W = w, H = h,
|
||||||
|
AnchorMinX = amin_x, AnchorMinY = amin_y,
|
||||||
|
AnchorMaxX = amax_x, AnchorMaxY = amax_y,
|
||||||
|
ColorR = (byte)Mathf.Clamp(Mathf.RoundToInt(box.BoxColor.r * 255f), 0, 255),
|
||||||
|
ColorG = (byte)Mathf.Clamp(Mathf.RoundToInt(box.BoxColor.g * 255f), 0, 255),
|
||||||
|
ColorB = (byte)Mathf.Clamp(Mathf.RoundToInt(box.BoxColor.b * 255f), 0, 255),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CollectSingleText(
|
||||||
|
PSXUIText txt, RectTransform canvasRect,
|
||||||
|
float scaleX, float scaleY, Vector2 resolution,
|
||||||
|
List<PSXUIElementData> elements,
|
||||||
|
List<PSXFontAsset> uniqueFonts)
|
||||||
|
{
|
||||||
|
RectTransform rt = txt.GetComponent<RectTransform>();
|
||||||
|
if (rt == null) return;
|
||||||
|
|
||||||
|
BakeLayout(rt, canvasRect, scaleX, scaleY, resolution,
|
||||||
|
out short x, out short y, out short w, out short h,
|
||||||
|
out byte amin_x, out byte amin_y, out byte amax_x, out byte amax_y);
|
||||||
|
|
||||||
|
string defaultText = txt.DefaultText ?? "";
|
||||||
|
if (defaultText.Length > 63) defaultText = defaultText.Substring(0, 63);
|
||||||
|
|
||||||
|
byte fontIndex = 0;
|
||||||
|
PSXFontAsset effectiveFont = txt.GetEffectiveFont();
|
||||||
|
if (effectiveFont != null && uniqueFonts != null)
|
||||||
|
{
|
||||||
|
int idx = uniqueFonts.IndexOf(effectiveFont);
|
||||||
|
if (idx >= 0) fontIndex = (byte)(idx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.Add(new PSXUIElementData
|
||||||
|
{
|
||||||
|
Type = PSXUIElementType.Text,
|
||||||
|
StartVisible = txt.StartVisible,
|
||||||
|
Name = TruncateName(txt.ElementName),
|
||||||
|
X = x, Y = y, W = w, H = h,
|
||||||
|
AnchorMinX = amin_x, AnchorMinY = amin_y,
|
||||||
|
AnchorMaxX = amax_x, AnchorMaxY = amax_y,
|
||||||
|
ColorR = (byte)Mathf.Clamp(Mathf.RoundToInt(txt.TextColor.r * 255f), 0, 255),
|
||||||
|
ColorG = (byte)Mathf.Clamp(Mathf.RoundToInt(txt.TextColor.g * 255f), 0, 255),
|
||||||
|
ColorB = (byte)Mathf.Clamp(Mathf.RoundToInt(txt.TextColor.b * 255f), 0, 255),
|
||||||
|
DefaultText = defaultText,
|
||||||
|
FontIndex = fontIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CollectSingleProgressBar(
|
||||||
|
PSXUIProgressBar bar, RectTransform canvasRect,
|
||||||
|
float scaleX, float scaleY, Vector2 resolution,
|
||||||
|
List<PSXUIElementData> elements)
|
||||||
|
{
|
||||||
|
RectTransform rt = bar.GetComponent<RectTransform>();
|
||||||
|
if (rt == null) return;
|
||||||
|
|
||||||
|
BakeLayout(rt, canvasRect, scaleX, scaleY, resolution,
|
||||||
|
out short x, out short y, out short w, out short h,
|
||||||
|
out byte amin_x, out byte amin_y, out byte amax_x, out byte amax_y);
|
||||||
|
|
||||||
|
elements.Add(new PSXUIElementData
|
||||||
|
{
|
||||||
|
Type = PSXUIElementType.Progress,
|
||||||
|
StartVisible = bar.StartVisible,
|
||||||
|
Name = TruncateName(bar.ElementName),
|
||||||
|
X = x, Y = y, W = w, H = h,
|
||||||
|
AnchorMinX = amin_x, AnchorMinY = amin_y,
|
||||||
|
AnchorMaxX = amax_x, AnchorMaxY = amax_y,
|
||||||
|
ColorR = (byte)Mathf.Clamp(Mathf.RoundToInt(bar.FillColor.r * 255f), 0, 255),
|
||||||
|
ColorG = (byte)Mathf.Clamp(Mathf.RoundToInt(bar.FillColor.g * 255f), 0, 255),
|
||||||
|
ColorB = (byte)Mathf.Clamp(Mathf.RoundToInt(bar.FillColor.b * 255f), 0, 255),
|
||||||
|
BgR = (byte)Mathf.Clamp(Mathf.RoundToInt(bar.BackgroundColor.r * 255f), 0, 255),
|
||||||
|
BgG = (byte)Mathf.Clamp(Mathf.RoundToInt(bar.BackgroundColor.g * 255f), 0, 255),
|
||||||
|
BgB = (byte)Mathf.Clamp(Mathf.RoundToInt(bar.BackgroundColor.b * 255f), 0, 255),
|
||||||
|
ProgressValue = (byte)bar.InitialValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Legacy per-type collectors (kept for reference, no longer called) ───
|
||||||
|
|
||||||
private static void CollectImages(
|
private static void CollectImages(
|
||||||
Transform root, RectTransform canvasRect,
|
Transform root, RectTransform canvasRect,
|
||||||
float scaleX, float scaleY, Vector2 resolution,
|
float scaleX, float scaleY, Vector2 resolution,
|
||||||
|
|||||||
Reference in New Issue
Block a user