У меня есть некий кошелек, в котором пока что есть только монетки и ключи для сундуков. На данный момент player выглядит вот так:
private Wallet _wallet;
public event UnityAction<int> CoinsCountChanged;
public event UnityAction<int> KeysCountChanged;
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.TryGetComponent<Resource>(out Resource resource))
{
if (resource is Coin)
{
_wallet.AddCoin((Coin)resource);
CoinsCountChanged?.Invoke(_wallet.Coins);
}
else if (resource is Key)
{
_wallet.AddKey((Key)resource);
KeysCountChanged?.Invoke(_wallet.Keys);
}
Destroy(collision.gameObject);
}
}
Key и Coin наследуются от Resource, и сам кошелек, который имеет 2 свойства и 2 метода добавления каждого из ресурсов. Если бы я хотел иметь много ресурсов, например разные типы кристаллов, монет и ключей, мне бы пришлось для каждого ресурса писать свой иф, создавать событие под него и метод в кошельке. Тогда OnTriggerEnter превратился бы в сплошной копипаст. Есть идея закинуть эту проверку в кошелек, но тогда его нужно будет делать пабликом, что бы подписаться на событие для вывода. Да и не совсем логично когда ресурс определяет кошелек а не плеер. Есть более логичная, но и затратная идея, передавать в кошелек Resource, а в кошельке создать и перегрузить метод на разные типы ресурсов. Но опять же вопрос, как определить что это за ресурс? Может есть идея как это реализовать лучше?
public enum ResourseTypes { Gold, Key, Wood, Rock }
// вешаем на игрока
[DisallowMultipleComponent]
public class ResourseStash : MonoBehaviour {
public event Action<ResourseTypes, int> ResourseAddes;
public event Action<ResourseTypes, int> ResourseSpended;
public event Action<ResourseTypes, int> ResourseChanged;
private Dictionary<ResourseTypes, int> _resourses;
private void Awake () {
_resourses = new Dictionary<ResourseTypes, int>();
}
public int Count (ResourseTypes type) {
return _resourses.ContainsKey(type) ? _resourses[type] : 0;
}
public void AddResourse (ResourseTypes type, int count) {
if (_resourses.ContainsKey(type) == false)
_resourses.Add(type, 0);
_resourses[type] += count;
if (ResourseAddes != null)
ResourseAddes.Invoke(type, count);
if (ResourseChanged != null)
ResourseChanged.Invoke(type, _resourses[type]);
}
public bool TrySpendResourse (ResourseTypes type, int count) {
if (_resourses.ContainsKey(type) != false && _resourses[type] >= count) {
_resourses[type] -= count;
if (ResourseSpended != null)
ResourseSpended.Invoke(type, count);
if (ResourseChanged != null)
ResourseChanged.Invoke(type, _resourses[type]);
return true;
} else {
Debug.Log("Does not have "+count+" "+type.ToString());
return false;
}
}
}
[DisallowMultipleComponent]
[RequireComponent(typeof(Collider))]
public class CollectableResourse : MonoBehaviour {
[SerializeField] private ResourseTypes _type;
[SerializeField] private int _count;
// ресурс сам подберётся столкнувшись с носителем ресурсов
// или можно прописать в ResourseStash, на вкус
private void OnCollisionEnter (Collider2D collision) {
if (collision.gameObject.TryGetComponent<ResourseStash>(out ResourseStash stash)) {
stash.AddResourse(_type, _count);
Destroy(gameObject);
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Собственно вопрос в тайтлеЧто я хочу: единый формат ответов от API как у VK
У меня есть проект AspNet core 2
У меня есть структура, в которой есть поле Mod, высчитываемое при инициализации: