Добрый день. Пишу на C++ систему инвентаря и представления предметов

в мире. Идея такова:

1. Есть C++ класс типа предмета ItemType (AActor), содержит информацию о названии, картинку для отображения в инвентаре, опционально StaticMesh, признак, может ли стакаться, число предметов в стаке.
Наследование от этого класса в целях расширения функционала не предполагается, только наследование Blueprint в целях задания ассетов.
Имеет ссылки на классы (TSubclassOf) Item и WorldItem, для их пораждения.

2. Есть класс Item (UObject), ссылающийся на объект типа ItemType. Базовый класс содержит информацию о количестве предметов. Наследование от этого класса предполагается, если нужна какая-то логика. Например для описания еды, наследуемся от Item, добавляем свойство "свежесть", таймер и уменьшаем значение свежести до минимума и помечаем еду как испорченную при достижении нуля.
ItemType имеет ссылку на тип этого класса (TSubclassOf) для порождения экземпляра объекта. Объект этого типа существует, пока существует предмет. Он будет уничтожен, например если воспользоваться аптечкой или съесть еду, представленные этим объектом.

3. Есть базовый класс WorldItem (AActor), который имеет ссылку на объект Item. Этот актор спавнится, когда пользователь выбрасывает предмет из инвентаря. Или просто спавнится в начале уровня. Короче, представление предмета в мире. Дефолтная версия просто представлена StaticMesh'ем из ItemType. Для большинства простых предметов будет применяться эта версия, но если нужно сложное представление, то наследуемся от WorldItem и пишем свое представление.
ItemType имеет ссылку на тип этого класса (TSubclassOf) для порождения экземпляра объекта в мире. Объект этого типа существует, пока существует предмет в мире. Он будет уничтожен, если игрок поднимет предмет и положит его в инвентарь или когда будет уничтожен Item.

Я хочу описать систему достаточно гибкую, но с минимальным наборот сущеностей.
Например, если в игре будут квестовые предметы, не обладающие сложными характеристиками, которые просто нужно будет проверять на наличие в инвентаре, я добавлю Blueprint наследник ItemType под названием QuestItem и всё. Item и WorldItem подойдут базовых типов.

Но у меня возникли вопросы. WorldItem обязан быть наследником AActor, так как он будет спавниться в мире, тут все понятно. Item - логический объект, собственного представления на уровне иметь не будет, базовый класс - UObject. А вот ItemType тоже логический, напрашивается AActor, но мне нужно как-то задавать для него ассеты, а это требует создания Blueprint, а они могут наследоваться только от AActor. Я прав?

Следующий вопрос: хотелось бы иметь возможность во-первых спавнить предметы по ключу идентификатору, во-вторых взять да и отобразить все доступные предметы в игре. Допустим я добавлю наследник UGameInstanceSubsystem и буд регистрировать в нем блюпринты типов (ItemType). С помощью какой структуры данных это лучше сделать? Просто добавлять член класса с UPROPERTY для каждого типа мне кажется плохой идеей. Я бы добавлял их в TMap с строковым идентификатором в качестве строки, а значением устанавливал бы ItemType*, то есть фактически блюпринты. Но в этом случае надо будет вручную поддерживать соответствие текстового ключа блюпринту. Хорошо было бы, чтобы блюпринты типов сами зарегистрировались в моем UGameInstanceSubsystem. Есть ли для этого способ?

Ну и вообще, есть ли у вас замечания к такой системе?

6 ответов

58 просмотров
Алексей-Попов Автор вопроса

Не знал про этот тип, спасибо большое! Ушел читать что это)

Алексей-Попов Автор вопроса

Хм, Вы правы. Для Actor, Pawn и других типов не доводилось указывать спецификатор, потому что он вижимо наследуется от базового типа.

Алексей-Попов Автор вопроса

Читаю про DataAsset и не очень понимаю, чем это лучше просто UObject? И в том и в другом случае возможно настройка через редактор. Я так понима, DataAsset предоставляет какие-то возможности сериализации, которые в моем случае не нужны?

Осилил всё, прочитал несколько раз. Вопросы есть, но напишу по существу по-поводу сбора ассетов определённого типа: через AssetRegistry и например GetAssetsByClass

Алексей-Попов Автор вопроса

Отлично! Это то, что нужно)

Похожие вопросы

Обсуждают сегодня

Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
5
А в каком формате фреймы? Сам формат сейчас придумываешь, или что-то готовое нужно распарсить?
Okhsunrog
5
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
сделал сайт, прикрутил в боте сайт, и виджет логина. как автоматически логинить пользователя в аккаунт(телеграм), при входе с бота?
Александра Чернивецкая
5
Карта сайта