Перейти к содержанию

Конвертация предметов

Эта страница объясняет, как переносить предметы между инвентарями, если они используют разные модели данных.

Пример: торговец хранит товар как ScriptableObject, игрок хранит купленный предмет как runtime-модель, а экипировка использует фиксированные слоты со своими проверками.

Когда нужен converter

Converter нужен, если предмет должен перейти из одного типа adapter-а в другой.

Типичные случаи:

  • торговец и игрок хранят предметы в разных моделях
  • инвентарь экипировки принимает только специальные adapter-ы
  • контейнер внутри предмета хранит runtime-экземпляры
  • один и тот же предмет должен выглядеть по-разному в разных инвентарях

Если оба инвентаря используют один и тот же adapter-тип, converter обычно не нужен.

Где его настраивать

Converter задаётся в binding-е:

protected override IItemAdapterConverter CreateItemConverter()
{
    return new MyItemAdapterConverter();
}

Binding тем самым говорит системе:

  • как предметы из этого инвентаря выглядят при выходе наружу
  • как предметы должны выглядеть, когда попадают в этот инвентарь

Если converter не задан, используется поведение “оставить как есть”.

Простая модель

Когда предмет переносится из одного инвентаря в другой, система должна получить adapter, который понятен целевому инвентарю.

adapter исходного инвентаря
  -> converter
  -> adapter целевого инвентаря

Главная цель converter-а — не потерять смысл предмета при переходе между моделями данных.

Что converter должен сохранить

Если предметы уникальные, converter должен переносить не только картинку и имя.

Проверьте, что сохраняются:

  • ItemId, если он влияет на stacking
  • количество предметов в стеке
  • уникальное состояние экземпляра
  • ссылка на доменную модель, если предмет не просто ScriptableObject
  • данные, которые нужны для CanDrop, tooltip, цены, редкости или экипировки

Если после переноса “предмет выглядит правильно, но больше не перетаскивается”, чаще всего целевой слот получил adapter не того типа или без нужных данных.

Swap между разными инвентарями

Swap между разными типами инвентарей — это не простая замена двух стеков местами.

Каждый предмет должен быть приведён к модели того инвентаря, куда он попадёт:

предмет A -> модель инвентаря B
предмет B -> модель инвентаря A

Если просто поменять местами два adapter-а, следующий drag/drop может сломаться, потому что слот будет хранить предмет в чужом формате.

Когда возвращать null

Converter может вернуть null, если предмет нельзя безопасно перевести в нужную модель.

Это уместно, если:

  • предмет не должен попадать в этот инвентарь
  • невозможно создать adapter целевого типа
  • при конвертации потеряются важные данные

Не используйте null для временных запретов вроде “не хватает денег” или “магазин закрыт”. Для этого лучше использовать rules или ITransferDomainHandler.

Типичные ошибки

После переноса появляется Неверный тип предмета

Проверьте:

  • реализован ли CreateItemConverter()
  • возвращает ли converter adapter целевого инвентаря
  • не остался ли в слоте adapter исходного инвентаря

Первый swap работает, второй ломается

Проверьте:

  • есть ли конвертация в обе стороны
  • не обмениваются ли два стека напрямую без converter-а
  • какой adapter лежит в каждом слоте после первого swap

Данные предмета потерялись

Проверьте:

  • переносится ли runtime-состояние экземпляра
  • не создаёте ли вы все предметы стека из одного adapter-а
  • не теряются ли цена, редкость, прочность, владелец или другие поля вашей модели

Чеклист для нового converter-а

  • source и target инвентари действительно используют разные adapter-типы
  • binding переопределяет CreateItemConverter()
  • converter создаёт adapter того типа, который ожидает целевой инвентарь
  • каждый уникальный предмет сохраняет своё состояние
  • swap проверен в обе стороны
  • после переноса следующий drag/drop из целевого слота работает

См. также: