24 декабря Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!
Помогите советом - создание инвентаря Unreal Engine
Как правильно организовать архитектуру? Делаю "бесконечный" инвентарь, слоты создаются налету, когда подбирается предмет. Суть в том, что в роли этого предмета могут выступать многие разные вещи - оружие, материалы, заклинания и т.д, у всех свои разные структуры характеристик, но есть и общее, например у всего есть цена, иконка как минимум. Что я сделал: 1. создал ItemParent, в котором описал структуру общих свойств для всех предметов; 2. создал ActorComponent для инвентаря, тип map из ItemParent Class + integer; 3. Из ItemParent сделал child-блюпринт-классы, в которых в виде переменных поместил дополнительные структуры, описывающие базовые характеристики этих классов - weapon, spell и т.д. Из него уже создаю сами предметы; 4. Нарисовал виджет слота в инвентаре, и через обращение к классу ItemParent в preconstruct могу в нем отрисовать иконку, количество единиц в инвентаре, цену и то, что мне нужно.
Застрял на том, что добавил к слоту кнопку, по нажатии на которой мне нужно например вытащить текстовую информацию именно содержимого слота, предмета который в нем лежит. Как правильно обратиться к содержимому? В зависимости от того, какой класс предмета там лежит, будут отличаться как минимум названия полей.. что-то я не могу сообразить. Как это правильно делается?
И вот типа тут в Graph у InventorySlot я могу обратиться например к родительскому классу ItemParent, и вернуть оттуда что угодно - количество, цену, иконку - но не то, что мне нужно, а мне нужно обратиться к структуре и значениям дочернего Item'а, как это блин сделать?
>>747039 >как это блин сделать? Виртуальные функции для того и созданы, чтобы, если вызваны на родительском классе - находить наследника и запускаться на нем. В блупринтах функции вроде по умолчанию виртуальные, так что создаешь в ItemParent что-то типа GetItemInfo() и потом в каждом наследнике переписываешь. Или даже создаешь отдельные GetWeaponInfo, GetArmorInfo,GetPotionInfo и т.д. и вызываешь их через свою переменную Item.
>>747174 нет, блин, я создал custom event в родителе, переписал его в дочернем Item'е например, чтобы делал PrintString. Пытаюсь вызвать его из щелчка по кнопки виджета - но так как там тип переменной Item - Class Reference, я не могу вызывать оттуда его функции. Для этого нужно обращаться к Obgect Reference. Бля, не догоняю вообще, ведь виджет не должен знать по идее, что в нем лежит, поэтому и описывать нужно работу с классом
>>747037 (OP) Бро, извини, конечно, но у тебя в голове ООП-ад. Плодишь объектные сущности на каждый пук, а это оперативка, которая твоей игре и без того нужна будет.
Инвентарь это просто список. Лично для себя я вывел, что самым удобным вариантом инвентаря является одномерный массив, элементами которого являются ассоциативные массивы: https://pastebin.com/0hDW5j0T вот например. И не надо себе морочить голову с кучей классов. Просто постулируешь у себя в диздоке (даже если диздок у тебя в голове - это всё равно диздок), так вот, постулируешь у себя в диздоке некий протокол, согласно которому у вот такого типа есть вот такие поля. И потом легко парсишь, ожидая определённых полей от определенного типа.
>>747037 (OP) О, инвентарь. Люблю инвентари. Сразу же косяк - почему ты решил что предмет является актором? Премет может быть представлен актором, но он не обязан им являться.Тебе надо разделить данные от вида. Предмет должен быть каким нибудь объектом созданным от UObject например. Он описывает чем объект яляется и что делает. Интерфейс принимает список таких объектов и показывает их. Персонаж имеет функции типа "Взять в руки", "Убрать их рук", "Положить на землю" которые создают/убивают акторов представляющих предмет. Это очень грубое описание, но так примерно делать и надо.
Но если у тебя один и тот же предмет может иметь какие-то динамические переменные которые надо бы тоже сохранять в инвентаре, то их придется хранить отдельно. Ну к примеру ты скрафтил что-то и некоторые характеристики этого объекта задаються рандомом при крафте. То есть может быть один и тот же меч с уроном 8.45 или 11.23. Это один и тот же класс и получить его урон не имея ссылку на конкретно этот мечь - невозможно. В таком случае, в слоте надо предусмотреть структурку, в которую будет записываться индивидуальная инфа. И при спавне эта структура будет подаваться на ноду Спавн Актор фром клас. Соответсвенно в самом мече эта структура должны быть помечена как Експосед то спавн.
>>748617 Не слушайте его. В никакой слот инфа не пигится о предмете. Слот хранит идшник массива инвентаря героя и только отражает что лежит там. А там лежит предмет. Соответственно, когда предмет перекладывают из ячейки в ячейку, это тоже самое что сказать объекту герой - перемести из клетки массива в клетку массива. Когда герой это сделал, он посылает сигнал о том, что эти две ячейки изменены. И интерфейс просто их запрашивает и перерисовывает.
1. создал ItemParent, в котором описал структуру общих свойств для всех предметов;
2. создал ActorComponent для инвентаря, тип map из ItemParent Class + integer;
3. Из ItemParent сделал child-блюпринт-классы, в которых в виде переменных поместил дополнительные структуры, описывающие базовые характеристики этих классов - weapon, spell и т.д. Из него уже создаю сами предметы;
4. Нарисовал виджет слота в инвентаре, и через обращение к классу ItemParent в preconstruct могу в нем отрисовать иконку, количество единиц в инвентаре, цену и то, что мне нужно.
Застрял на том, что добавил к слоту кнопку, по нажатии на которой мне нужно например вытащить текстовую информацию именно содержимого слота, предмета который в нем лежит. Как правильно обратиться к содержимому? В зависимости от того, какой класс предмета там лежит, будут отличаться как минимум названия полей.. что-то я не могу сообразить. Как это правильно делается?