206 lines
8.0 KiB
C#
206 lines
8.0 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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<CharacterPrefabManager>();
|
|
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<CharacterName, string> playerPrefabPaths = new Dictionary<CharacterName, string>();
|
|
private Dictionary<CharacterName, string> aiPrefabPaths = new Dictionary<CharacterName, string>();
|
|
|
|
// Dictionary mapping GameObject clone names to character names
|
|
private Dictionary<string, CharacterName> gameObjectToCharacterName = new Dictionary<string, CharacterName>();
|
|
|
|
private void Initialize()
|
|
{
|
|
// Setup player prefab paths
|
|
playerPrefabPaths[CharacterName.WINDHAM] = "Rabbit";
|
|
playerPrefabPaths[CharacterName.AMIRA] = "Cheetah";
|
|
playerPrefabPaths[CharacterName.BAHMAN] = "Eagle";
|
|
playerPrefabPaths[CharacterName.ZIGGY] = "Cat";
|
|
playerPrefabPaths[CharacterName.AMON] = "HM";
|
|
playerPrefabPaths[CharacterName.IMANI] = "Hyena";
|
|
|
|
// 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] = "Rabbit"; // No longer "Rabbit Enemy"
|
|
aiPrefabPaths[CharacterName.AMIRA] = "Cheetah"; // No longer "Cheetah Enemy"
|
|
aiPrefabPaths[CharacterName.BAHMAN] = "Eagle"; // No longer "Eagle Enemy"
|
|
aiPrefabPaths[CharacterName.ZIGGY] = "Cat"; // No longer "Cat Enemy"
|
|
aiPrefabPaths[CharacterName.AMON] = "HM"; // No longer "HM Enemy"
|
|
aiPrefabPaths[CharacterName.IMANI] = "Hyena"; // 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the prefab for a character based on name and mode
|
|
/// </summary>
|
|
/// <param name="characterName">The character to load</param>
|
|
/// <param name="isAI">Whether to load the AI version</param>
|
|
/// <returns>The loaded prefab GameObject</returns>
|
|
public GameObject GetCharacterPrefab(CharacterName characterName, bool isAI = false)
|
|
{
|
|
string prefabPath = isAI ? aiPrefabPaths[characterName] : playerPrefabPaths[characterName];
|
|
GameObject prefab = Resources.Load<GameObject>(prefabPath);
|
|
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogError($"Failed to load character prefab: {characterName} (AI: {isAI})");
|
|
}
|
|
|
|
return prefab;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the prefab for a character based on string name and mode
|
|
/// </summary>
|
|
/// <param name="characterName">The string name of the character</param>
|
|
/// <param name="isAI">Whether to load the AI version</param>
|
|
/// <returns>The loaded prefab GameObject</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Try to parse a string character name (case insensitive) to a CharacterName enum
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the character name from a GameObject (useful for clones)
|
|
/// </summary>
|
|
/// <param name="gameObject">The GameObject to identify</param>
|
|
/// <returns>The character's display name as a string</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if a GameObject is a valid character prefab
|
|
/// </summary>
|
|
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;
|
|
}
|
|
} |