Грамотность реализации
У меня в игре есть класс Properties, в котором хранятся публичные статические свойства (монеты и так далее), так как надо много данных сохранять на сервер (для системы аккаунтов) и сокращения PlayerPrefs'ов. Корректно ли так делать?
Ответы (1 шт):
Валюту грамотно держать в кошельке.
public class Currency
{
public const string Gold = "gold";
public const string Diamond = "diamond";
}
Wallet wallet = new Wallet();
wallet[Currency.Gold] += 100;
wallet[Currency.Diamond] += 10;
wallet[Currency.Gold] -= 20;
wallet["grayCoin"] += 30;
Debug.Log(wallet);
// gold: 80, diamond: 10, grayCoin: 30
public class Wallet
{
public event Action<string, int> Changed;
private Dictionary<string, int> _currencys = new Dictionary<string, int>();
public int this[string currency]
{
get => GetCurrencyAmout(currency);
set => SetCurrencyAmout(currency, value);
}
public override string ToString () =>
GetCurrencyData();
public int GetCurrencyAmout (string currency)
{
if (_currencys.ContainsKey(currency))
return _currencys[currency];
return 0;
}
public void SetCurrencyAmout (string currency, int amout)
{
if (_currencys.ContainsKey(currency) == false)
_currencys.Add(currency, 0);
int newAmout = Math.Max(0, amout);
if (_currencys[currency] != newAmout)
{
_currencys[currency] = newAmout;
Changed?.Invoke(currency, newAmout);
}
}
public string GetSaveData () =>
JsonUtility.ToJson(GetCurrencyData());
public void LoadData (string json)
{
CurrencyDataCollection currencysCollection = JsonUtility.FromJson<CurrencyDataCollection>(json);
_currencys.Clear();
foreach (CurrencyData currency in currencysCollection.Currencys)
SetCurrency(currency.name, currency.value);
}
private CurrencyDataCollection GetCurrencyData () =>
new CurrencyDataCollection(_currencys.Select(c => new CurrencyData(c.Key, c.Value)));
}
[Serializable]
public struct CurrencyData
{
public string name;
public int amout;
public CurrencyData (string name, int amout)
{
this.name = name;
this.amout = amout;
}
public override string ToString () =>
string.Format("{0}: {1}", name, amout);
}
[Serializable]
public struct CurrencyDataCollection
{
public CurrencyData[] Currencys;
public CurrencyDataCollection (IEnumerable<CurrencyData> currencys) =>
Currencys = currencys.ToArray();
public override string ToString () =>
string.Join(", ", Currencys);
}
В C# статика это инструмент для расширения (extension). Singleton это просто костыль, для тех, кто не умеет создавать архитектуру. static class это для тех, кто вообще ничего не умеет.
Мало того, что класс не должен быть статикой, обработчик и данные для хранения должны быть двумя разными сущьностями, что бы одно можно было скармливать другому (паттерн Memento). Причём данные должны быть легко сериализуемыми, то есть строка или структура.
То как нуждающиеся в этом объекты, получат ссылку на wallet, это тема выстраивания зависимостей и архитектуры. Можно просто польоваться каким-нибудь Zenject.