107 lines
4.2 KiB
C#
107 lines
4.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
|
||
// Центральное хранилище всех ресурсов игрока.
|
||
// Один объект на сцену (Singleton) -- любой скрипт обращается через ResourceManager.Instance
|
||
|
||
public enum ResourceType
|
||
{
|
||
Population = 0, // люди
|
||
Food = 1, // еда
|
||
Wood = 2, // дерево
|
||
Stone = 3, // камень
|
||
Iron = 4, // металл
|
||
Gold = 5, // золото
|
||
Gems = 6, // кристаллы
|
||
Power = 7 // "сила" -- как в референсе HUD
|
||
}
|
||
|
||
public class ResourceManager : MonoBehaviour
|
||
{
|
||
public static ResourceManager Instance { get; private set; }
|
||
|
||
// Событие: вызывается каждый раз, когда любой ресурс меняется.
|
||
// UI подписывается на него, чтобы обновлять текст автоматически, без Update() каждый кадр.
|
||
public event Action<ResourceType, float> OnResourceChanged;
|
||
|
||
[Header("Стартовые значения (для теста/баланса)")]
|
||
public float startWood = 0f;
|
||
public float startStone = 0f;
|
||
public float startIron = 0f;
|
||
public float startFood = 0f;
|
||
public float startGold = 0f;
|
||
public float startGems = 0f;
|
||
public float startPower = 0f;
|
||
public float startPopulation = 0f;
|
||
|
||
private Dictionary<ResourceType, float> resources = new Dictionary<ResourceType, float>();
|
||
|
||
void Awake()
|
||
{
|
||
// Классический паттерн Singleton: если уже есть экземпляр -- уничтожаем дубликат
|
||
if (Instance != null && Instance != this)
|
||
{
|
||
Destroy(gameObject);
|
||
return;
|
||
}
|
||
Instance = this;
|
||
DontDestroyOnLoad(gameObject); // менеджер ресурсов должен жить между сценами (меню -> игра)
|
||
|
||
resources[ResourceType.Wood] = startWood;
|
||
resources[ResourceType.Stone] = startStone;
|
||
resources[ResourceType.Iron] = startIron;
|
||
resources[ResourceType.Food] = startFood;
|
||
resources[ResourceType.Gold] = startGold;
|
||
resources[ResourceType.Gems] = startGems;
|
||
resources[ResourceType.Power] = startPower;
|
||
resources[ResourceType.Population] = startPopulation;
|
||
}
|
||
|
||
// Добавить ресурс (можно и отрицательное число -- для трат)
|
||
public void AddResource(ResourceType type, float amount)
|
||
{
|
||
if (!resources.ContainsKey(type))
|
||
resources[type] = 0f;
|
||
|
||
resources[type] += amount;
|
||
if (resources[type] < 0f) resources[type] = 0f; // ресурс не уходит в минус
|
||
|
||
OnResourceChanged?.Invoke(type, resources[type]);
|
||
}
|
||
|
||
// Проверить, хватает ли ресурса (для трат/построек в будущем)
|
||
public bool HasEnough(ResourceType type, float amount)
|
||
{
|
||
return GetResource(type) >= amount;
|
||
}
|
||
|
||
// Попробовать потратить -- вернёт false, если не хватило (и ничего не спишет)
|
||
public bool TrySpend(ResourceType type, float amount)
|
||
{
|
||
if (!HasEnough(type, amount)) return false;
|
||
AddResource(type, -amount);
|
||
return true;
|
||
}
|
||
|
||
public float GetResource(ResourceType type)
|
||
{
|
||
return resources.TryGetValue(type, out float value) ? value : 0f;
|
||
}
|
||
|
||
// Устанавливает значение напрямую, БЕЗ проверок и без учёта прошлого значения.
|
||
// Используется только при загрузке сохранения -- обычная игровая логика должна
|
||
// использовать AddResource/TrySpend, а не этот метод.
|
||
public void SetResource(ResourceType type, float value)
|
||
{
|
||
resources[type] = value;
|
||
OnResourceChanged?.Invoke(type, value);
|
||
}
|
||
|
||
// Все ресурсы разом -- удобно для сохранения
|
||
public Dictionary<ResourceType, float> GetAllResources()
|
||
{
|
||
return new Dictionary<ResourceType, float>(resources);
|
||
}
|
||
}
|