fix: game over UI panels never showing + polish panel visuals

- CampaignManager: FindObjectOfType<T>(true) to find inactive panels
- CampaignManager: ActivateHierarchy() walks full ancestor chain before Show()
- All UI panels: defensive gameObject.SetActive(true) fallback when _panel is null
- Editor tools: polished panel visuals (overlay, borders, dividers, outline titles)
- Editor tools: same polish applied to SetupChapterScenes + CreateChapterScenes
This commit is contained in:
2026-08-20 02:20:48 -03:00
parent 389f5272b5
commit 1c905e2689
9 changed files with 1007 additions and 88 deletions
+109 -29
View File
@@ -169,16 +169,22 @@ public static class CreateChapterScenes
cv.AddComponent<GraphicRaycaster>();
}
// Create the panel
var panel = CreatePanel("DeadKingInputPanel", cv.transform, new Vector2(700, 500), new Color(.05f, .02f, .08f, .97f));
var titleTMP = CreateTMP("TitleText", panel.transform, "INSCRIBE TU NOMBRE", 36f);
titleTMP.color = new Color(.9f, .1f, .1f);
var overlay = MakeOverlay(cv.transform);
var panel = CreatePanel("DeadKingInputPanel", cv.transform, new Vector2(800, 560), new Color(.05f, .015f, .06f, .98f));
AddBorder(panel.transform, new Color(.55f, .45f, .7f, .9f));
var titleTMP = CreateTMP("TitleText", panel.transform, "INSCRIBE TU NOMBRE", 44f);
titleTMP.color = new Color(.85f, .7f, 1f);
titleTMP.fontStyle = FontStyles.Bold;
titleTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(titleTMP.rectTransform, .05f, .84f, .95f, .97f);
titleTMP.outlineWidth = .1f;
titleTMP.outlineColor = new Color(.2f, .12f, .3f, .5f);
AnchorNorm(titleTMP.rectTransform, .08f, .86f, .92f, .97f);
var nameLabel = CreateTMP("NameLabel", panel.transform, "Tu nombre:", 18f);
nameLabel.color = new Color(.8f, .8f, .8f);
MakeDivider(panel.transform, .82f, new Color(.55f, .45f, .7f, .7f));
var nameLabel = CreateTMP("NameLabel", panel.transform, "Tu nombre:", 20f);
nameLabel.color = new Color(.82f, .82f, .82f);
AnchorNorm(nameLabel.rectTransform, .08f, .72f, .92f, .80f);
// Name input field placeholder
@@ -187,12 +193,12 @@ public static class CreateChapterScenes
var nameInputRT = nameInputGO.AddComponent<RectTransform>();
AnchorNorm(nameInputRT, .08f, .62f, .92f, .72f);
var nameInputImg = nameInputGO.AddComponent<Image>();
nameInputImg.color = new Color(.15f, .1f, .15f);
nameInputImg.color = new Color(.1f, .06f, .14f);
var nameInput = nameInputGO.AddComponent<TMP_InputField>();
nameInput.characterLimit = 20;
var msgLabel = CreateTMP("MessageLabel", panel.transform, "Tu mensaje:", 18f);
msgLabel.color = new Color(.8f, .8f, .8f);
var msgLabel = CreateTMP("MessageLabel", panel.transform, "Tu mensaje:", 20f);
msgLabel.color = new Color(.82f, .82f, .82f);
AnchorNorm(msgLabel.rectTransform, .08f, .48f, .92f, .56f);
// Message input field placeholder
@@ -201,24 +207,29 @@ public static class CreateChapterScenes
var msgInputRT = msgInputGO.AddComponent<RectTransform>();
AnchorNorm(msgInputRT, .08f, .28f, .92f, .48f);
var msgInputImg = msgInputGO.AddComponent<Image>();
msgInputImg.color = new Color(.15f, .1f, .15f);
msgInputImg.color = new Color(.1f, .06f, .14f);
var msgInput = msgInputGO.AddComponent<TMP_InputField>();
msgInput.characterLimit = 100;
// Submit button
var submitGO = CreateButton("SubmitButton", panel.transform, "INSCRIBIR");
submitGO.GetComponent<Image>().color = new Color(.35f, .08f, .08f);
AnchorNorm(submitGO.GetComponent<RectTransform>(), .25f, .06f, .75f, .18f);
submitGO.GetComponent<Image>().color = new Color(.4f, .1f, .1f);
var sb = submitGO.GetComponent<Button>().colors;
sb.highlightedColor = new Color(.55f, .18f, .18f);
sb.pressedColor = new Color(.28f, .06f, .06f);
submitGO.GetComponent<Button>().colors = sb;
AnchorNorm(submitGO.GetComponent<RectTransform>(), .25f, .05f, .75f, .18f);
// Feedback text
var feedbackTMP = CreateTMP("FeedbackText", panel.transform, "", 20f);
feedbackTMP.color = new Color(.3f, .9f, .3f);
var feedbackTMP = CreateTMP("FeedbackText", panel.transform, "", 22f);
feedbackTMP.color = new Color(.35f, .9f, .35f);
feedbackTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(feedbackTMP.rectTransform, .08f, .20f, .92f, .28f);
panel.SetActive(false);
// Add the component
var cg = panel.AddComponent<CanvasGroup>();
var deadKingUI = panel.AddComponent<AjedrezPurgatorio.UI.DeadKingInputUI>();
var so = new SerializedObject(deadKingUI);
SetProp(so, "_panel", panel);
@@ -226,8 +237,10 @@ public static class CreateChapterScenes
SetProp(so, "_messageInputField", msgInput);
SetProp(so, "_submitButton", submitGO.GetComponent<Button>());
SetProp(so, "_feedbackText", feedbackTMP);
SetProp(so, "_canvasGroup", cg);
so.ApplyModifiedPropertiesWithoutUndo();
overlay.SetActive(false);
Debug.Log(" ✅ DeadKingInputUI creado.");
}
@@ -248,36 +261,48 @@ public static class CreateChapterScenes
cv.AddComponent<GraphicRaycaster>();
}
var panel = CreatePanel("DeadKingRevealPanel", cv.transform, new Vector2(700, 500), new Color(.08f, .02f, .02f, .97f));
var titleTMP = CreateTMP("RevealTitle", panel.transform, "UN CAÍDTO REGRESA", 36f);
titleTMP.color = new Color(.9f, .1f, .1f);
var overlay = MakeOverlay(cv.transform);
var panel = CreatePanel("DeadKingRevealPanel", cv.transform, new Vector2(800, 540), new Color(.06f, .015f, .015f, .98f));
AddBorder(panel.transform, new Color(.7f, .15f, .15f, .9f));
var titleTMP = CreateTMP("RevealTitle", panel.transform, "UN CAIDO REGRESA", 44f);
titleTMP.color = new Color(.9f, .2f, .2f);
titleTMP.fontStyle = FontStyles.Bold;
titleTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(titleTMP.rectTransform, .05f, .84f, .95f, .97f);
titleTMP.outlineWidth = .12f;
titleTMP.outlineColor = new Color(.35f, .05f, .05f, .6f);
AnchorNorm(titleTMP.rectTransform, .08f, .86f, .92f, .97f);
var nameTMP = CreateTMP("DeadKingName", panel.transform, "Nombre del Rey Caído", 28f);
MakeDivider(panel.transform, .82f, new Color(.7f, .15f, .15f, .7f));
var nameTMP = CreateTMP("DeadKingName", panel.transform, "Nombre del Rey Caido", 32f);
nameTMP.color = new Color(1f, .85f, .2f);
nameTMP.fontStyle = FontStyles.Bold;
nameTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(nameTMP.rectTransform, .05f, .68f, .95f, .82f);
AnchorNorm(nameTMP.rectTransform, .08f, .70f, .92f, .82f);
var quoteTMP = CreateTMP("DeadKingQuote", panel.transform, "\"...\"", 22f);
quoteTMP.color = new Color(.7f, .7f, .85f);
var quoteTMP = CreateTMP("DeadKingQuote", panel.transform, "\"...\"", 24f);
quoteTMP.color = new Color(.75f, .75f, .9f);
quoteTMP.fontStyle = FontStyles.Italic;
quoteTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(quoteTMP.rectTransform, .08f, .48f, .92f, .66f);
AnchorNorm(quoteTMP.rectTransform, .10f, .46f, .90f, .68f);
var statsTMP = CreateTMP("DeadKingStats", panel.transform, "Capítulo alcanzado: ?\nPiezas perdidas: ?", 18f);
statsTMP.color = new Color(.75f, .75f, .75f);
var statsTMP = CreateTMP("DeadKingStats", panel.transform, "Capítulo alcanzado: ?\nPiezas perdidas: ?", 20f);
statsTMP.color = new Color(.78f, .78f, .78f);
statsTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(statsTMP.rectTransform, .05f, .30f, .95f, .46f);
statsTMP.lineSpacing = 6f;
AnchorNorm(statsTMP.rectTransform, .08f, .26f, .92f, .44f);
var continueGO = CreateButton("ContinueButton", panel.transform, "CONTINUAR");
continueGO.GetComponent<Image>().color = new Color(.18f, .36f, .18f);
AnchorNorm(continueGO.GetComponent<RectTransform>(), .3f, .06f, .7f, .18f);
continueGO.GetComponent<Image>().color = new Color(.22f, .38f, .15f);
var cb = continueGO.GetComponent<Button>().colors;
cb.highlightedColor = new Color(.32f, .52f, .22f);
cb.pressedColor = new Color(.14f, .26f, .10f);
continueGO.GetComponent<Button>().colors = cb;
AnchorNorm(continueGO.GetComponent<RectTransform>(), .28f, .05f, .72f, .18f);
panel.SetActive(false);
var cg = panel.AddComponent<CanvasGroup>();
var revealUI = panel.AddComponent<DeadKingRevealUI>();
var so = new SerializedObject(revealUI);
SetProp(so, "_panel", panel);
@@ -285,8 +310,10 @@ public static class CreateChapterScenes
SetProp(so, "_messageText", quoteTMP);
SetProp(so, "_statsText", statsTMP);
SetProp(so, "_continueButton", continueGO.GetComponent<Button>());
SetProp(so, "_canvasGroup", cg);
so.ApplyModifiedPropertiesWithoutUndo();
overlay.SetActive(false);
Debug.Log(" ✅ DeadKingRevealUI creado.");
}
@@ -379,6 +406,59 @@ public static class CreateChapterScenes
rt.offsetMin = rt.offsetMax = Vector2.zero;
}
static void Stretch(RectTransform rt)
{
rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one;
rt.offsetMin = rt.offsetMax = Vector2.zero;
}
static GameObject MakeOverlay(Transform parent)
{
var go = new GameObject("Overlay");
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = new Color(0f, 0f, 0f, 0.55f);
Stretch(go.GetComponent<RectTransform>());
return go;
}
static void AddBorder(Transform panel, Color borderColor)
{
float thickness = 3f;
Vector2 sz = panel.GetComponent<RectTransform>().sizeDelta;
MakeBorderEdge("BorderTop", panel, new Vector2(sz.x + thickness*2, thickness), new Vector2(0, sz.y/2f - thickness/2f), borderColor);
MakeBorderEdge("BorderBottom", panel, new Vector2(sz.x + thickness*2, thickness), new Vector2(0, -sz.y/2f + thickness/2f), borderColor);
MakeBorderEdge("BorderLeft", panel, new Vector2(thickness, sz.y + thickness*2), new Vector2(-sz.x/2f + thickness/2f, 0), borderColor);
MakeBorderEdge("BorderRight", panel, new Vector2(thickness, sz.y + thickness*2), new Vector2(sz.x/2f - thickness/2f, 0), borderColor);
}
static void MakeBorderEdge(string name, Transform parent, Vector2 size, Vector2 pos, Color color)
{
var go = new GameObject(name);
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = color;
img.raycastTarget = false;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = rt.pivot = new Vector2(.5f, .5f);
rt.sizeDelta = size;
rt.anchoredPosition = pos;
}
static void MakeDivider(Transform parent, float yNorm, Color color)
{
var go = new GameObject("Divider");
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = color;
img.raycastTarget = false;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(.12f, yNorm);
rt.anchorMax = new Vector2(.88f, yNorm);
rt.sizeDelta = new Vector2(0, 2f);
rt.anchoredPosition = Vector2.zero;
}
static void SetProp(SerializedObject so, string field, Object val)
{
var p = so.FindProperty(field);
+106 -30
View File
@@ -568,37 +568,49 @@ public static class SetupChapterScenes
static void CreateDeadKingRevealUI()
{
var canvas = FindOrCreateCanvas("PurgatoryCanvas", 120);
var panel = CreatePanel("DeadKingRevealPanel", canvas.transform, new Vector2(700, 500), new Color(0.08f, 0.02f, 0.02f, 0.97f));
var overlay = MakeOverlay(canvas.transform);
var panel = CreatePanel("DeadKingRevealPanel", canvas.transform, new Vector2(800, 540), new Color(0.06f, 0.015f, 0.015f, 0.98f));
AddBorder(panel.transform, new Color(0.7f, 0.15f, 0.15f, 0.9f));
var titleTMP = CreateTMPChild("RevealTitle", panel.transform, "UN CAIDO REGRESA", 36f);
titleTMP.color = new Color(0.9f, 0.1f, 0.1f);
var titleTMP = CreateTMPChild("RevealTitle", panel.transform, "UN CAIDO REGRESA", 44f);
titleTMP.color = new Color(0.9f, 0.2f, 0.2f);
titleTMP.fontStyle = FontStyles.Bold;
titleTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(titleTMP.rectTransform, 0.05f, 0.84f, 0.95f, 0.97f);
titleTMP.outlineWidth = 0.12f;
titleTMP.outlineColor = new Color(0.35f, 0.05f, 0.05f, 0.6f);
AnchorNorm(titleTMP.rectTransform, 0.08f, 0.86f, 0.92f, 0.97f);
var nameTMP = CreateTMPChild("DeadKingName", panel.transform, "Nombre del Rey Caido", 28f);
MakeDivider(panel.transform, 0.82f, new Color(0.7f, 0.15f, 0.15f, 0.7f));
var nameTMP = CreateTMPChild("DeadKingName", panel.transform, "Nombre del Rey Caido", 32f);
nameTMP.color = new Color(1f, 0.85f, 0.2f);
nameTMP.fontStyle = FontStyles.Bold;
nameTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(nameTMP.rectTransform, 0.05f, 0.68f, 0.95f, 0.82f);
AnchorNorm(nameTMP.rectTransform, 0.08f, 0.70f, 0.92f, 0.82f);
var quoteTMP = CreateTMPChild("DeadKingQuote", panel.transform, "\"...\"", 22f);
quoteTMP.color = new Color(0.7f, 0.7f, 0.85f);
var quoteTMP = CreateTMPChild("DeadKingQuote", panel.transform, "\"...\"", 24f);
quoteTMP.color = new Color(0.75f, 0.75f, 0.9f);
quoteTMP.fontStyle = FontStyles.Italic;
quoteTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(quoteTMP.rectTransform, 0.08f, 0.48f, 0.92f, 0.66f);
AnchorNorm(quoteTMP.rectTransform, 0.10f, 0.46f, 0.90f, 0.68f);
var statsTMP = CreateTMPChild("DeadKingStats", panel.transform, "Capitulo alcanzado: ?\nPiezas perdidas: ?", 18f);
statsTMP.color = new Color(0.75f, 0.75f, 0.75f);
var statsTMP = CreateTMPChild("DeadKingStats", panel.transform, "Capitulo alcanzado: ?\nPiezas perdidas: ?", 20f);
statsTMP.color = new Color(0.78f, 0.78f, 0.78f);
statsTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(statsTMP.rectTransform, 0.05f, 0.30f, 0.95f, 0.46f);
statsTMP.lineSpacing = 6f;
AnchorNorm(statsTMP.rectTransform, 0.08f, 0.26f, 0.92f, 0.44f);
var continueGO = CreateButton("ContinueButton", panel.transform, "CONTINUAR");
continueGO.GetComponent<Image>().color = new Color(0.18f, 0.36f, 0.18f);
AnchorNorm(continueGO.GetComponent<RectTransform>(), 0.3f, 0.06f, 0.7f, 0.18f);
continueGO.GetComponent<Image>().color = new Color(0.22f, 0.38f, 0.15f);
var cb = continueGO.GetComponent<Button>().colors;
cb.highlightedColor = new Color(0.32f, 0.52f, 0.22f);
cb.pressedColor = new Color(0.14f, 0.26f, 0.10f);
continueGO.GetComponent<Button>().colors = cb;
AnchorNorm(continueGO.GetComponent<RectTransform>(), 0.28f, 0.05f, 0.72f, 0.18f);
panel.SetActive(false);
var cg = panel.AddComponent<CanvasGroup>();
var comp = panel.AddComponent<DeadKingRevealUI>();
var so = new SerializedObject(comp);
SetObjProp(so, "_panel", panel);
@@ -606,24 +618,32 @@ public static class SetupChapterScenes
SetObjProp(so, "_messageText", quoteTMP);
SetObjProp(so, "_statsText", statsTMP);
SetObjProp(so, "_continueButton", continueGO.GetComponent<Button>());
SetObjProp(so, "_canvasGroup", cg);
so.ApplyModifiedPropertiesWithoutUndo();
overlay.SetActive(false);
Debug.Log(" ✅ Created DeadKingRevealUI");
}
static void CreateDeadKingInputUI()
{
var canvas = FindOrCreateCanvas("PurgatoryCanvas", 120);
var panel = CreatePanel("DeadKingInputPanel", canvas.transform, new Vector2(700, 500), new Color(0.05f, 0.02f, 0.08f, 0.97f));
var overlay = MakeOverlay(canvas.transform);
var panel = CreatePanel("DeadKingInputPanel", canvas.transform, new Vector2(800, 560), new Color(0.05f, 0.015f, 0.06f, 0.98f));
AddBorder(panel.transform, new Color(0.55f, 0.45f, 0.7f, 0.9f));
var titleTMP = CreateTMPChild("TitleText", panel.transform, "INSCRIBE TU NOMBRE", 36f);
titleTMP.color = new Color(0.9f, 0.1f, 0.1f);
var titleTMP = CreateTMPChild("TitleText", panel.transform, "INSCRIBE TU NOMBRE", 44f);
titleTMP.color = new Color(0.85f, 0.7f, 1f);
titleTMP.fontStyle = FontStyles.Bold;
titleTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(titleTMP.rectTransform, 0.05f, 0.84f, 0.95f, 0.97f);
titleTMP.outlineWidth = 0.1f;
titleTMP.outlineColor = new Color(0.2f, 0.12f, 0.3f, 0.5f);
AnchorNorm(titleTMP.rectTransform, 0.08f, 0.86f, 0.92f, 0.97f);
var nameLabel = CreateTMPChild("NameLabel", panel.transform, "Tu nombre:", 18f);
nameLabel.color = new Color(0.8f, 0.8f, 0.8f);
MakeDivider(panel.transform, 0.82f, new Color(0.55f, 0.45f, 0.7f, 0.7f));
var nameLabel = CreateTMPChild("NameLabel", panel.transform, "Tu nombre:", 20f);
nameLabel.color = new Color(0.82f, 0.82f, 0.82f);
AnchorNorm(nameLabel.rectTransform, 0.08f, 0.72f, 0.92f, 0.80f);
var nameInputGO = new GameObject("NameInputField");
@@ -631,12 +651,12 @@ public static class SetupChapterScenes
var nameInputRT = nameInputGO.AddComponent<RectTransform>();
AnchorNorm(nameInputRT, 0.08f, 0.62f, 0.92f, 0.72f);
var nameInputImg = nameInputGO.AddComponent<Image>();
nameInputImg.color = new Color(0.15f, 0.1f, 0.15f);
nameInputImg.color = new Color(0.1f, 0.06f, 0.14f);
var nameInput = nameInputGO.AddComponent<TMP_InputField>();
nameInput.characterLimit = 20;
var msgLabel = CreateTMPChild("MessageLabel", panel.transform, "Tu mensaje:", 18f);
msgLabel.color = new Color(0.8f, 0.8f, 0.8f);
var msgLabel = CreateTMPChild("MessageLabel", panel.transform, "Tu mensaje:", 20f);
msgLabel.color = new Color(0.82f, 0.82f, 0.82f);
AnchorNorm(msgLabel.rectTransform, 0.08f, 0.48f, 0.92f, 0.56f);
var msgInputGO = new GameObject("MessageInputField");
@@ -644,21 +664,26 @@ public static class SetupChapterScenes
var msgInputRT = msgInputGO.AddComponent<RectTransform>();
AnchorNorm(msgInputRT, 0.08f, 0.28f, 0.92f, 0.48f);
var msgInputImg = msgInputGO.AddComponent<Image>();
msgInputImg.color = new Color(0.15f, 0.1f, 0.15f);
msgInputImg.color = new Color(0.1f, 0.06f, 0.14f);
var msgInput = msgInputGO.AddComponent<TMP_InputField>();
msgInput.characterLimit = 100;
var submitGO = CreateButton("SubmitButton", panel.transform, "INSCRIBIR");
submitGO.GetComponent<Image>().color = new Color(0.35f, 0.08f, 0.08f);
AnchorNorm(submitGO.GetComponent<RectTransform>(), 0.25f, 0.06f, 0.75f, 0.18f);
var feedbackTMP = CreateTMPChild("FeedbackText", panel.transform, "", 20f);
feedbackTMP.color = new Color(0.3f, 0.9f, 0.3f);
var feedbackTMP = CreateTMPChild("FeedbackText", panel.transform, "", 22f);
feedbackTMP.color = new Color(0.35f, 0.9f, 0.35f);
feedbackTMP.alignment = TextAlignmentOptions.Center;
AnchorNorm(feedbackTMP.rectTransform, 0.08f, 0.20f, 0.92f, 0.28f);
var submitGO = CreateButton("SubmitButton", panel.transform, "INSCRIBIR");
submitGO.GetComponent<Image>().color = new Color(0.4f, 0.1f, 0.1f);
var sb = submitGO.GetComponent<Button>().colors;
sb.highlightedColor = new Color(0.55f, 0.18f, 0.18f);
sb.pressedColor = new Color(0.28f, 0.06f, 0.06f);
submitGO.GetComponent<Button>().colors = sb;
AnchorNorm(submitGO.GetComponent<RectTransform>(), 0.25f, 0.05f, 0.75f, 0.18f);
panel.SetActive(false);
var cg = panel.AddComponent<CanvasGroup>();
var comp = panel.AddComponent<DeadKingInputUI>();
var so = new SerializedObject(comp);
SetObjProp(so, "_panel", panel);
@@ -666,8 +691,10 @@ public static class SetupChapterScenes
SetObjProp(so, "_messageInputField", msgInput);
SetObjProp(so, "_submitButton", submitGO.GetComponent<Button>());
SetObjProp(so, "_feedbackText", feedbackTMP);
SetObjProp(so, "_canvasGroup", cg);
so.ApplyModifiedPropertiesWithoutUndo();
overlay.SetActive(false);
Debug.Log(" ✅ Created DeadKingInputUI");
}
@@ -791,6 +818,55 @@ public static class SetupChapterScenes
rt.offsetMin = rt.offsetMax = Vector2.zero;
}
static GameObject MakeOverlay(Transform parent)
{
var go = new GameObject("Overlay");
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = new Color(0f, 0f, 0f, 0.55f);
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one;
rt.offsetMin = rt.offsetMax = Vector2.zero;
return go;
}
static void AddBorder(Transform panel, Color borderColor)
{
float thickness = 3f;
Vector2 sz = panel.GetComponent<RectTransform>().sizeDelta;
MakeBorderEdge("BorderTop", panel, new Vector2(sz.x + thickness*2, thickness), new Vector2(0, sz.y/2f - thickness/2f), borderColor);
MakeBorderEdge("BorderBottom", panel, new Vector2(sz.x + thickness*2, thickness), new Vector2(0, -sz.y/2f + thickness/2f), borderColor);
MakeBorderEdge("BorderLeft", panel, new Vector2(thickness, sz.y + thickness*2), new Vector2(-sz.x/2f + thickness/2f, 0), borderColor);
MakeBorderEdge("BorderRight", panel, new Vector2(thickness, sz.y + thickness*2), new Vector2(sz.x/2f - thickness/2f, 0), borderColor);
}
static void MakeBorderEdge(string name, Transform parent, Vector2 size, Vector2 pos, Color color)
{
var go = new GameObject(name);
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = color;
img.raycastTarget = false;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = rt.pivot = new Vector2(.5f, .5f);
rt.sizeDelta = size;
rt.anchoredPosition = pos;
}
static void MakeDivider(Transform parent, float yNorm, Color color)
{
var go = new GameObject("Divider");
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = color;
img.raycastTarget = false;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(.12f, yNorm);
rt.anchorMax = new Vector2(.88f, yNorm);
rt.sizeDelta = new Vector2(0, 2f);
rt.anchoredPosition = Vector2.zero;
}
static void SetObjProp(SerializedObject so, string field, Object val)
{
var p = so.FindProperty(field);
@@ -30,6 +30,7 @@ public class PurgatorySetupValidator : EditorWindow
SetupPurgatorySystem();
SetupManagers();
SetupGameUI();
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene);
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene);
@@ -189,6 +190,158 @@ public class PurgatorySetupValidator : EditorWindow
}
}
static void SetupGameUI()
{
var cv = GameObject.Find("PurgatoryCanvas");
Canvas canvas = cv != null ? cv.GetComponent<Canvas>() : null;
if (canvas == null)
{
canvas = MakeCanvas("PurgatoryCanvas", 120);
cv = canvas.gameObject;
}
var canvasTransform = cv.transform;
// — Victory Panel —
if (Object.FindFirstObjectByType<AjedrezPurgatorio.UI.VictoryUI>() == null)
{
var vOverlay = MakeOverlay(canvasTransform);
var vP = MakePanel("VictoryPanel", canvasTransform, new Vector2(800, 520), new Color(.04f,.05f,.02f,.98f));
AddBorder(vP.transform, new Color(.65f,.55f,.1f,.9f));
var vTitle = MakeTMP("TitleText", vP.transform, "VICTORIA", 60f);
AnchorNorm(vTitle.rectTransform, .08f,.84f,.92f,.96f);
vTitle.color = new Color(1f,.88f,.25f); vTitle.fontStyle = FontStyles.Bold; vTitle.alignment = TextAlignmentOptions.Center;
vTitle.outlineWidth = .12f; vTitle.outlineColor = new Color(.3f,.25f,0f,.6f);
MakeDivider(vP.transform, .79f, new Color(.65f,.55f,.1f,.7f));
var vChName = MakeTMP("ChapterNameText", vP.transform, "Capítulo", 30f);
AnchorNorm(vChName.rectTransform, .08f,.70f,.92f,.82f);
vChName.color = Color.white; vChName.alignment = TextAlignmentOptions.Center; vChName.fontStyle = FontStyles.Bold;
var vLost = MakeTMP("PiecesLostText", vP.transform, "Piezas perdidas: 0", 22f);
AnchorNorm(vLost.rectTransform, .08f,.56f,.92f,.68f);
vLost.color = new Color(.9f,.7f,.7f); vLost.alignment = TextAlignmentOptions.Center;
var vStats = MakeTMP("StatsText", vP.transform, "", 20f);
AnchorNorm(vStats.rectTransform, .08f,.28f,.92f,.54f);
vStats.color = new Color(.78f,.78f,.78f); vStats.alignment = TextAlignmentOptions.Center; vStats.lineSpacing = 6f;
var vCont = MakeButton("ContinueButton", vP.transform, "CONTINUAR");
AnchorNorm(vCont.GetComponent<RectTransform>(), .28f,.04f,.72f,.18f);
vCont.GetComponent<Image>().color = new Color(.22f,.38f,.15f);
ColorBlock vcb = vCont.GetComponent<Button>().colors;
vcb.highlightedColor = new Color(.32f,.52f,.22f); vcb.pressedColor = new Color(.14f,.26f,.10f);
vCont.GetComponent<Button>().colors = vcb;
var vCg = vP.AddComponent<CanvasGroup>();
var vUI = vP.AddComponent<AjedrezPurgatorio.UI.VictoryUI>();
var vSO = new SerializedObject(vUI);
Ref(vSO, "_panel", vP); Ref(vSO, "_titleText", vTitle); Ref(vSO, "_chapterNameText", vChName);
Ref(vSO, "_piecesLostText", vLost); Ref(vSO, "_statsText", vStats);
Ref(vSO, "_continueButton", vCont.GetComponent<Button>()); Ref(vSO, "_canvasGroup", vCg);
vSO.ApplyModifiedPropertiesWithoutUndo();
vOverlay.SetActive(false); vP.SetActive(false);
Debug.Log(" ✅ VictoryPanel creado.");
}
// — Defeat Panel —
if (Object.FindFirstObjectByType<AjedrezPurgatorio.UI.DefeatUI>() == null)
{
var dOverlay = MakeOverlay(canvasTransform);
var dP = MakePanel("DefeatPanel", canvasTransform, new Vector2(800, 520), new Color(.08f,.02f,.02f,.98f));
AddBorder(dP.transform, new Color(.7f,.15f,.15f,.9f));
var dTitle = MakeTMP("TitleText", dP.transform, "DERROTA", 60f);
AnchorNorm(dTitle.rectTransform, .08f,.84f,.92f,.96f);
dTitle.color = new Color(.9f,.25f,.25f); dTitle.fontStyle = FontStyles.Bold; dTitle.alignment = TextAlignmentOptions.Center;
dTitle.outlineWidth = .12f; dTitle.outlineColor = new Color(.35f,.05f,.05f,.6f);
MakeDivider(dP.transform, .79f, new Color(.7f,.15f,.15f,.7f));
var dChName = MakeTMP("ChapterNameText", dP.transform, "Capítulo", 30f);
AnchorNorm(dChName.rectTransform, .08f,.70f,.92f,.82f);
dChName.color = Color.white; dChName.alignment = TextAlignmentOptions.Center; dChName.fontStyle = FontStyles.Bold;
var dReason = MakeTMP("ReasonText", dP.transform, "Jaque mate", 24f);
AnchorNorm(dReason.rectTransform, .08f,.58f,.92f,.70f);
dReason.color = new Color(.95f,.6f,.6f); dReason.alignment = TextAlignmentOptions.Center; dReason.fontStyle = FontStyles.Italic;
var dLost = MakeTMP("PiecesLostText", dP.transform, "Piezas perdidas: 0", 22f);
AnchorNorm(dLost.rectTransform, .08f,.46f,.92f,.58f);
dLost.color = new Color(.9f,.7f,.7f); dLost.alignment = TextAlignmentOptions.Center;
var dStats = MakeTMP("StatsText", dP.transform, "", 20f);
AnchorNorm(dStats.rectTransform, .08f,.20f,.92f,.44f);
dStats.color = new Color(.78f,.78f,.78f); dStats.alignment = TextAlignmentOptions.Center; dStats.lineSpacing = 6f;
var dCont = MakeButton("ContinueButton", dP.transform, "CONTINUAR");
AnchorNorm(dCont.GetComponent<RectTransform>(), .28f,.04f,.72f,.18f);
dCont.GetComponent<Image>().color = new Color(.4f,.14f,.14f);
ColorBlock dcb = dCont.GetComponent<Button>().colors;
dcb.highlightedColor = new Color(.55f,.22f,.22f); dcb.pressedColor = new Color(.28f,.08f,.08f);
dCont.GetComponent<Button>().colors = dcb;
var dCg = dP.AddComponent<CanvasGroup>();
var dUI = dP.AddComponent<AjedrezPurgatorio.UI.DefeatUI>();
var dSO = new SerializedObject(dUI);
Ref(dSO, "_panel", dP); Ref(dSO, "_titleText", dTitle); Ref(dSO, "_chapterNameText", dChName);
Ref(dSO, "_reasonText", dReason); Ref(dSO, "_piecesLostText", dLost); Ref(dSO, "_statsText", dStats);
Ref(dSO, "_continueButton", dCont.GetComponent<Button>()); Ref(dSO, "_canvasGroup", dCg);
dSO.ApplyModifiedPropertiesWithoutUndo();
dOverlay.SetActive(false); dP.SetActive(false);
Debug.Log(" ✅ DefeatPanel creado.");
}
// — Memorial Panel —
if (Object.FindFirstObjectByType<AjedrezPurgatorio.UI.MemorialUI>() == null)
{
var mOverlay = MakeOverlay(canvasTransform);
var mP = MakePanel("MemorialPanel", canvasTransform, new Vector2(800, 560), new Color(.05f,.03f,.07f,.98f));
AddBorder(mP.transform, new Color(.55f,.45f,.7f,.9f));
var mTitle = MakeTMP("TitleText", mP.transform, "MEMORIAL", 52f);
AnchorNorm(mTitle.rectTransform, .08f,.86f,.92f,.96f);
mTitle.color = new Color(.78f,.62f,.9f); mTitle.fontStyle = FontStyles.Bold; mTitle.alignment = TextAlignmentOptions.Center;
mTitle.outlineWidth = .1f; mTitle.outlineColor = new Color(.2f,.15f,.3f,.5f);
MakeDivider(mP.transform, .81f, new Color(.55f,.45f,.7f,.7f));
var mChName = MakeTMP("ChapterNameText", mP.transform, "Capítulo", 30f);
AnchorNorm(mChName.rectTransform, .08f,.73f,.92f,.84f);
mChName.color = Color.white; mChName.alignment = TextAlignmentOptions.Center; mChName.fontStyle = FontStyles.Bold;
var mResult = MakeTMP("ResultText", mP.transform, "", 28f);
AnchorNorm(mResult.rectTransform, .08f,.63f,.92f,.73f);
mResult.color = new Color(1f,.88f,.3f); mResult.fontStyle = FontStyles.Bold; mResult.alignment = TextAlignmentOptions.Center;
var mPieces = MakeTMP("PiecesStatusText", mP.transform, "", 20f);
AnchorNorm(mPieces.rectTransform, .08f,.30f,.92f,.62f);
mPieces.color = new Color(.78f,.78f,.78f); mPieces.alignment = TextAlignmentOptions.Center; mPieces.lineSpacing = 8f;
var mProgress = MakeTMP("ProgressText", mP.transform, "Progreso: 0/3", 22f);
AnchorNorm(mProgress.rectTransform, .08f,.18f,.92f,.30f);
mProgress.color = new Color(.7f,.7f,.9f); mProgress.alignment = TextAlignmentOptions.Center;
var mCont = MakeButton("ContinueButton", mP.transform, "CONTINUAR");
AnchorNorm(mCont.GetComponent<RectTransform>(), .28f,.04f,.72f,.16f);
mCont.GetComponent<Image>().color = new Color(.2f,.15f,.35f);
ColorBlock mcb = mCont.GetComponent<Button>().colors;
mcb.highlightedColor = new Color(.32f,.24f,.5f); mcb.pressedColor = new Color(.12f,.08f,.22f);
mCont.GetComponent<Button>().colors = mcb;
var mCg = mP.AddComponent<CanvasGroup>();
var mUI = mP.AddComponent<AjedrezPurgatorio.UI.MemorialUI>();
var mSO = new SerializedObject(mUI);
Ref(mSO, "_panel", mP); Ref(mSO, "_titleText", mTitle); Ref(mSO, "_chapterNameText", mChName);
Ref(mSO, "_resultText", mResult); Ref(mSO, "_piecesStatusText", mPieces); Ref(mSO, "_progressText", mProgress);
Ref(mSO, "_continueButton", mCont.GetComponent<Button>()); Ref(mSO, "_canvasGroup", mCg);
mSO.ApplyModifiedPropertiesWithoutUndo();
mOverlay.SetActive(false); mP.SetActive(false);
Debug.Log(" ✅ MemorialPanel creado.");
}
}
void OnGUI()
{
GUILayout.Label("Sistema de Purgatorio - Validación de Setup", EditorStyles.boldLabel);
@@ -507,6 +660,54 @@ public class PurgatorySetupValidator : EditorWindow
return go;
}
static GameObject MakeOverlay(Transform parent)
{
var go = new GameObject("Overlay");
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = new Color(0f, 0f, 0f, 0.55f);
Stretch(go.GetComponent<RectTransform>());
return go;
}
static void AddBorder(Transform panel, Color borderColor)
{
float thickness = 3f;
Vector2 sz = panel.GetComponent<RectTransform>().sizeDelta;
MakeBorderEdge("BorderTop", panel, new Vector2(sz.x + thickness*2, thickness), new Vector2(0, sz.y/2f - thickness/2f), borderColor);
MakeBorderEdge("BorderBottom", panel, new Vector2(sz.x + thickness*2, thickness), new Vector2(0, -sz.y/2f + thickness/2f), borderColor);
MakeBorderEdge("BorderLeft", panel, new Vector2(thickness, sz.y + thickness*2), new Vector2(-sz.x/2f + thickness/2f, 0), borderColor);
MakeBorderEdge("BorderRight", panel, new Vector2(thickness, sz.y + thickness*2), new Vector2(sz.x/2f - thickness/2f, 0), borderColor);
}
static void MakeBorderEdge(string name, Transform parent, Vector2 size, Vector2 pos, Color color)
{
var go = new GameObject(name);
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = color;
img.raycastTarget = false;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = rt.pivot = new Vector2(.5f, .5f);
rt.sizeDelta = size;
rt.anchoredPosition = pos;
}
static void MakeDivider(Transform parent, float yNorm, Color color)
{
var go = new GameObject("Divider");
go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>();
img.color = color;
img.raycastTarget = false;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(.12f, yNorm);
rt.anchorMax = new Vector2(.88f, yNorm);
rt.sizeDelta = new Vector2(0, 2f);
rt.anchoredPosition = Vector2.zero;
}
static void AnchorNorm(RectTransform rt, float xMin, float yMin, float xMax, float yMax)
{
rt.anchorMin = new Vector2(xMin, yMin); rt.anchorMax = new Vector2(xMax, yMax);
+123 -20
View File
@@ -1,6 +1,7 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using System.Collections.Generic;
using AjedrezPurgatorio.Data;
using AjedrezPurgatorio.Meta;
using AjedrezPurgatorio.UI;
@@ -329,14 +330,14 @@ public class CampaignManager : MonoBehaviour
AutoSaveProgress();
if (_currentDeadKing != null)
// Show victory UI, then proceed to outro/dead king reveal
ShowVictoryUI(() =>
{
ShowDeadKingReveal(() => TransitionToChapterOutro());
}
else
{
TransitionToChapterOutro();
}
if (_currentDeadKing != null)
ShowDeadKingReveal(() => TransitionToChapterOutro());
else
TransitionToChapterOutro();
});
}
private void OnChapterDefeat()
@@ -349,7 +350,9 @@ public class CampaignManager : MonoBehaviour
_campaignState.CompleteChapter(CurrentChapter.id, wasVictory: false);
AutoSaveProgress();
TransitionToDeadKings();
// Show defeat UI, then proceed to dead kings flow
ShowDefeatUI(() => TransitionToDeadKings());
}
// ══════════════════════════════════════════════════════
@@ -431,6 +434,16 @@ public class CampaignManager : MonoBehaviour
CompleteChapter();
}
private void ActivateHierarchy(Transform t)
{
while (t != null)
{
if (!t.gameObject.activeSelf)
t.gameObject.SetActive(true);
t = t.parent;
}
}
private void TransitionToDeadKings()
{
Debug.Log("[CampaignManager] Dead Kings flow...");
@@ -438,22 +451,109 @@ public class CampaignManager : MonoBehaviour
if (GameStateManager.Instance != null)
GameStateManager.Instance.TransitionTo(GameState.GameOver);
DeadKingInputUI inputUI = FindObjectOfType<DeadKingInputUI>();
DeadKingInputUI inputUI = FindObjectOfType<DeadKingInputUI>(true);
if (inputUI != null)
{
ActivateHierarchy(inputUI.transform);
inputUI.Show(_campaignState, _currentChapterIndex);
}
else
Debug.LogWarning("[CampaignManager] DeadKingInputUI no encontrado.");
}
private void ShowDeadKingReveal(Action onContinue)
{
DeadKingRevealUI revealUI = FindObjectOfType<DeadKingRevealUI>();
DeadKingRevealUI revealUI = FindObjectOfType<DeadKingRevealUI>(true);
if (revealUI != null)
{
ActivateHierarchy(revealUI.transform);
revealUI.Show(_currentDeadKing, onContinue);
}
else
onContinue?.Invoke();
}
private void ShowVictoryUI(Action onContinue)
{
VictoryUI victoryUI = FindObjectOfType<VictoryUI>(true);
if (victoryUI != null)
{
ActivateHierarchy(victoryUI.transform);
var stats = GatherCurrentStats();
victoryUI.Show(
CurrentChapter?.name ?? "Capítulo",
_campaignState?.CurrentChapterPiecesLost ?? 0,
stats.moves, stats.captures, stats.pWins, stats.pLosses,
onContinue
);
}
else
{
Debug.LogWarning("[CampaignManager] VictoryUI no encontrado.");
onContinue?.Invoke();
}
}
private void ShowDefeatUI(Action onContinue)
{
DefeatUI defeatUI = FindObjectOfType<DefeatUI>(true);
if (defeatUI != null)
{
ActivateHierarchy(defeatUI.transform);
var stats = GatherCurrentStats();
defeatUI.Show(
CurrentChapter?.name ?? "Capítulo",
"Jaque mate",
_campaignState?.CurrentChapterPiecesLost ?? 0,
stats.moves, stats.captures, stats.pWins, stats.pLosses,
onContinue
);
}
else
{
Debug.LogWarning("[CampaignManager] DefeatUI no encontrado.");
onContinue?.Invoke();
}
}
private void ShowMemorialUI(Action onContinue)
{
MemorialUI memorialUI = FindObjectOfType<MemorialUI>(true);
if (memorialUI != null)
{
ActivateHierarchy(memorialUI.transform);
List<string> alivePieces = _campaignState?.GetAvailablePieceNames() ?? new List<string>();
memorialUI.Show(
CurrentChapter?.name ?? "Capítulo",
_campaignState?.LastChapterWasVictory ?? false,
alivePieces,
_campaignState?.TotalPiecesLost ?? 0,
_campaignState?.CompletedChapters.Count ?? 0,
TotalChapters,
onContinue
);
}
else
{
Debug.LogWarning("[CampaignManager] MemorialUI no encontrado.");
onContinue?.Invoke();
}
}
private (int moves, int captures, int pWins, int pLosses) GatherCurrentStats()
{
if (GameManager.Instance != null)
{
return (
GameManager.Instance.TotalMoves,
GameManager.Instance.TotalCaptures,
GameManager.Instance.PurgatoryWins,
GameManager.Instance.PurgatoryLosses
);
}
return (0, 0, 0, 0);
}
// ══════════════════════════════════════════════════════
// CHAPTER NAVIGATION (scene transitions)
// ══════════════════════════════════════════════════════
@@ -463,8 +563,8 @@ public class CampaignManager : MonoBehaviour
int nextIndex = _currentChapterIndex + 1;
Debug.Log($"[CampaignManager] Siguiente capítulo: {nextIndex + 1}");
// TODO: Memorial screen between chapters
LoadChapterScene(nextIndex);
// Show memorial screen, then load next chapter
ShowMemorialUI(() => LoadChapterScene(nextIndex));
}
private void HandleCampaignVictory()
@@ -474,14 +574,17 @@ public class CampaignManager : MonoBehaviour
_campaignActive = false;
OnCampaignVictory?.Invoke();
// Return to main menu
if (GameStateManager.Instance != null)
GameStateManager.Instance.TransitionTo(GameState.Menu);
if (SceneTransitionManager.Instance != null)
SceneTransitionManager.Instance.LoadScene("MainMenu");
else
SceneManager.LoadScene("MainMenu");
// Show memorial with campaign complete, then return to main menu
ShowMemorialUI(() =>
{
if (GameStateManager.Instance != null)
GameStateManager.Instance.TransitionTo(GameState.Menu);
if (SceneTransitionManager.Instance != null)
SceneTransitionManager.Instance.LoadScene("MainMenu");
else
SceneManager.LoadScene("MainMenu");
});
}
// ══════════════════════════════════════════════════════
@@ -141,9 +141,9 @@ namespace AjedrezPurgatorio.UI
// Show panel with fade in
if (_panel != null)
{
_panel.SetActive(true);
}
else
gameObject.SetActive(true);
StartCoroutine(FadeIn());
@@ -316,7 +316,7 @@ namespace AjedrezPurgatorio.UI
while (elapsed < _fadeInDuration)
{
elapsed += Time.deltaTime;
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / _fadeInDuration);
yield return null;
}
@@ -341,7 +341,7 @@ namespace AjedrezPurgatorio.UI
while (elapsed < _fadeOutDuration)
{
elapsed += Time.deltaTime;
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / _fadeOutDuration);
yield return null;
}
@@ -113,9 +113,9 @@ namespace AjedrezPurgatorio.UI
// Show panel with fade in
if (_panel != null)
{
_panel.SetActive(true);
}
else
gameObject.SetActive(true);
StartCoroutine(FadeIn());
@@ -156,7 +156,7 @@ namespace AjedrezPurgatorio.UI
/// </summary>
private IEnumerator InvokeContinueAfterFade()
{
yield return new WaitForSeconds(_fadeOutDuration);
yield return new WaitForSecondsRealtime(_fadeOutDuration);
_onContinueCallback?.Invoke();
}
@@ -177,7 +177,7 @@ namespace AjedrezPurgatorio.UI
while (elapsed < _fadeInDuration)
{
elapsed += Time.deltaTime;
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / _fadeInDuration);
yield return null;
}
@@ -202,7 +202,7 @@ namespace AjedrezPurgatorio.UI
while (elapsed < _fadeOutDuration)
{
elapsed += Time.deltaTime;
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / _fadeOutDuration);
yield return null;
}
+152
View File
@@ -0,0 +1,152 @@
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace AjedrezPurgatorio.UI
{
/// <summary>
/// UI panel shown when the player loses a chapter (checkmate on own king or draw).
/// Displays defeat message, stats, and a continue button to proceed to Dead Kings flow.
/// </summary>
public class DefeatUI : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private GameObject _panel;
[SerializeField] private TextMeshProUGUI _titleText;
[SerializeField] private TextMeshProUGUI _chapterNameText;
[SerializeField] private TextMeshProUGUI _reasonText;
[SerializeField] private TextMeshProUGUI _statsText;
[SerializeField] private TextMeshProUGUI _piecesLostText;
[SerializeField] private Button _continueButton;
[SerializeField] private CanvasGroup _canvasGroup;
[Header("Fade Configuration")]
[SerializeField] private float _fadeInDuration = 0.8f;
[SerializeField] private float _fadeOutDuration = 0.5f;
[Header("Debug")]
[SerializeField] private bool _enableDebugLogging = false;
private System.Action _onContinueCallback;
private void Awake()
{
if (_continueButton != null)
_continueButton.onClick.AddListener(OnContinueClick);
if (_panel != null)
_panel.SetActive(false);
}
private void OnDestroy()
{
if (_continueButton != null)
_continueButton.onClick.RemoveListener(OnContinueClick);
}
/// <summary>
/// Shows the defeat panel with chapter results.
/// </summary>
/// <param name="chapterName">Name of the failed chapter</param>
/// <param name="reason">Reason for defeat (checkmate, draw, etc.)</param>
/// <param name="piecesLost">Number of pieces lost during the chapter</param>
/// <param name="totalMoves">Total moves made</param>
/// <param name="totalCaptures">Total captures made</param>
/// <param name="purgatoryWins">Purgatory dice wins</param>
/// <param name="purgatoryLosses">Purgatory dice losses</param>
/// <param name="onContinue">Callback when continue is pressed</param>
public void Show(string chapterName, string reason, int piecesLost, int totalMoves,
int totalCaptures, int purgatoryWins, int purgatoryLosses,
System.Action onContinue = null)
{
_onContinueCallback = onContinue;
if (_titleText != null)
_titleText.text = "DERROTA";
if (_chapterNameText != null)
_chapterNameText.text = chapterName ?? "Capítulo";
if (_reasonText != null)
_reasonText.text = reason ?? "Jaque mate";
if (_piecesLostText != null)
_piecesLostText.text = $"Piezas perdidas: {piecesLost}";
if (_statsText != null)
_statsText.text = $"Movimientos: {totalMoves}\n" +
$"Capturas: {totalCaptures}\n" +
$"Purgatorio: {purgatoryWins}V / {purgatoryLosses}D";
if (_panel != null)
_panel.SetActive(true);
else
gameObject.SetActive(true);
StartCoroutine(FadeIn());
if (_enableDebugLogging)
Debug.Log($"[DefeatUI] Derrota en: {chapterName} - {reason}");
}
public void Hide()
{
StartCoroutine(FadeOutAndHide());
}
private void OnContinueClick()
{
if (_enableDebugLogging)
Debug.Log("[DefeatUI] Continue clicked.");
Hide();
StartCoroutine(InvokeContinueAfterFade());
}
private IEnumerator InvokeContinueAfterFade()
{
yield return new WaitForSecondsRealtime(_fadeOutDuration);
_onContinueCallback?.Invoke();
}
private IEnumerator FadeIn()
{
if (_canvasGroup == null) yield break;
float elapsed = 0f;
_canvasGroup.alpha = 0f;
while (elapsed < _fadeInDuration)
{
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / _fadeInDuration);
yield return null;
}
_canvasGroup.alpha = 1f;
}
private IEnumerator FadeOutAndHide()
{
if (_canvasGroup == null)
{
if (_panel != null) _panel.SetActive(false);
yield break;
}
float elapsed = 0f;
_canvasGroup.alpha = 1f;
while (elapsed < _fadeOutDuration)
{
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / _fadeOutDuration);
yield return null;
}
_canvasGroup.alpha = 0f;
if (_panel != null) _panel.SetActive(false);
}
}
}
+161
View File
@@ -0,0 +1,161 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace AjedrezPurgatorio.UI
{
/// <summary>
/// UI panel shown between chapters (after outro dialogue).
/// Displays chapter results summary, pieces status, and campaign progress.
/// </summary>
public class MemorialUI : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private GameObject _panel;
[SerializeField] private TextMeshProUGUI _titleText;
[SerializeField] private TextMeshProUGUI _chapterNameText;
[SerializeField] private TextMeshProUGUI _resultText;
[SerializeField] private TextMeshProUGUI _piecesStatusText;
[SerializeField] private TextMeshProUGUI _progressText;
[SerializeField] private Button _continueButton;
[SerializeField] private CanvasGroup _canvasGroup;
[Header("Fade Configuration")]
[SerializeField] private float _fadeInDuration = 0.8f;
[SerializeField] private float _fadeOutDuration = 0.5f;
[Header("Debug")]
[SerializeField] private bool _enableDebugLogging = false;
private System.Action _onContinueCallback;
private void Awake()
{
if (_continueButton != null)
_continueButton.onClick.AddListener(OnContinueClick);
if (_panel != null)
_panel.SetActive(false);
}
private void OnDestroy()
{
if (_continueButton != null)
_continueButton.onClick.RemoveListener(OnContinueClick);
}
/// <summary>
/// Shows the memorial panel with chapter results.
/// </summary>
/// <param name="chapterName">Name of the completed chapter</param>
/// <param name="wasVictory">Whether the chapter was won</param>
/// <param name="alivePieces">List of surviving piece names</param>
/// <param name="totalPiecesLost">Total pieces lost across campaign</param>
/// <param name="chaptersCompleted">Number of chapters completed</param>
/// <param name="totalChapters">Total chapters in campaign</param>
/// <param name="onContinue">Callback when continue is pressed</param>
public void Show(string chapterName, bool wasVictory, List<string> alivePieces,
int totalPiecesLost, int chaptersCompleted, int totalChapters,
System.Action onContinue = null)
{
_onContinueCallback = onContinue;
if (_titleText != null)
_titleText.text = "MEMORIAL";
if (_chapterNameText != null)
_chapterNameText.text = chapterName ?? "Capítulo";
if (_resultText != null)
_resultText.text = wasVictory ? "Victoria" : "Derrota";
if (_piecesStatusText != null)
{
if (alivePieces != null && alivePieces.Count > 0)
{
string names = string.Join(", ", alivePieces);
_piecesStatusText.text = $"Piezas vivas ({alivePieces.Count}):\n{names}\n\n" +
$"Total perdidas: {totalPiecesLost}";
}
else
{
_piecesStatusText.text = $"Total piezas perdidas: {totalPiecesLost}";
}
}
if (_progressText != null)
_progressText.text = $"Progreso: {chaptersCompleted}/{totalChapters} capítulos";
if (_panel != null)
_panel.SetActive(true);
else
gameObject.SetActive(true);
StartCoroutine(FadeIn());
if (_enableDebugLogging)
Debug.Log($"[MemorialUI] Memorial: {chapterName} - {(wasVictory ? "Victoria" : "Derrota")}");
}
public void Hide()
{
StartCoroutine(FadeOutAndHide());
}
private void OnContinueClick()
{
if (_enableDebugLogging)
Debug.Log("[MemorialUI] Continue clicked.");
Hide();
StartCoroutine(InvokeContinueAfterFade());
}
private IEnumerator InvokeContinueAfterFade()
{
yield return new WaitForSecondsRealtime(_fadeOutDuration);
_onContinueCallback?.Invoke();
}
private IEnumerator FadeIn()
{
if (_canvasGroup == null) yield break;
float elapsed = 0f;
_canvasGroup.alpha = 0f;
while (elapsed < _fadeInDuration)
{
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / _fadeInDuration);
yield return null;
}
_canvasGroup.alpha = 1f;
}
private IEnumerator FadeOutAndHide()
{
if (_canvasGroup == null)
{
if (_panel != null) _panel.SetActive(false);
yield break;
}
float elapsed = 0f;
_canvasGroup.alpha = 1f;
while (elapsed < _fadeOutDuration)
{
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / _fadeOutDuration);
yield return null;
}
_canvasGroup.alpha = 0f;
if (_panel != null) _panel.SetActive(false);
}
}
}
+146
View File
@@ -0,0 +1,146 @@
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace AjedrezPurgatorio.UI
{
/// <summary>
/// UI panel shown when the player wins a chapter (checkmate on enemy king).
/// Displays chapter name, stats, and a continue button to proceed to outro dialogue.
/// </summary>
public class VictoryUI : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private GameObject _panel;
[SerializeField] private TextMeshProUGUI _titleText;
[SerializeField] private TextMeshProUGUI _chapterNameText;
[SerializeField] private TextMeshProUGUI _statsText;
[SerializeField] private TextMeshProUGUI _piecesLostText;
[SerializeField] private Button _continueButton;
[SerializeField] private CanvasGroup _canvasGroup;
[Header("Fade Configuration")]
[SerializeField] private float _fadeInDuration = 0.8f;
[SerializeField] private float _fadeOutDuration = 0.5f;
[Header("Debug")]
[SerializeField] private bool _enableDebugLogging = false;
private System.Action _onContinueCallback;
private void Awake()
{
if (_continueButton != null)
_continueButton.onClick.AddListener(OnContinueClick);
if (_panel != null)
_panel.SetActive(false);
}
private void OnDestroy()
{
if (_continueButton != null)
_continueButton.onClick.RemoveListener(OnContinueClick);
}
/// <summary>
/// Shows the victory panel with chapter results.
/// </summary>
/// <param name="chapterName">Name of the completed chapter</param>
/// <param name="piecesLost">Number of pieces lost during the chapter</param>
/// <param name="totalMoves">Total moves made</param>
/// <param name="totalCaptures">Total captures made</param>
/// <param name="purgatoryWins">Purgatory dice wins</param>
/// <param name="purgatoryLosses">Purgatory dice losses</param>
/// <param name="onContinue">Callback when continue is pressed</param>
public void Show(string chapterName, int piecesLost, int totalMoves, int totalCaptures,
int purgatoryWins, int purgatoryLosses, System.Action onContinue = null)
{
_onContinueCallback = onContinue;
if (_titleText != null)
_titleText.text = "VICTORIA";
if (_chapterNameText != null)
_chapterNameText.text = chapterName ?? "Capítulo";
if (_piecesLostText != null)
_piecesLostText.text = $"Piezas perdidas: {piecesLost}";
if (_statsText != null)
_statsText.text = $"Movimientos: {totalMoves}\n" +
$"Capturas: {totalCaptures}\n" +
$"Purgatorio: {purgatoryWins}V / {purgatoryLosses}D";
if (_panel != null)
_panel.SetActive(true);
else
gameObject.SetActive(true);
StartCoroutine(FadeIn());
if (_enableDebugLogging)
Debug.Log($"[VictoryUI] Victoria en: {chapterName}");
}
public void Hide()
{
StartCoroutine(FadeOutAndHide());
}
private void OnContinueClick()
{
if (_enableDebugLogging)
Debug.Log("[VictoryUI] Continue clicked.");
Hide();
StartCoroutine(InvokeContinueAfterFade());
}
private IEnumerator InvokeContinueAfterFade()
{
yield return new WaitForSecondsRealtime(_fadeOutDuration);
_onContinueCallback?.Invoke();
}
private IEnumerator FadeIn()
{
if (_canvasGroup == null) yield break;
float elapsed = 0f;
_canvasGroup.alpha = 0f;
while (elapsed < _fadeInDuration)
{
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / _fadeInDuration);
yield return null;
}
_canvasGroup.alpha = 1f;
}
private IEnumerator FadeOutAndHide()
{
if (_canvasGroup == null)
{
if (_panel != null) _panel.SetActive(false);
yield break;
}
float elapsed = 0f;
_canvasGroup.alpha = 1f;
while (elapsed < _fadeOutDuration)
{
elapsed += Time.unscaledDeltaTime;
_canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / _fadeOutDuration);
yield return null;
}
_canvasGroup.alpha = 0f;
if (_panel != null) _panel.SetActive(false);
}
}
}