using UnityEngine; [CreateAssetMenu(fileName = "GamePrefabs", menuName = "Gatherer of Souls/Game Prefabs")] public class GamePrefabs : ScriptableObject { [Header("Core Prefabs")] public GameObject villagerPrefab; public GameObject townHallPrefab; [Header("Resource Nodes")] public GameObject treePrefab; public GameObject stonePrefab; public GameObject farmPrefab; [Header("Buildings")] public GameObject storagePrefab; public GameObject lumberMillPrefab; public GameObject quarryPrefab; public GameObject housePrefab; [Header("Materials")] public Material villagerMaterial; public Material ghostMaterial; public Material selectionMaterial; [Header("UI")] public GameObject uiCanvasPrefab; } public class PrefabManager : MonoBehaviour { public static PrefabManager Instance { get; private set; } [Header("Prefab Data")] public GamePrefabs gamePrefabs; void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } public GameObject CreateVillager(Vector3 position, string villagerName = "") { GameObject villagerGO; if (gamePrefabs?.villagerPrefab != null) { villagerGO = Instantiate(gamePrefabs.villagerPrefab, position, Quaternion.identity); } else { // Fallback creation villagerGO = CreateBasicVillager(position); } Villager villager = villagerGO.GetComponent(); if (villager != null && !string.IsNullOrEmpty(villagerName)) { villager.villagerName = villagerName; } return villagerGO; } GameObject CreateBasicVillager(Vector3 position) { GameObject villagerGO = GameObject.CreatePrimitive(PrimitiveType.Capsule); villagerGO.name = "Villager"; villagerGO.tag = "Villager"; villagerGO.transform.position = position; // Add Villager component Villager villager = villagerGO.AddComponent(); // Apply material if available if (gamePrefabs?.villagerMaterial != null) { villagerGO.GetComponent().material = gamePrefabs.villagerMaterial; } // Create selection indicator GameObject indicator = GameObject.CreatePrimitive(PrimitiveType.Cylinder); indicator.transform.SetParent(villagerGO.transform); indicator.transform.localPosition = Vector3.down * 0.6f; indicator.transform.localScale = Vector3.one * 1.2f; indicator.GetComponent().material.color = Color.yellow; indicator.SetActive(false); villager.selectionIndicator = indicator; Destroy(indicator.GetComponent()); return villagerGO; } public GameObject CreateTownHall(Vector3 position) { GameObject townHallGO; if (gamePrefabs?.townHallPrefab != null) { townHallGO = Instantiate(gamePrefabs.townHallPrefab, position, Quaternion.identity); } else { // Fallback creation townHallGO = CreateBasicTownHall(position); } return townHallGO; } GameObject CreateBasicTownHall(Vector3 position) { GameObject townHallGO = GameObject.CreatePrimitive(PrimitiveType.Cube); townHallGO.name = "TownHall"; townHallGO.tag = "TownHall"; townHallGO.transform.position = position; townHallGO.transform.localScale = new Vector3(3f, 2f, 3f); // Add TownHall component TownHall townHall = townHallGO.AddComponent(); // Set material color townHallGO.GetComponent().material.color = Color.blue; // Create selection indicator GameObject indicator = GameObject.CreatePrimitive(PrimitiveType.Cylinder); indicator.transform.SetParent(townHallGO.transform); indicator.transform.localPosition = Vector3.down * 1.2f; indicator.transform.localScale = Vector3.one * 1.5f; indicator.GetComponent().material.color = Color.yellow; indicator.SetActive(false); townHall.selectionIndicator = indicator; Destroy(indicator.GetComponent()); return townHallGO; } public GameObject CreateResourceNode(ResourceNodeType nodeType, Vector3 position) { GameObject nodePrefab = nodeType switch { ResourceNodeType.Tree => gamePrefabs?.treePrefab, ResourceNodeType.Stone => gamePrefabs?.stonePrefab, ResourceNodeType.Farm => gamePrefabs?.farmPrefab, _ => null }; GameObject nodeGO; if (nodePrefab != null) { nodeGO = Instantiate(nodePrefab, position, Quaternion.identity); } else { nodeGO = CreateBasicResourceNode(nodeType, position); } return nodeGO; } GameObject CreateBasicResourceNode(ResourceNodeType nodeType, Vector3 position) { GameObject nodeGO; ResourceNode node; switch (nodeType) { case ResourceNodeType.Tree: nodeGO = GameObject.CreatePrimitive(PrimitiveType.Cylinder); nodeGO.transform.localScale = new Vector3(1f, 2f, 1f); nodeGO.GetComponent().material.color = Color.green; nodeGO.name = "Tree"; nodeGO.tag = "Tree"; node = nodeGO.AddComponent(); node.nodeType = ResourceNodeType.Tree; node.resourceType = ResourceType.Wood; node.maxResources = 50; node.currentResources = 50; node.regenerationRate = 2f; break; case ResourceNodeType.Stone: nodeGO = GameObject.CreatePrimitive(PrimitiveType.Sphere); nodeGO.transform.localScale = Vector3.one * 1.5f; nodeGO.GetComponent().material.color = Color.gray; nodeGO.name = "Stone"; nodeGO.tag = "Stone"; node = nodeGO.AddComponent(); node.nodeType = ResourceNodeType.Stone; node.resourceType = ResourceType.Stone; node.maxResources = 75; node.currentResources = 75; node.regenerationRate = 0.5f; break; case ResourceNodeType.Farm: nodeGO = GameObject.CreatePrimitive(PrimitiveType.Cube); nodeGO.transform.localScale = new Vector3(2f, 0.2f, 2f); nodeGO.GetComponent().material.color = Color.yellow; nodeGO.name = "Farm"; nodeGO.tag = "Farm"; node = nodeGO.AddComponent(); node.nodeType = ResourceNodeType.Farm; node.resourceType = ResourceType.Food; node.maxResources = 100; node.currentResources = 100; node.regenerationRate = 3f; break; default: return null; } nodeGO.transform.position = position; // Create selection indicator CreateSelectionIndicatorForNode(nodeGO, node); return nodeGO; } void CreateSelectionIndicatorForNode(GameObject parent, ResourceNode node) { GameObject indicator = GameObject.CreatePrimitive(PrimitiveType.Cylinder); indicator.transform.SetParent(parent.transform); indicator.transform.localPosition = Vector3.down * 0.6f; indicator.transform.localScale = Vector3.one * 1.2f; if (gamePrefabs?.selectionMaterial != null) { indicator.GetComponent().material = gamePrefabs.selectionMaterial; } else { indicator.GetComponent().material.color = Color.cyan; } indicator.SetActive(false); node.selectionIndicator = indicator; Destroy(indicator.GetComponent()); } public Material GetGhostMaterial() { return gamePrefabs?.ghostMaterial; } }