using UnityEngine; using System.Collections.Generic; /// /// Centralized system for managing character prefabs and names. /// This singleton can be used across the entire game to load character prefabs /// and translate between prefab names and character display names. /// public class CharacterPrefabManager : MonoBehaviour { #region Singleton private static CharacterPrefabManager _instance; public static CharacterPrefabManager Instance { get { if (_instance == null) { GameObject go = new GameObject("CharacterPrefabManager"); _instance = go.AddComponent(); DontDestroyOnLoad(go); _instance.Initialize(); } return _instance; } } #endregion // Character display names (uppercase for UI display) public enum CharacterName { WINDHAM, AMIRA, BAHMAN, ZIGGY, AMON, IMANI, ZIGGY_NEW } // Dictionary mapping character names to prefab resource paths private Dictionary playerPrefabPaths = new Dictionary(); private Dictionary aiPrefabPaths = new Dictionary(); // Dictionary mapping GameObject clone names to character names private Dictionary gameObjectToCharacterName = new Dictionary(); private void Initialize() { // Setup player prefab paths playerPrefabPaths[CharacterName.WINDHAM] = "RabbitNew"; playerPrefabPaths[CharacterName.AMIRA] = "CheetahNew"; playerPrefabPaths[CharacterName.BAHMAN] = "EagleNew"; playerPrefabPaths[CharacterName.ZIGGY] = "CatNewPrefab"; playerPrefabPaths[CharacterName.AMON] = "HMNew"; playerPrefabPaths[CharacterName.IMANI] = "HyenaNew"; // Setup AI prefab paths - NOW USES SAME UNIFIED PREFABS AS PLAYER // The modular architecture means we use ONE prefab per character // and configure behavior (player vs AI) at runtime via component enable/disable aiPrefabPaths[CharacterName.WINDHAM] = "RabbitNewAI"; // No longer "Rabbit Enemy" aiPrefabPaths[CharacterName.AMIRA] = "CheetahNewAI"; // No longer "Cheetah Enemy" aiPrefabPaths[CharacterName.BAHMAN] = "EagleNewAI"; // No longer "Eagle Enemy" aiPrefabPaths[CharacterName.ZIGGY] = "CatNewAI"; // No longer "Cat Enemy" aiPrefabPaths[CharacterName.AMON] = "HMNewAI"; // No longer "HM Enemy" aiPrefabPaths[CharacterName.IMANI] = "HyenaNewAI"; // No longer "Hyena Enemy" // Setup GameObject name mapping MapCloneNamesToCharacters(); } private void MapCloneNamesToCharacters() { // Player prefabs gameObjectToCharacterName["Rabbit(Clone)"] = CharacterName.WINDHAM; // gameObjectToCharacterName["Rabbit 2(Clone)"] = CharacterName.WINDHAM; gameObjectToCharacterName["Cheetah(Clone)"] = CharacterName.AMIRA; // gameObjectToCharacterName["Cheetah 2(Clone)"] = CharacterName.AMIRA; gameObjectToCharacterName["Eagle(Clone)"] = CharacterName.BAHMAN; gameObjectToCharacterName["Cat(Clone)"] = CharacterName.ZIGGY; gameObjectToCharacterName["HM(Clone)"] = CharacterName.AMON; gameObjectToCharacterName["Hyena(Clone)"] = CharacterName.IMANI; // AI prefabs gameObjectToCharacterName["Rabbit Enemy(Clone)"] = CharacterName.WINDHAM; // gameObjectToCharacterName["Rabbit Enemy 2(Clone)"] = CharacterName.WINDHAM; gameObjectToCharacterName["Cheetah Enemy(Clone)"] = CharacterName.AMIRA; // gameObjectToCharacterName["Cheetah Enemy 2(Clone)"] = CharacterName.AMIRA; gameObjectToCharacterName["Eagle Enemy(Clone)"] = CharacterName.BAHMAN; gameObjectToCharacterName["Cat Enemy(Clone)"] = CharacterName.ZIGGY; gameObjectToCharacterName["HM Enemy(Clone)"] = CharacterName.AMON; gameObjectToCharacterName["Hyena Enemy(Clone)"] = CharacterName.IMANI; } /// /// Get the prefab for a character based on name and mode /// /// The character to load /// Whether to load the AI version /// The loaded prefab GameObject public GameObject GetCharacterPrefab(CharacterName characterName, bool isAI = false) { string prefabPath = isAI ? aiPrefabPaths[characterName] : playerPrefabPaths[characterName]; GameObject prefab = Resources.Load(prefabPath); if (prefab == null) { Debug.LogError($"Failed to load character prefab: {characterName} (AI: {isAI})"); } return prefab; } /// /// Get the prefab for a character based on string name and mode /// /// The string name of the character /// Whether to load the AI version /// The loaded prefab GameObject public GameObject GetCharacterPrefab(string characterName, bool isAI = false) { if (TryParseCharacterName(characterName, out CharacterName parsedName)) { return GetCharacterPrefab(parsedName, isAI); } Debug.LogError($"Invalid character name: {characterName}"); return null; } /// /// Try to parse a string character name (case insensitive) to a CharacterName enum /// public bool TryParseCharacterName(string nameString, out CharacterName characterName) { // Normalize input to uppercase and remove spaces string normalizedName = nameString.ToUpper().Replace(" ", "_"); // Try to parse as enum if (System.Enum.TryParse(normalizedName, out characterName)) { return true; } characterName = CharacterName.WINDHAM; // Default return false; } /// /// Get the character name from a GameObject (useful for clones) /// /// The GameObject to identify /// The character's display name as a string public string GetCharacterDisplayName(GameObject gameObject) { if (gameObject == null) return string.Empty; if (gameObjectToCharacterName.TryGetValue(gameObject.name, out CharacterName characterName)) { return characterName.ToString().Replace("_", " "); } // If we can't find it directly, try to be smarter about it by checking if it contains character names string objName = gameObject.name.ToUpper(); foreach (CharacterName name in System.Enum.GetValues(typeof(CharacterName))) { string nameStr = name.ToString(); if (objName.Contains(nameStr.Replace("_", " ")) || objName.Contains(nameStr)) { return nameStr.Replace("_", " "); } } Debug.LogWarning($"Unknown character GameObject: {gameObject.name}"); return gameObject.name; } /// /// Check if a GameObject is a valid character prefab /// public bool IsValidCharacter(GameObject gameObject) { if (gameObject == null) return false; return gameObjectToCharacterName.ContainsKey(gameObject.name) || FindMatchingCharacterName(gameObject.name) != null; } private string FindMatchingCharacterName(string objectName) { string upperName = objectName.ToUpper(); // Check each character name foreach (CharacterName name in System.Enum.GetValues(typeof(CharacterName))) { string nameStr = name.ToString(); if (upperName.Contains(nameStr.Replace("_", " ")) || upperName.Contains(nameStr)) { return nameStr; } } return null; } }