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}' " +
|
||||
$"canvasW={canvasW} canvasH={canvasH} childCount={canvas.transform.childCount}");
|
||||
|
||||
// Log what each collector finds
|
||||
int prevCount = elements.Count;
|
||||
CollectImages(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements);
|
||||
Debug.Log($"[UIExporter] Images: {elements.Count - prevCount}");
|
||||
prevCount = elements.Count;
|
||||
CollectBoxes(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements);
|
||||
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}");
|
||||
// Collect all UI elements in hierarchy order (depth-first, sibling index).
|
||||
// GetComponentsInChildren returns top-of-hierarchy first, but the C++
|
||||
// renderer draws index 0 first (back). Reverse so that top-of-hierarchy
|
||||
// elements are rendered last (on top), matching Unity's visual stacking.
|
||||
CollectAllElementsInHierarchyOrder(canvas.transform, canvasRect, scaleX, scaleY, resolution, elements, uniqueFonts);
|
||||
elements.Reverse();
|
||||
Debug.Log($"[UIExporter] TOTAL elements: {elements.Count}");
|
||||
|
||||
string name = canvas.CanvasName ?? "canvas";
|
||||
@@ -258,6 +251,214 @@ namespace SplashEdit.RuntimeCode
|
||||
|
||||
// ─── 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(
|
||||
Transform root, RectTransform canvasRect,
|
||||
float scaleX, float scaleY, Vector2 resolution,
|
||||
|
||||
Reference in New Issue
Block a user