123 lines
3.8 KiB
C#
123 lines
3.8 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
// Управляет режимом строительства: показывает "призрак" здания под курсором,
|
|
// проверяет ресурсы, спавнит здание в подтверждённой позиции.
|
|
|
|
public class BuildManager : MonoBehaviour
|
|
{
|
|
public static BuildManager Instance { get; private set; }
|
|
|
|
[Header("Все типы зданий в игре")]
|
|
public List<BuildingData> allBuildings;
|
|
|
|
[Header("Визуал 'призрака' здания при размещении")]
|
|
public Color validPlacementColor = new Color(1, 1, 1, 0.6f);
|
|
public Color invalidPlacementColor = new Color(1, 0.3f, 0.3f, 0.6f);
|
|
|
|
private BuildingData currentlyPlacing;
|
|
private GameObject ghostObject;
|
|
private Camera mainCam;
|
|
|
|
void Awake()
|
|
{
|
|
if (Instance != null && Instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
Instance = this;
|
|
mainCam = Camera.main;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (currentlyPlacing == null || ghostObject == null)
|
|
return;
|
|
|
|
Vector3 worldPos = GetPointerWorldPosition();
|
|
worldPos.z = 0;
|
|
ghostObject.transform.position = worldPos;
|
|
|
|
bool canAfford = currentlyPlacing.CanAfford();
|
|
SpriteRenderer sr = ghostObject.GetComponent<SpriteRenderer>();
|
|
if (sr != null)
|
|
sr.color = canAfford ? validPlacementColor : invalidPlacementColor;
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
TryConfirmPlacement(worldPos);
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape))
|
|
{
|
|
CancelPlacement();
|
|
}
|
|
}
|
|
|
|
// Список зданий, доступных для стройки ПРЯМО СЕЙЧАС (по уровню Ратуши)
|
|
public List<BuildingData> GetAvailableBuildings()
|
|
{
|
|
List<BuildingData> available = new List<BuildingData>();
|
|
int townHallLevel = TownHall.Instance != null ? TownHall.Instance.currentLevel : 1;
|
|
|
|
foreach (var b in allBuildings)
|
|
{
|
|
if (b.requiredTownHallLevel <= townHallLevel)
|
|
available.Add(b);
|
|
}
|
|
return available;
|
|
}
|
|
|
|
// Вызывается из UI-кнопки конкретного здания в меню стройки
|
|
public void StartPlacing(BuildingData data)
|
|
{
|
|
if (currentlyPlacing != null)
|
|
{
|
|
CancelPlacement();
|
|
}
|
|
|
|
currentlyPlacing = data;
|
|
|
|
ghostObject = Instantiate(data.prefab);
|
|
// Отключаем на "призраке" всё, что мешает (коллайдер, скрипты сбора ресурсов и т.д.)
|
|
Collider2D col = ghostObject.GetComponent<Collider2D>();
|
|
if (col != null) col.enabled = false;
|
|
|
|
MonoBehaviour[] scripts = ghostObject.GetComponents<MonoBehaviour>();
|
|
foreach (var s in scripts)
|
|
{
|
|
s.enabled = false;
|
|
}
|
|
}
|
|
|
|
void TryConfirmPlacement(Vector3 position)
|
|
{
|
|
if (!currentlyPlacing.CanAfford())
|
|
{
|
|
Debug.Log("[СТРОЙКА] Не хватает ресурсов!");
|
|
return;
|
|
}
|
|
|
|
currentlyPlacing.PayCost();
|
|
|
|
GameObject built = Instantiate(currentlyPlacing.prefab, position, Quaternion.identity);
|
|
Debug.Log($"[СТРОЙКА] Построено: {currentlyPlacing.buildingName} в {position}");
|
|
|
|
Destroy(ghostObject);
|
|
currentlyPlacing = null;
|
|
}
|
|
|
|
void CancelPlacement()
|
|
{
|
|
if (ghostObject != null) Destroy(ghostObject);
|
|
currentlyPlacing = null;
|
|
Debug.Log("[СТРОЙКА] Размещение отменено.");
|
|
}
|
|
|
|
Vector3 GetPointerWorldPosition()
|
|
{
|
|
Vector3 screenPos = Input.mousePosition;
|
|
return mainCam.ScreenToWorldPoint(screenPos);
|
|
}
|
|
} |