feat: herramientas editor y ajustes diálogo, campaña y transición de escena

This commit is contained in:
2026-08-16 03:59:20 -03:00
parent 51364556d9
commit b8b26ae5c1
12 changed files with 1240 additions and 8 deletions
+110
View File
@@ -0,0 +1,110 @@
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using TMPro;
/// <summary>
/// Corrige el layout roto del DialogueCanvas en Chapter1.
/// </summary>
public class FixDialogueLayout
{
public static void Execute()
{
Debug.Log("=== FixDialogueLayout: corrigiendo UI de diálogos ===");
var scene = EditorSceneManager.GetSceneByPath("Assets/Scenes/Chapter1.unity");
if (!scene.IsValid() || !scene.isLoaded)
scene = EditorSceneManager.OpenScene("Assets/Scenes/Chapter1.unity", OpenSceneMode.Single);
// ── DialoguePanel ──────────────────────────────────────────────────────────
var dialoguePanelGO = GameObject.Find("DialogueCanvas/DialoguePanel");
if (dialoguePanelGO == null)
{
Debug.LogError(" ✖ DialoguePanel no encontrado.");
return;
}
// Hacer que DialoguePanel se estire en todo el ancho, en la parte inferior
var panelRT = dialoguePanelGO.GetComponent<RectTransform>();
panelRT.anchorMin = new Vector2(0f, 0f);
panelRT.anchorMax = new Vector2(1f, 0f);
panelRT.offsetMin = new Vector2(0f, 0f);
panelRT.offsetMax = new Vector2(0f, 220f); // 220 px de altura desde abajo
panelRT.pivot = new Vector2(0.5f, 0f);
Debug.Log(" ✅ DialoguePanel: stretch en la parte inferior de pantalla (h=220px).");
// Asegurarse de que el panel está activo (se muestra solo cuando hay diálogo)
dialoguePanelGO.SetActive(true);
// ── SpeakerNameText ────────────────────────────────────────────────────────
var speakerNameGO = GameObject.Find("DialogueCanvas/DialoguePanel/SpeakerNameText");
if (speakerNameGO != null)
{
var rt = speakerNameGO.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(0f, 1f);
rt.anchorMax = new Vector2(0.35f, 1f);
rt.pivot = new Vector2(0f, 1f);
rt.offsetMin = new Vector2(20f, -48f); // 20px desde el borde, 48px de alto
rt.offsetMax = new Vector2(0f, 0f);
var tmp = speakerNameGO.GetComponent<TextMeshProUGUI>();
if (tmp != null)
{
tmp.text = "Speaker Name";
tmp.fontSize = 22f;
tmp.color = new Color(1f, 0.85f, 0f, 1f); // amarillo dorado
tmp.fontStyle = FontStyles.Bold;
tmp.overflowMode = TextOverflowModes.Overflow;
tmp.margin = Vector4.zero; // limpiar márgenes rotos
tmp.horizontalAlignment = HorizontalAlignmentOptions.Left;
tmp.verticalAlignment = VerticalAlignmentOptions.Middle;
}
Debug.Log(" ✅ SpeakerNameText corregido.");
}
// ── DialogueText ───────────────────────────────────────────────────────────
var dialogueTextGO = GameObject.Find("DialogueCanvas/DialoguePanel/DialogueText");
if (dialogueTextGO != null)
{
var rt = dialogueTextGO.GetComponent<RectTransform>();
// Stretch que ocupa casi todo el panel (dejando espacio para el nombre arriba)
rt.anchorMin = new Vector2(0f, 0f);
rt.anchorMax = new Vector2(1f, 1f);
rt.offsetMin = new Vector2(20f, 10f); // margen interior izq-abajo
rt.offsetMax = new Vector2(-20f, -55f); // margen interior der-arriba (55px para el nombre)
rt.pivot = new Vector2(0.5f, 0.5f);
var tmp = dialogueTextGO.GetComponent<TextMeshProUGUI>();
if (tmp != null)
{
tmp.text = "Dialogue text appears here...";
tmp.fontSize = 20f;
tmp.color = Color.white;
tmp.fontStyle = FontStyles.Normal;
tmp.overflowMode = TextOverflowModes.Overflow;
tmp.textWrappingMode = TextWrappingModes.Normal;
tmp.margin = Vector4.zero; // limpiar márgenes rotos
tmp.horizontalAlignment = HorizontalAlignmentOptions.Left;
tmp.verticalAlignment = VerticalAlignmentOptions.Top;
}
Debug.Log(" ✅ DialogueText corregido (stretch, márgenes limpios).");
}
// ── ContinueButton ─────────────────────────────────────────────────────────
var continueButtonGO = GameObject.Find("DialogueCanvas/DialoguePanel/DialogueText/ContinueButton");
if (continueButtonGO != null)
{
var rt = continueButtonGO.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(1f, 0f);
rt.anchorMax = new Vector2(1f, 0f);
rt.pivot = new Vector2(1f, 0f);
rt.anchoredPosition = new Vector2(-20f, 10f);
rt.sizeDelta = new Vector2(40f, 40f);
Debug.Log(" ✅ ContinueButton posicionado en esquina inferior derecha.");
}
EditorSceneManager.MarkSceneDirty(scene);
EditorSceneManager.SaveScene(scene);
Debug.Log("=== FixDialogueLayout: completado y guardado ===");
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dbc75f0946668e9468ef8b07d6ef1884
+215
View File
@@ -0,0 +1,215 @@
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
/// <summary>
/// Corrige los 3 errores críticos encontrados en Play Mode.
/// </summary>
public class FixErrors
{
public static void Execute()
{
Debug.Log("=== FixErrors: corrigiendo errores críticos ===");
// 1. SceneTransitionManager — agregar CanvasGroup en MainMenu y Chapter1
FixSceneTransitionManager("Assets/Scenes/MainMenu.unity");
FixSceneTransitionManager("Assets/Scenes/Chapter1.unity");
// 2. BoardManager — crear MoveIndicator prefab y asignarlo
CreateMoveIndicatorPrefab();
// 3. CampaignConfig — verificar/asignar JSON
FixCampaignConfig();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("=== FixErrors: completado ===");
}
// ─────────────────────────────────────────────
// 1. SceneTransitionManager: añadir CanvasGroup
// ─────────────────────────────────────────────
static void FixSceneTransitionManager(string scenePath)
{
var scene = EditorSceneManager.GetSceneByPath(scenePath);
if (!scene.IsValid() || !scene.isLoaded)
scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
var stm = Object.FindFirstObjectByType<SceneTransitionManager>();
if (stm == null)
{
Debug.LogWarning($" ⚠ SceneTransitionManager no encontrado en {scenePath}");
return;
}
// Buscar FadeCanvas hijo
var fadeCanvas = stm.transform.Find("FadeCanvas");
if (fadeCanvas == null)
{
// Crear FadeCanvas si no existe
var canvasGO = new GameObject("FadeCanvas");
canvasGO.transform.SetParent(stm.transform, false);
var canvas = canvasGO.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = 999;
var scaler = canvasGO.AddComponent<CanvasScaler>();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(1920, 1080);
fadeCanvas = canvasGO.transform;
Debug.Log($" ✅ FadeCanvas creado en {scenePath}");
}
// Asegurarse que FadeCanvas tiene CanvasGroup
var cg = fadeCanvas.GetComponent<CanvasGroup>();
if (cg == null)
{
cg = fadeCanvas.gameObject.AddComponent<CanvasGroup>();
Debug.Log($" ✅ CanvasGroup añadido a FadeCanvas en {scenePath}");
}
// Buscar o crear FadeImage
var fadeImageTransform = fadeCanvas.Find("FadeImage");
Image fadeImg = null;
if (fadeImageTransform == null)
{
var imgGO = new GameObject("FadeImage");
imgGO.transform.SetParent(fadeCanvas, false);
fadeImg = imgGO.AddComponent<Image>();
fadeImg.color = new Color(0, 0, 0, 1);
var rt = imgGO.GetComponent<RectTransform>();
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = rt.offsetMax = Vector2.zero;
Debug.Log($" ✅ FadeImage creado en {scenePath}");
}
else
{
fadeImg = fadeImageTransform.GetComponent<Image>();
}
// Asignar referencias en SceneTransitionManager
var so = new SerializedObject(stm);
var cgProp = so.FindProperty("_fadeCanvasGroup");
var imgProp = so.FindProperty("_fadeImage");
if (cgProp != null) { cgProp.objectReferenceValue = cg; Debug.Log($" ✅ _fadeCanvasGroup asignado"); }
if (imgProp != null) { imgProp.objectReferenceValue = fadeImg; Debug.Log($" ✅ _fadeImage asignado"); }
so.ApplyModifiedPropertiesWithoutUndo();
// Inicializar: alpha = 0, no bloquear raycast
cg.alpha = 0f;
cg.blocksRaycasts = false;
EditorSceneManager.MarkSceneDirty(scene);
EditorSceneManager.SaveScene(scene);
Debug.Log($" ✅ SceneTransitionManager corregido en {scenePath}");
}
// ─────────────────────────────────────────────
// 2. MoveIndicator Prefab
// ─────────────────────────────────────────────
static void CreateMoveIndicatorPrefab()
{
const string prefabPath = "Assets/Game/Prefabs/UI/MoveIndicator.prefab";
// Abrir Chapter1 para asignar
var c1Scene = EditorSceneManager.GetSceneByPath("Assets/Scenes/Chapter1.unity");
if (!c1Scene.IsValid() || !c1Scene.isLoaded)
c1Scene = EditorSceneManager.OpenScene("Assets/Scenes/Chapter1.unity", OpenSceneMode.Single);
// Crear prefab si no existe
if (!File.Exists(prefabPath))
{
// Crear carpeta si no existe
if (!AssetDatabase.IsValidFolder("Assets/Game/Prefabs/UI"))
AssetDatabase.CreateFolder("Assets/Game/Prefabs", "UI");
// Crear GO temporal en escena
var indicatorGO = new GameObject("MoveIndicator");
var sr = indicatorGO.AddComponent<SpriteRenderer>();
// Usar el sprite de círculo built-in de Unity o un sprite default
var circleSprite = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Knob.psd");
if (circleSprite != null)
sr.sprite = circleSprite;
sr.color = new Color(0.2f, 0.9f, 0.2f, 0.55f); // verde semitransparente
sr.sortingOrder = 5;
indicatorGO.transform.localScale = new Vector3(0.7f, 0.7f, 1f);
// Guardar como prefab
var prefab = PrefabUtility.SaveAsPrefabAsset(indicatorGO, prefabPath);
Object.DestroyImmediate(indicatorGO);
AssetDatabase.Refresh();
Debug.Log($" ✅ MoveIndicator prefab creado en {prefabPath}");
}
else
{
Debug.Log(" ⏭ MoveIndicator prefab ya existe.");
}
// Asignar a BoardManager en Chapter1
var bm = Object.FindFirstObjectByType<BoardManager>();
if (bm != null)
{
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (prefab != null)
{
var so = new SerializedObject(bm);
var prop = so.FindProperty("_moveIndicatorPrefab");
if (prop != null)
{
prop.objectReferenceValue = prefab;
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log(" ✅ BoardManager._moveIndicatorPrefab asignado.");
}
}
}
else
{
Debug.LogWarning(" ⚠ BoardManager no encontrado en Chapter1.");
}
EditorSceneManager.MarkSceneDirty(c1Scene);
EditorSceneManager.SaveScene(c1Scene);
}
// ─────────────────────────────────────────────
// 3. CampaignConfig: verificar JSON asignado
// ─────────────────────────────────────────────
static void FixCampaignConfig()
{
var config = AssetDatabase.LoadAssetAtPath<CampaignConfig>("Assets/Game/Data/CampaignConfig.asset");
if (config == null)
{
Debug.LogWarning(" ⚠ CampaignConfig.asset no encontrado.");
return;
}
var so = new SerializedObject(config);
var prop = so.FindProperty("_campaignDataJson");
if (prop != null && prop.objectReferenceValue == null)
{
var json = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/Data/Campaign/campaign_config.json");
if (json != null)
{
prop.objectReferenceValue = json;
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log(" ✅ CampaignConfig._campaignDataJson asignado.");
}
else
{
Debug.LogWarning(" ⚠ campaign_config.json no encontrado en Assets/Data/Campaign/");
}
}
else
{
Debug.Log(" ⏭ CampaignConfig._campaignDataJson ya asignado.");
}
AssetDatabase.SaveAssets();
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0c1977031974e544c954acd6c653cf3f
+732
View File
@@ -0,0 +1,732 @@
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// Implementa en Unity todos los sistemas ya desarrollados para Ajedrez Purgatorio.
/// </summary>
public class ProjectSetup
{
public static void Execute()
{
Debug.Log("╔════════════════════════════════════════════╗");
Debug.Log("║ AJEDREZ PURGATORIO — SETUP COMPLETO ║");
Debug.Log("╚════════════════════════════════════════════╝");
CreatePieceIdentityAssets();
CreateCampaignConfigAsset();
SetupChapter1();
SetupMainMenuScene();
ConfigureBuildSettings();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("✅ Setup completado.");
}
// ══════════════════════════════════════════════════════
// PIECE IDENTITY ASSETS (16 personajes)
// ══════════════════════════════════════════════════════
static void CreatePieceIdentityAssets()
{
Debug.Log("── PieceIdentity assets...");
string folder = "Assets/Game/Data/PieceIdentities";
if (!AssetDatabase.IsValidFolder(folder))
AssetDatabase.CreateFolder("Assets/Game/Data", "PieceIdentities");
var defs = new (string file, string name, string role, string rel, PieceType type, string[] q)[]
{
("King_Ricardo", "Ricardo Valdés", "El Rey", "Tú mismo", PieceType.King, new[]{"No puedo caer."}),
("Queen_Elena", "Elena Valdés", "Tu esposa", "Esposa", PieceType.Queen, new[]{"Siempre te perdoné.","Te amé hasta el final."}),
("Rook_DonAlberto", "Don Alberto", "Padre del Rey", "Tu padre", PieceType.Rook, new[]{"Te di todo lo que pude."}),
("Rook_DonaCarmen", "Doña Carmen", "Madre del Rey", "Tu madre", PieceType.Rook, new[]{"Siempre creí en ti."}),
("Bishop_Tomas", "Padre Tomás", "Confesor", "Tu confesor", PieceType.Bishop, new[]{"El arrepentimiento requiere acción."}),
("Bishop_Lucia", "Dra. Lucía Reyes", "Médica de familia","Tu médica", PieceType.Bishop, new[]{"Debiste venir antes."}),
("Knight_Marcos", "Marcos Herrera", "Socio fundador", "Tu socio", PieceType.Knight, new[]{"Construimos algo juntos."}),
("Knight_Santiago", "Santiago Ruiz", "Segundo socio", "Tu socio", PieceType.Knight, new[]{"La lealtad tiene un límite."}),
("Pawn_Carlos", "Carlos", "Operario", "Empleado 15 años", PieceType.Pawn, new[]{"Señor... ¿por qué?"}),
("Pawn_Marta", "Marta", "Contadora", "Empleada de confianza", PieceType.Pawn, new[]{"Nunca me dijiste la verdad."}),
("Pawn_Julio", "Julio", "Supervisor", "Tu supervisor", PieceType.Pawn, new[]{"¿Eras un buen hombre?"}),
("Pawn_Ana", "Ana", "Secretaria", "Tu secretaria", PieceType.Pawn, new[]{"Todas las cartas que no enviaste."}),
("Pawn_Pedro", "Pedro", "Técnico senior", "Tu técnico", PieceType.Pawn, new[]{"Yo avisé del fallo."}),
("Pawn_Rosa", "Rosa", "Limpieza", "Empleada invisible", PieceType.Pawn, new[]{"Nunca supiste mi nombre."}),
("Pawn_Luis", "Luis", "Almacén", "Tu trabajador", PieceType.Pawn, new[]{"Tenía tres hijos, señor."}),
("Pawn_Isabel", "Isabel", "RRHH", "Tu jefa de RRHH", PieceType.Pawn, new[]{"Procesé las 47 cartas de despido."}),
};
var campaignState = AssetDatabase.LoadAssetAtPath<CampaignState>("Assets/Game/Data/Resources/CampaignState.asset");
var created = new List<PieceIdentity>();
foreach (var d in defs)
{
string path = $"{folder}/{d.file}.asset";
var identity = AssetDatabase.LoadAssetAtPath<PieceIdentity>(path);
if (identity == null)
{
identity = ScriptableObject.CreateInstance<PieceIdentity>();
identity.characterName = d.name;
identity.role = d.role;
identity.relationship = d.rel;
identity.pieceType = d.type;
identity.quotes = d.q;
identity.isAlive = true;
AssetDatabase.CreateAsset(identity, path);
Debug.Log($" ✅ {d.name}");
}
created.Add(identity);
}
if (campaignState != null)
{
var so = new SerializedObject(campaignState);
var prop = so.FindProperty("_allIdentities");
if (prop != null)
{
prop.ClearArray();
for (int i = 0; i < created.Count; i++)
{
prop.InsertArrayElementAtIndex(i);
prop.GetArrayElementAtIndex(i).objectReferenceValue = created[i];
}
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log($" ✅ {created.Count} identidades asignadas en CampaignState");
}
}
AssetDatabase.SaveAssets();
}
// ══════════════════════════════════════════════════════
// CAMPAIGN CONFIG ASSET
// ══════════════════════════════════════════════════════
static void CreateCampaignConfigAsset()
{
Debug.Log("── CampaignConfig asset...");
string path = "Assets/Game/Data/CampaignConfig.asset";
if (AssetDatabase.LoadAssetAtPath<CampaignConfig>(path) != null) { Debug.Log(" ⏭ ya existe."); return; }
var config = ScriptableObject.CreateInstance<CampaignConfig>();
AssetDatabase.CreateAsset(config, path);
var json = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/Data/Campaign/campaign_config.json");
if (json != null)
{
var so = new SerializedObject(config);
var prop = so.FindProperty("_campaignDataJson");
if (prop != null) { prop.objectReferenceValue = json; so.ApplyModifiedPropertiesWithoutUndo(); }
Debug.Log(" ✅ CampaignConfig creado con JSON.");
}
else Debug.LogWarning(" ⚠ campaign_config.json no encontrado.");
AssetDatabase.SaveAssets();
}
// ══════════════════════════════════════════════════════
// CHAPTER 1 SETUP COMPLETO
// ══════════════════════════════════════════════════════
static void SetupChapter1()
{
Debug.Log("── Configurando Chapter1...");
// Abrir la escena si hace falta
var scene = EditorSceneManager.GetSceneByPath("Assets/Scenes/Chapter1.unity");
if (!scene.IsValid() || !scene.isLoaded)
scene = EditorSceneManager.OpenScene("Assets/Scenes/Chapter1.unity", OpenSceneMode.Single);
ConnectBoardManager();
ConnectDialogueSystem();
ConnectDialogueUI();
SetupGameHUD();
CreatePieceTooltipUI();
CreatePromotionUI();
CreatePurgatorySystem();
CreatePauseMenuUI();
CreateChapterManagers();
EditorSceneManager.MarkSceneDirty(scene);
EditorSceneManager.SaveScene(scene);
Debug.Log(" ✅ Chapter1 guardado.");
}
// ── BoardManager ──────────────────────────────────────
static void ConnectBoardManager()
{
var bm = FindComp<BoardManager>("board");
if (bm == null) return;
var boardParent = GameObject.Find("BoardParent");
if (boardParent == null) return;
Ref(bm, "_boardParent", boardParent.transform);
Debug.Log(" ✅ BoardManager._boardParent conectado.");
}
// ── DialogueSystem ────────────────────────────────────
static void ConnectDialogueSystem()
{
var ds = FindComp<DialogueSystem>("DialogueSystem");
if (ds == null) return;
string[] paths = {
"Assets/Game/Data/Dialogues/ch1_intro.json",
"Assets/Game/Data/Dialogues/ch1_outro.json",
"Assets/Game/Data/Dialogues/ch2_intro.json",
"Assets/Game/Data/Dialogues/ch2_outro.json",
"Assets/Game/Data/Dialogues/ch3_intro.json",
"Assets/Game/Data/Dialogues/ch3_outro.json",
};
var so = new SerializedObject(ds);
var prop = so.FindProperty("_dialogueFiles");
if (prop == null) return;
prop.ClearArray();
int idx = 0;
foreach (var p in paths)
{
var ta = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
if (ta == null) continue;
prop.InsertArrayElementAtIndex(idx);
prop.GetArrayElementAtIndex(idx++).objectReferenceValue = ta;
}
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log($" ✅ DialogueSystem: {idx} archivos JSON.");
}
// ── DialogueUI ────────────────────────────────────────
static void ConnectDialogueUI()
{
var canvas = GameObject.Find("DialogueCanvas");
if (canvas == null) return;
var dui = canvas.GetComponent<DialogueUI>();
if (dui == null) return;
var panel = Path("DialogueCanvas/DialoguePanel");
var spkTmp = TMP("DialogueCanvas/DialoguePanel/SpeakerNameText");
var dlgTmp = TMP("DialogueCanvas/DialoguePanel/DialogueText");
var contGO = Path("DialogueCanvas/DialoguePanel/DialogueText/ContinueButton");
var so = new SerializedObject(dui);
if (panel != null) Ref(so, "_dialoguePanel", panel);
if (spkTmp != null) Ref(so, "_speakerNameText", spkTmp);
if (dlgTmp != null) Ref(so, "_dialogueText", dlgTmp);
if (contGO != null) Ref(so, "_continueIndicator",contGO);
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log(" ✅ DialogueUI referencias conectadas.");
}
// ── GameHUD ───────────────────────────────────────────
static void SetupGameHUD()
{
var hudCanvas = GameObject.Find("GameHUDCanvas");
if (hudCanvas == null) return;
var hud = hudCanvas.GetComponent<AjedrezPurgatorio.UI.GameHUD>()
?? hudCanvas.AddComponent<AjedrezPurgatorio.UI.GameHUD>();
// Re-parent CheckText dentro de Panel
var panel = Path("GameHUDCanvas/Panel");
var checkText = Path("GameHUDCanvas/CheckText");
if (panel != null && checkText != null && checkText.transform.parent != panel.transform)
{
checkText.transform.SetParent(panel.transform, false);
Stretch(checkText.GetComponent<RectTransform>());
}
if (panel != null) panel.SetActive(false);
// BlackCapturedPanel
var whitePnl = Path("GameHUDCanvas/WhiteCapturedPanel");
var blackPnl = Path("GameHUDCanvas/BlackCapturedPanel");
if (blackPnl == null && whitePnl != null)
{
blackPnl = Object.Instantiate(whitePnl, hudCanvas.transform);
blackPnl.name = "BlackCapturedPanel";
var rt = blackPnl.GetComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = rt.pivot = new Vector2(1, 0.5f);
rt.anchoredPosition = new Vector2(-10, 0);
}
var so = new SerializedObject(hud);
Ref(so, "_turnText", TMP("GameHUDCanvas/TurnText"));
Ref(so, "_moveCountText", TMP("GameHUDCanvas/MoveCountText"));
if (panel != null) Ref(so, "_checkIndicator", panel);
if (whitePnl != null) Ref(so, "_whiteCapturedContainer", whitePnl.transform);
if (blackPnl != null) Ref(so, "_blackCapturedContainer", blackPnl.transform);
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log(" ✅ GameHUD configurado.");
}
// ── PieceTooltip UI ───────────────────────────────────
static void CreatePieceTooltipUI()
{
if (GameObject.Find("PieceTooltipCanvas") != null) { Debug.Log(" ⏭ PieceTooltipCanvas ya existe."); return; }
var cv = MakeCanvas("PieceTooltipCanvas", 90);
var bg = MakePanel("TooltipPanel", cv.transform, new Vector2(280, 130), new Color(0.08f, 0.04f, 0.04f, 0.92f));
var nm = MakeTMP("NameText", bg.transform, "Nombre", 22f); nm.color = new Color(1f, 0.85f, 0.2f); nm.fontStyle = FontStyles.Bold;
var rl = MakeTMP("RoleText", bg.transform, "Rol", 17f); rl.color = new Color(0.9f, 0.65f, 0.65f);
var re = MakeTMP("RelationshipText", bg.transform, "Rel.", 14f); re.color = new Color(0.8f, 0.8f, 0.8f);
AnchorNorm(nm.rectTransform, .05f, .62f, .95f, .95f);
AnchorNorm(rl.rectTransform, .05f, .33f, .95f, .62f);
AnchorNorm(re.rectTransform, .05f, .05f, .95f, .33f);
bg.SetActive(false);
var tt = cv.gameObject.AddComponent<PieceTooltip>();
var so = new SerializedObject(tt);
Ref(so, "_tooltipPanel", bg);
Ref(so, "_nameText", nm);
Ref(so, "_roleText", rl);
Ref(so, "_relationshipText", re);
so.ApplyModifiedPropertiesWithoutUndo();
var gm = Object.FindFirstObjectByType<GameManager>();
if (gm != null) Ref(gm, "_pieceTooltip", tt);
Debug.Log(" ✅ PieceTooltipCanvas creado.");
}
// ── Promotion UI ──────────────────────────────────────
static void CreatePromotionUI()
{
if (GameObject.Find("PromotionCanvas") != null) { Debug.Log(" ⏭ PromotionCanvas ya existe."); return; }
var cv = MakeCanvas("PromotionCanvas", 150);
var dimBG = MakePanel("DimBG", cv.transform, Vector2.zero, new Color(0,0,0,0.7f));
Stretch(dimBG.GetComponent<RectTransform>());
var panel = MakePanel("PromotionPanel", cv.transform, new Vector2(620, 200), new Color(0.1f, 0.06f, 0.02f, 0.97f));
MakeTMP("Title", panel.transform, "PROMOCIÓN DE PEÓN", 28f).color = new Color(1f,.85f,.2f);
string[] lbls = { "♛ REINA", "♜ TORRE", "♝ ALFIL", "♞ CABALLO" };
string[] bNames = { "QueenButton","RookButton","BishopButton","KnightButton" };
var buttons = new Button[4];
float sx = -210f;
for (int i = 0; i < 4; i++)
{
var b = MakeButton(bNames[i], panel.transform, lbls[i]);
var rt = b.GetComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = new Vector2(.5f, 0f);
rt.sizeDelta = new Vector2(120, 55);
rt.anchoredPosition = new Vector2(sx + i * 140f, 15f);
buttons[i] = b.GetComponent<Button>();
}
panel.SetActive(false);
var pu = cv.gameObject.AddComponent<PromotionUI>();
var so = new SerializedObject(pu);
Ref(so, "_promotionPanel", panel);
Ref(so, "_queenButton", buttons[0]);
Ref(so, "_rookButton", buttons[1]);
Ref(so, "_bishopButton", buttons[2]);
Ref(so, "_knightButton", buttons[3]);
so.ApplyModifiedPropertiesWithoutUndo();
var gm = Object.FindFirstObjectByType<GameManager>();
if (gm != null) Ref(gm, "_promotionUI", pu);
Debug.Log(" ✅ PromotionCanvas creado.");
}
// ── Purgatory System ──────────────────────────────────
static void CreatePurgatorySystem()
{
if (GameObject.Find("PurgatoryCanvas") != null) { Debug.Log(" ⏭ PurgatoryCanvas ya existe."); return; }
var cv = MakeCanvas("PurgatoryCanvas", 120);
// — Offer Panel —
var offerP = MakePanel("OfferPanel", cv.transform, new Vector2(700, 480), new Color(.05f,.02f,.08f,.97f));
var oTitle = MakeTMP("TitleText", offerP.transform, "¿Desafiar a la Muerte?", 36f);
var oPName = MakeTMP("PieceNameText", offerP.transform, "Nombre", 30f);
var oRole = MakeTMP("RoleText", offerP.transform, "Rol", 22f);
var oRel = MakeTMP("RelationshipText", offerP.transform, "Relación", 18f);
var oFlav = MakeTMP("FlavorText", offerP.transform, "...", 18f);
AnchorNorm(oTitle.rectTransform, .05f,.80f,.95f,.97f); oTitle.color = new Color(.9f,.1f,.1f); oTitle.fontStyle = FontStyles.Bold; oTitle.alignment = TextAlignmentOptions.Center;
AnchorNorm(oPName.rectTransform, .05f,.64f,.95f,.80f); oPName.color = new Color(1f,.85f,.2f); oPName.fontStyle = FontStyles.Bold; oPName.alignment = TextAlignmentOptions.Center;
AnchorNorm(oRole.rectTransform, .05f,.52f,.95f,.64f); oRole.color = new Color(.85f,.65f,.65f); oRole.alignment = TextAlignmentOptions.Center;
AnchorNorm(oRel.rectTransform, .05f,.42f,.95f,.52f); oRel.color = new Color(.75f,.75f,.75f); oRel.alignment = TextAlignmentOptions.Center;
AnchorNorm(oFlav.rectTransform, .05f,.24f,.95f,.42f); oFlav.color = new Color(.7f,.7f,.85f); oFlav.fontStyle = FontStyles.Italic; oFlav.alignment = TextAlignmentOptions.Center;
var acceptB = MakeButton("AcceptButton", offerP.transform, "⚄ DESAFIAR");
var declineB = MakeButton("DeclineButton", offerP.transform, "✕ DEJAR IR");
AnchorNorm(acceptB.GetComponent<RectTransform>(), .08f,.04f,.45f,.20f); acceptB.GetComponent<Image>().color = new Color(.45f,.08f,.08f);
AnchorNorm(declineB.GetComponent<RectTransform>(), .55f,.04f,.92f,.20f); declineB.GetComponent<Image>().color = new Color(.18f,.18f,.18f);
var offerUI = offerP.AddComponent<PurgatoryOfferUI>();
var offerSO = new SerializedObject(offerUI);
Ref(offerSO, "_offerPanel", offerP);
Ref(offerSO, "_titleText", oTitle);
Ref(offerSO, "_pieceNameText", oPName);
Ref(offerSO, "_roleText", oRole);
Ref(offerSO, "_relationshipText", oRel);
Ref(offerSO, "_flavorText", oFlav);
Ref(offerSO, "_acceptButton", acceptB.GetComponent<Button>());
Ref(offerSO, "_declineButton", declineB.GetComponent<Button>());
offerSO.ApplyModifiedPropertiesWithoutUndo();
offerP.SetActive(false);
// — Dice Roll Panel —
var diceP = MakePanel("DiceRollPanel", cv.transform, new Vector2(700, 460), new Color(.03f,.03f,.1f,.97f));
var dStatus = MakeTMP("StatusText", diceP.transform, "Tirando dados...", 28f);
var dPRoll = MakeTMP("PlayerRollText", diceP.transform, "?", 72f);
var dDRoll = MakeTMP("DeathRollText", diceP.transform, "?", 72f);
var dPMod = MakeTMP("PlayerModText", diceP.transform, "+0", 18f);
var dPTot = MakeTMP("PlayerTotalText", diceP.transform, "Total: ?", 22f);
var dDTot = MakeTMP("DeathTotalText", diceP.transform, "Total: ?", 22f);
AnchorNorm(dStatus.rectTransform, .05f,.84f,.95f,.97f); dStatus.alignment = TextAlignmentOptions.Center; dStatus.color = Color.white;
AnchorNorm(dPRoll.rectTransform, .05f,.52f,.45f,.84f); dPRoll.color = new Color(.3f,.85f,.3f); dPRoll.fontStyle = FontStyles.Bold; dPRoll.alignment = TextAlignmentOptions.Center;
AnchorNorm(dDRoll.rectTransform, .55f,.52f,.95f,.84f); dDRoll.color = new Color(.85f,.2f,.2f); dDRoll.fontStyle = FontStyles.Bold; dDRoll.alignment = TextAlignmentOptions.Center;
AnchorNorm(dPMod.rectTransform, .05f,.36f,.45f,.52f); dPMod.color = new Color(.8f,.8f,.4f); dPMod.alignment = TextAlignmentOptions.Center;
AnchorNorm(dPTot.rectTransform, .05f,.22f,.45f,.36f); dPTot.color = new Color(.3f,.9f,.3f); dPTot.alignment = TextAlignmentOptions.Center;
AnchorNorm(dDTot.rectTransform, .55f,.22f,.95f,.36f); dDTot.color = new Color(.9f,.2f,.2f); dDTot.alignment = TextAlignmentOptions.Center;
var diceRollUI = diceP.AddComponent<DiceRollUI>();
var diceSO = new SerializedObject(diceRollUI);
Ref(diceSO, "_dicePanel", diceP);
Ref(diceSO, "_playerRollText", dPRoll);
Ref(diceSO, "_playerModifiersText", dPMod);
Ref(diceSO, "_playerTotalText", dPTot);
Ref(diceSO, "_deathRollText", dDRoll);
Ref(diceSO, "_deathTotalText", dDTot);
Ref(diceSO, "_statusText", dStatus);
diceSO.ApplyModifiedPropertiesWithoutUndo();
diceP.SetActive(false);
// — Result Panel —
var resP = MakePanel("ResultPanel", cv.transform, new Vector2(700, 440), new Color(.04f,.04f,.04f,.97f));
var rOut = MakeTMP("OutcomeText", resP.transform, "RESULTADO", 56f);
var rQuote = MakeTMP("DeathQuoteText", resP.transform, "\"...\"", 22f);
var rDet = MakeTMP("DetailsText", resP.transform, "...", 20f);
AnchorNorm(rOut.rectTransform, .05f,.74f,.95f,.97f); rOut.fontStyle = FontStyles.Bold; rOut.alignment = TextAlignmentOptions.Center;
AnchorNorm(rQuote.rectTransform, .08f,.48f,.92f,.74f); rQuote.fontStyle = FontStyles.Italic; rQuote.color = new Color(.7f,.7f,.85f); rQuote.alignment = TextAlignmentOptions.Center;
AnchorNorm(rDet.rectTransform, .05f,.30f,.95f,.48f); rDet.color = new Color(.75f,.75f,.75f); rDet.alignment = TextAlignmentOptions.Center;
var flashGO = new GameObject("FlashOverlay");
flashGO.transform.SetParent(resP.transform, false);
var flashImg = flashGO.AddComponent<Image>(); flashImg.color = new Color(1,1,1,0);
Stretch(flashGO.GetComponent<RectTransform>()); flashGO.SetActive(false);
var contResBtn = MakeButton("ContinueButton", resP.transform, "CONTINUAR");
AnchorNorm(contResBtn.GetComponent<RectTransform>(), .3f,.04f,.7f,.20f);
var resultUI = resP.AddComponent<DiceResultUI>();
var resSO = new SerializedObject(resultUI);
Ref(resSO, "_resultPanel", resP);
Ref(resSO, "_outcomeText", rOut);
Ref(resSO, "_deathQuoteText",rQuote);
Ref(resSO, "_detailsText", rDet);
Ref(resSO, "_continueButton",contResBtn.GetComponent<Button>());
Ref(resSO, "_flashOverlay", flashImg);
resSO.ApplyModifiedPropertiesWithoutUndo();
resP.SetActive(false);
// — PurgatoryManager GO —
var pmGO = new GameObject("PurgatoryManager");
var pmgr = pmGO.AddComponent<PurgatoryManager>();
var dSys = pmGO.AddComponent<DiceSystem>();
var cs = AssetDatabase.LoadAssetAtPath<CampaignState>("Assets/Game/Data/Resources/CampaignState.asset");
var pmSO = new SerializedObject(pmgr);
Ref(pmSO, "_diceSystem", dSys);
Ref(pmSO, "_offerUI", offerUI);
Ref(pmSO, "_diceRollUI", diceRollUI);
Ref(pmSO, "_resultUI", resultUI);
if (cs != null) Ref(pmSO, "_campaignState", cs);
pmSO.ApplyModifiedPropertiesWithoutUndo();
Debug.Log(" ✅ PurgatoryCanvas + PurgatoryManager creados.");
}
// ── Pause Menu ────────────────────────────────────────
static void CreatePauseMenuUI()
{
if (GameObject.Find("PauseMenuCanvas") != null) { Debug.Log(" ⏭ PauseMenuCanvas ya existe."); return; }
var cv = MakeCanvas("PauseMenuCanvas", 200);
var dimBG = MakePanel("DimBG", cv.transform, Vector2.zero, new Color(0,0,0,.75f));
Stretch(dimBG.GetComponent<RectTransform>()); dimBG.GetComponent<Image>().raycastTarget = true;
var panel = MakePanel("PausePanel", cv.transform, new Vector2(460, 480), new Color(.1f,.07f,.07f,.97f));
var title = MakeTMP("Title", panel.transform, "PAUSA", 60f);
AnchorNorm(title.rectTransform, .05f,.84f,.95f,.97f); title.fontStyle = FontStyles.Bold; title.alignment = TextAlignmentOptions.Center;
var contB = MakeButton("ContinueButton", panel.transform, "▶ CONTINUAR");
var retryB = MakeButton("RetryButton", panel.transform, "↺ REINTENTAR");
var mmB = MakeButton("MainMenuButton", panel.transform, "⌂ MENÚ PRINCIPAL");
AnchorNorm(contB.GetComponent<RectTransform>(), .1f,.66f,.9f,.80f); contB.GetComponent<Image>().color = new Color(.18f,.36f,.18f);
AnchorNorm(retryB.GetComponent<RectTransform>(), .1f,.48f,.9f,.62f); retryB.GetComponent<Image>().color = new Color(.3f,.28f,.1f);
AnchorNorm(mmB.GetComponent<RectTransform>(), .1f,.30f,.9f,.44f); mmB.GetComponent<Image>().color = new Color(.12f,.12f,.28f);
panel.SetActive(false);
var ctrl = cv.gameObject.AddComponent<AjedrezPurgatorio.UI.PauseMenuController>();
var so = new SerializedObject(ctrl);
Ref(so, "_panel", panel);
Ref(so, "_continueButton", contB.GetComponent<Button>());
Ref(so, "_retryButton", retryB.GetComponent<Button>());
Ref(so, "_mainMenuButton", mmB.GetComponent<Button>());
so.ApplyModifiedPropertiesWithoutUndo();
cv.gameObject.SetActive(false);
Debug.Log(" ✅ PauseMenuCanvas creado.");
}
// ── Managers de Chapter1 ──────────────────────────────
static void CreateChapterManagers()
{
var cs = AssetDatabase.LoadAssetAtPath<CampaignState>("Assets/Game/Data/Resources/CampaignState.asset");
var cfg = AssetDatabase.LoadAssetAtPath<CampaignConfig>("Assets/Game/Data/CampaignConfig.asset");
// CampaignManager
if (GameObject.Find("CampaignManager") == null)
{
var go = new GameObject("CampaignManager");
var cm = go.AddComponent<CampaignManager>();
var so = new SerializedObject(cm);
if (cfg != null) Ref(so, "_campaignConfig", cfg);
if (cs != null) Ref(so, "_campaignState", cs);
so.ApplyModifiedPropertiesWithoutUndo();
Debug.Log(" ✅ CampaignManager.");
}
// SceneTransitionManager
if (Object.FindFirstObjectByType<AjedrezPurgatorio.UI.SceneTransitionManager>() == null)
{
new GameObject("SceneTransitionManager").AddComponent<AjedrezPurgatorio.UI.SceneTransitionManager>();
Debug.Log(" ✅ SceneTransitionManager.");
}
// SaveSystem
if (Object.FindFirstObjectByType<AjedrezPurgatorio.Meta.SaveSystem>() == null)
{
new GameObject("SaveSystem").AddComponent<AjedrezPurgatorio.Meta.SaveSystem>();
Debug.Log(" ✅ SaveSystem.");
}
// AudioManager
if (Object.FindFirstObjectByType<AjedrezPurgatorio.Audio.AudioManager>() == null)
{
new GameObject("AudioManager").AddComponent<AjedrezPurgatorio.Audio.AudioManager>();
Debug.Log(" ✅ AudioManager.");
}
// PieceIdentityManager
if (Object.FindFirstObjectByType<PieceIdentityManager>() == null)
{
var go = new GameObject("PieceIdentityManager");
var pim = go.AddComponent<PieceIdentityManager>();
if (cs != null) Ref(pim, "_campaignState", cs);
Debug.Log(" ✅ PieceIdentityManager.");
}
}
// ══════════════════════════════════════════════════════
// MAIN MENU SCENE
// ══════════════════════════════════════════════════════
static void SetupMainMenuScene()
{
Debug.Log("── MainMenu scene...");
const string path = "Assets/Scenes/MainMenu.unity";
var scene = EditorSceneManager.GetSceneByPath(path);
if (!scene.IsValid() || !scene.isLoaded)
scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
if (!scene.IsValid())
{
scene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
EditorSceneManager.SaveScene(scene, path);
}
if (Object.FindFirstObjectByType<AjedrezPurgatorio.UI.MainMenuController>() == null)
BuildMainMenuUI();
else
Debug.Log(" ⏭ MainMenuController ya existe.");
if (Object.FindFirstObjectByType<CampaignManager>() == null)
CreateMainMenuManagers();
else
Debug.Log(" ⏭ Managers ya existen.");
EditorSceneManager.MarkSceneDirty(scene);
EditorSceneManager.SaveScene(scene);
Debug.Log(" ✅ MainMenu guardado.");
}
static void BuildMainMenuUI()
{
var cam = Object.FindFirstObjectByType<Camera>();
if (cam != null) { cam.clearFlags = CameraClearFlags.SolidColor; cam.backgroundColor = new Color(.1f,.05f,.02f); }
var cv = MakeCanvas("MainMenuCanvas", 0);
var bg = MakePanel("Background", cv.transform, Vector2.zero, new Color(.07f,.03f,.03f));
Stretch(bg.GetComponent<RectTransform>());
var title = MakeTMP("TitleText", cv.transform, "AJEDREZ PURGATORIO", 80f);
AnchorNorm(title.rectTransform, .1f,.74f,.9f,.93f);
title.fontStyle = FontStyles.Bold; title.alignment = TextAlignmentOptions.Center; title.color = new Color(1f,.85f,.2f);
var sub = MakeTMP("SubtitleText", cv.transform, "¿Puedes proteger en la muerte a quienes no protegiste en vida?", 22f);
AnchorNorm(sub.rectTransform, .15f,.65f,.85f,.74f);
sub.fontStyle = FontStyles.Italic; sub.alignment = TextAlignmentOptions.Center; sub.color = new Color(.75f,.6f,.6f);
var newB = MakeButton("NewCampaignButton", cv.transform, "✦ NUEVA CAMPAÑA");
var contB = MakeButton("ContinueButton", cv.transform, "▶ CONTINUAR");
var optB = MakeButton("OptionsButton", cv.transform, "⚙ OPCIONES");
var quitB = MakeButton("QuitButton", cv.transform, "✕ SALIR");
AnchorNorm(newB.GetComponent<RectTransform>(), .35f,.51f,.65f,.59f); newB.GetComponent<Image>().color = new Color(.35f,.14f,.04f);
AnchorNorm(contB.GetComponent<RectTransform>(), .35f,.41f,.65f,.49f); contB.GetComponent<Image>().color = new Color(.12f,.22f,.12f);
AnchorNorm(optB.GetComponent<RectTransform>(), .35f,.31f,.65f,.39f); optB.GetComponent<Image>().color = new Color(.18f,.18f,.24f);
AnchorNorm(quitB.GetComponent<RectTransform>(), .35f,.21f,.65f,.29f); quitB.GetComponent<Image>().color = new Color(.24f,.07f,.07f);
var ctrl = new GameObject("GameController").AddComponent<AjedrezPurgatorio.UI.MainMenuController>();
var so = new SerializedObject(ctrl);
Ref(so, "_newCampaignButton", newB.GetComponent<Button>());
Ref(so, "_continueButton", contB.GetComponent<Button>());
Ref(so, "_optionsButton", optB.GetComponent<Button>());
Ref(so, "_quitButton", quitB.GetComponent<Button>());
so.ApplyModifiedPropertiesWithoutUndo();
if (Object.FindFirstObjectByType<UnityEngine.EventSystems.EventSystem>() == null)
{
var es = new GameObject("EventSystem");
es.AddComponent<UnityEngine.EventSystems.EventSystem>();
es.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();
}
Debug.Log(" ✅ MainMenu UI construido.");
}
static void CreateMainMenuManagers()
{
var cs = AssetDatabase.LoadAssetAtPath<CampaignState>("Assets/Game/Data/Resources/CampaignState.asset");
var cfg = AssetDatabase.LoadAssetAtPath<CampaignConfig>("Assets/Game/Data/CampaignConfig.asset");
var cm = new GameObject("CampaignManager").AddComponent<CampaignManager>();
var so = new SerializedObject(cm);
if (cfg != null) Ref(so, "_campaignConfig", cfg);
if (cs != null) Ref(so, "_campaignState", cs);
so.ApplyModifiedPropertiesWithoutUndo();
new GameObject("SceneTransitionManager").AddComponent<AjedrezPurgatorio.UI.SceneTransitionManager>();
new GameObject("SaveSystem").AddComponent<AjedrezPurgatorio.Meta.SaveSystem>();
new GameObject("AudioManager").AddComponent<AjedrezPurgatorio.Audio.AudioManager>();
Debug.Log(" ✅ Managers MainMenu creados.");
}
// ══════════════════════════════════════════════════════
// BUILD SETTINGS
// ══════════════════════════════════════════════════════
static void ConfigureBuildSettings()
{
Debug.Log("── Build Settings...");
string[] scenes = {
"Assets/Scenes/MainMenu.unity",
"Assets/Scenes/Chapter1.unity",
"Assets/Scenes/Chapter2.unity",
"Assets/Scenes/Chapter3.unity",
};
var list = new List<EditorBuildSettingsScene>();
foreach (var s in scenes)
{
if (File.Exists(s))
{ list.Add(new EditorBuildSettingsScene(s, true)); Debug.Log($" ✅ {s}"); }
else
Debug.LogWarning($" ⚠ No existe: {s}");
}
EditorBuildSettings.scenes = list.ToArray();
}
// ══════════════════════════════════════════════════════
// HELPERS
// ══════════════════════════════════════════════════════
static Canvas MakeCanvas(string name, int order)
{
var go = new GameObject(name);
var c = go.AddComponent<Canvas>(); c.renderMode = RenderMode.ScreenSpaceOverlay; c.sortingOrder = order;
var sc = go.AddComponent<CanvasScaler>(); sc.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; sc.referenceResolution = new Vector2(1920,1080); sc.matchWidthOrHeight = .5f;
go.AddComponent<GraphicRaycaster>();
return c;
}
static GameObject MakePanel(string name, Transform parent, Vector2 size, Color color)
{
var go = new GameObject(name); go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>(); img.color = color;
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = rt.anchorMax = rt.pivot = new Vector2(.5f,.5f);
rt.sizeDelta = size == Vector2.zero ? new Vector2(1920,1080) : size;
rt.anchoredPosition = Vector2.zero;
return go;
}
static TextMeshProUGUI MakeTMP(string name, Transform parent, string text, float size)
{
var go = new GameObject(name); go.transform.SetParent(parent, false);
var tmp = go.AddComponent<TextMeshProUGUI>();
tmp.text = text; tmp.fontSize = size; tmp.color = Color.white; tmp.enableWordWrapping = true;
return tmp;
}
static GameObject MakeButton(string name, Transform parent, string label)
{
var go = new GameObject(name); go.transform.SetParent(parent, false);
var img = go.AddComponent<Image>(); img.color = new Color(.22f,.12f,.08f);
var btn = go.AddComponent<Button>();
var col = btn.colors; col.highlightedColor = new Color(.45f,.3f,.18f); col.pressedColor = new Color(.12f,.06f,.03f); btn.colors = col;
var tGO = new GameObject("Text (TMP)"); tGO.transform.SetParent(go.transform, false);
var tmp = tGO.AddComponent<TextMeshProUGUI>();
tmp.text = label; tmp.fontSize = 26f; tmp.fontStyle = FontStyles.Bold; tmp.color = Color.white; tmp.alignment = TextAlignmentOptions.Center;
Stretch(tGO.GetComponent<RectTransform>());
return go;
}
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);
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;
}
// Asignar referencia via SerializedObject
static void Ref(SerializedObject so, string field, Object val)
{
var p = so.FindProperty(field);
if (p != null) p.objectReferenceValue = val;
else Debug.LogWarning($" ⚠ campo '{field}' no encontrado en {so.targetObject?.GetType().Name}");
}
// Asignar referencia directamente en component (sin SO)
static void Ref(Component comp, string field, Object val)
{
var so = new SerializedObject(comp);
var p = so.FindProperty(field);
if (p != null) { p.objectReferenceValue = val; so.ApplyModifiedPropertiesWithoutUndo(); }
else Debug.LogWarning($" ⚠ campo '{field}' no encontrado en {comp.GetType().Name}");
}
static T FindComp<T>(string goName) where T : Component
{
var go = GameObject.Find(goName);
return go != null ? go.GetComponent<T>() : null;
}
static GameObject Path(string path)
{
var parts = path.Split('/');
var go = GameObject.Find(parts[0]);
if (go == null) return null;
for (int i = 1; i < parts.Length; i++)
{
var t = go.transform.Find(parts[i]);
if (t == null) return null;
go = t.gameObject;
}
return go;
}
static TextMeshProUGUI TMP(string path)
{
var go = Path(path);
return go != null ? go.GetComponent<TextMeshProUGUI>() : null;
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5a0d63a2787ce714c97977d8b26bd16d
+103
View File
@@ -0,0 +1,103 @@
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Collections.Generic;
/// <summary>
/// Verifica y muestra el estado completo del setup del proyecto.
/// </summary>
public class VerifySetup
{
public static void Execute()
{
Debug.Log("╔═══════════════════════════════════════════╗");
Debug.Log("║ VERIFICACIÓN DEL SETUP — AJEDREZ PURG. ║");
Debug.Log("╚═══════════════════════════════════════════╝");
CheckBuildSettings();
CheckScriptableObjects();
CheckPieceIdentities();
CheckChapter1Scene();
Debug.Log("══════════════════════════════════════════════");
}
static void CheckBuildSettings()
{
Debug.Log("── Build Settings:");
foreach (var scene in EditorBuildSettings.scenes)
{
string status = scene.enabled ? "✅" : "⚠ (disabled)";
Debug.Log($" {status} [{System.Array.IndexOf(EditorBuildSettings.scenes, scene)}] {scene.path}");
}
if (EditorBuildSettings.scenes.Length == 0)
Debug.LogWarning(" ⚠ No hay scenes en Build Settings!");
}
static void CheckScriptableObjects()
{
Debug.Log("── ScriptableObjects:");
Check("CampaignState", "Assets/Game/Data/Resources/CampaignState.asset");
Check("DeadKingPool", "Assets/Game/Data/Resources/DeadKingPool.asset");
Check("CampaignConfig", "Assets/Game/Data/CampaignConfig.asset");
Check("BalanceConfig", "Assets/Game/Data/BalanceConfig.asset");
}
static void CheckPieceIdentities()
{
Debug.Log("── PieceIdentity assets:");
var guids = AssetDatabase.FindAssets("t:PieceIdentity", new[]{"Assets/Game/Data/PieceIdentities"});
Debug.Log($" {'✅'} {guids.Length}/16 identidades creadas");
// Verificar asignadas en CampaignState
var cs = AssetDatabase.LoadAssetAtPath<CampaignState>("Assets/Game/Data/Resources/CampaignState.asset");
if (cs != null)
{
var so = new SerializedObject(cs);
var prop = so.FindProperty("_allIdentities");
if (prop != null)
Debug.Log($" {'✅'} CampaignState._allIdentities: {prop.arraySize} asignadas");
}
}
static void CheckChapter1Scene()
{
Debug.Log("── Chapter1 components (requiere abrir escena):");
// Forzar apertura si no está activa
var scene = UnityEditor.SceneManagement.EditorSceneManager.GetSceneByPath("Assets/Scenes/Chapter1.unity");
if (!scene.IsValid() || !scene.isLoaded)
{
scene = UnityEditor.SceneManagement.EditorSceneManager.OpenScene("Assets/Scenes/Chapter1.unity",
UnityEditor.SceneManagement.OpenSceneMode.Single);
}
CheckGO("GameManager", "GameManager");
CheckGO("BoardManager", "board");
CheckGO("DialogueSystem", "DialogueSystem");
CheckGO("DialogueUI", "DialogueCanvas");
CheckGO("GameHUD", "GameHUDCanvas");
CheckGO("PurgatoryManager", "PurgatoryManager");
CheckGO("PieceTooltipCanvas", "PieceTooltipCanvas");
CheckGO("PromotionCanvas", "PromotionCanvas");
CheckGO("PurgatoryCanvas", "PurgatoryCanvas");
CheckGO("PauseMenuCanvas", "PauseMenuCanvas");
CheckGO("CampaignManager", "CampaignManager");
CheckGO("SaveSystem", "SaveSystem");
CheckGO("AudioManager", "AudioManager");
CheckGO("PieceIdentityManager", "PieceIdentityManager");
CheckGO("SceneTransitionMgr", "SceneTransitionManager");
}
static void Check(string label, string path)
{
bool exists = File.Exists(path);
Debug.Log($" {(exists ? "" : "")} {label}: {path}");
}
static void CheckGO(string label, string goName)
{
var go = GameObject.Find(goName);
Debug.Log($" {(go != null ? "" : "")} {label}: {goName}");
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 176a6b29dacbf81428831b4e59ec74a4
@@ -177,6 +177,17 @@ public class CampaignManager : MonoBehaviour
}
}
// Configurar tablero con piezas disponibles según campaña
if (BoardManager.Instance != null && _campaignState != null)
{
BoardManager.Instance.SetupBoard(_campaignState);
Debug.Log($"[CampaignManager] Tablero configurado con piezas de la campaña.");
}
else
{
Debug.LogWarning("[CampaignManager] BoardManager o CampaignState no disponible. El tablero usará setup estándar.");
}
// Configurar IA según el capítulo
ApplyChapterAIConfiguration(chapter.aiConfig);
@@ -41,15 +41,46 @@ public class SceneTransitionManager : MonoBehaviour
private void InitializeFadeCanvas()
{
if (_fadeCanvasGroup != null)
// Auto-crear canvas si no está asignado en el Inspector
if (_fadeCanvasGroup == null)
{
_fadeCanvasGroup.alpha = 0f;
_fadeCanvasGroup.blocksRaycasts = false;
}
else
{
Debug.LogError("[SceneTransitionManager] CanvasGroup no está asignado.");
// Buscar CanvasGroup en hijos existentes
_fadeCanvasGroup = GetComponentInChildren<CanvasGroup>();
if (_fadeCanvasGroup == null)
{
// Crear FadeCanvas completo en runtime
var fadeCanvasGO = new GameObject("FadeCanvas");
fadeCanvasGO.transform.SetParent(transform, false);
var canvas = fadeCanvasGO.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = 999;
fadeCanvasGO.AddComponent<UnityEngine.UI.CanvasScaler>();
fadeCanvasGO.AddComponent<UnityEngine.UI.GraphicRaycaster>();
_fadeCanvasGroup = fadeCanvasGO.AddComponent<CanvasGroup>();
// Crear imagen de fade
var imgGO = new GameObject("FadeImage");
imgGO.transform.SetParent(fadeCanvasGO.transform, false);
_fadeImage = imgGO.AddComponent<Image>();
_fadeImage.color = Color.black;
var rt = imgGO.GetComponent<RectTransform>();
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = rt.offsetMax = Vector2.zero;
Debug.Log("[SceneTransitionManager] FadeCanvas creado automáticamente.");
}
}
// Si _fadeImage no está asignado, buscarlo en hijos
if (_fadeImage == null)
_fadeImage = GetComponentInChildren<Image>();
_fadeCanvasGroup.alpha = 0f;
_fadeCanvasGroup.blocksRaycasts = false;
}
/// <summary>
+1 -1
View File
@@ -17,4 +17,4 @@ public class SquareClick : MonoBehaviour
GameManager.Instance.TryMoveTo(position);
}
}
}
}
+22
View File
@@ -28,6 +28,28 @@ public class DialogueUI : MonoBehaviour
private Coroutine _blinkCoroutine;
private bool _isInputEnabled = false;
void Update()
{
// Fallback: Space, Enter o clic izquierdo cuando no hay InputAction asignada
if (!_isInputEnabled) return;
if (_advanceDialogueAction != null) return; // el InputAction ya maneja esto
if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Return) || Input.GetMouseButtonDown(0))
{
AdvanceOrComplete();
}
}
private void AdvanceOrComplete()
{
if (DialogueSystem.Instance == null) return;
if (DialogueSystem.Instance.IsTyping)
DialogueSystem.Instance.CompleteCurrentNode();
else
DialogueSystem.Instance.AdvanceDialogue();
}
void OnEnable()
{
// Suscribirse a eventos de DialogueSystem