Оптимальный способ подбора предметов в Unity 3d
Делаю небольшую игру. Пришло время создать систему предметов, которые будут выпадать в рандомных точках локации. Мне нужно, чтобы после подбора предмета он отображался на экране, чтобы игрок видел, что у него есть, например, броня, или, если игрок подбирает патроны, у него изменялось значение в соответствующей переменной. Мой способ реализации примерно такой:
- Сделать коллекцию item ов , присвоить им ID.
- Через скрипт игрока написать onTriggerEnter и в нем if ами прописывать. "Если ID предмета такой то - добавить, например, жизнь на экран или патроны Все бы ничего, но мне кажется, этот способ очень корявый, хоть и, наверное, самый простой. Есть что то оптимальнее?
Ответы (1 шт):
Правильный способ это всегда разделение на маленькие и простые ответственности. Например:
На игроке есть некий компонет
ItemPickerс единственным методомPick(PickableItem item)Подбираемый предмет сам реагирует на коллекторов как ему нужно, какие-то могут подбираться на расстоянии например патроны и валюта, к другим нужно близко подойти, например хилки. Предметы могут реагировать на
OnCollisionEnterили считать дистанцию или смешенный вариант для разных типов. Отдавая полномочия подбора коллектору закрываются возможности реализаций и навешивая сразу две ответственности.Соответственно на предмете несколько компонентов.
PickDetectorотвечает за фиксацию подбирания тем или иным способом после чего происходит событие передающееPickerи отключение. На событие может сработать компонент анимирующий полет до пикера, после чего передать пикеру компонентPickableItemкоторый может быть чем угодно.ItemPickerдолжен выступать в виде визитера (паттерн visitor). То-есть все предметы реализуют класс унаследованные отPickableItem, напримерPickableAmmoилиPickableHealth. МетодPickне совсем один, а имеет соответствующий набор перегрузокPick(PickableAmmo ammo),Pick(PickableHealth health)и в зависимости от типа он сработает необходимый или базовый для неопределенного перегрузкой предмета. Под каждый тип есть событияAction<AmmoType, int> PickedAmmo,Action<int> PickedHealthна которые и подписаны все заинтересованные не получая лишнего и даже не зная о существовании никакихPickableItem, а сразу конкретные значения, сколько хп или сколько амуниции T типа подобранно.
public abstact class PickableItem : MonoBehavour
{ }
public enum AmmoType { Pistol, Rifle, Shotgun }
public class PickableAmmo : PickableItem
{
public AmmoType Type;
public int Amount;
}
public class PickableHealth : PickableItem
{
public int Amount;
}
Итого 4 ответственности:
ItemPickerсообщает о подобранном в отсортированном виде для разных подписчиковPickDetectorотвечающий за подборPickAnimationотвечающий за полет до пикера или просто эффект вспышки символизирующий подбирание. (опционально)PickableItemи его наследники содержащие информацию о том что находится в подобранном предмете.