Идентификация активов в игровом движке?

12

Я хочу определить свои загруженные активы, но я не знаю, какой из них выбрать. Есть 2 варианта:

  • Имя (строка)

    • Это самый простой и быстрый способ с unordered_map (O (1)), но намного медленнее, чем с использованием целых чисел.
    • Легко понять в коде.
  • Целые

    • Самый быстрый.
    • Не понятно в коде.

Я знаю, что строки не так безопасны или быстры, но так ли это плохо, или они считаются плохими только в названии AAA? Я мог бы создавать перечисления, использовать целые числа, но если я загружаю сцену, ресурсы и т. Д. Из файла во время выполнения, я не могу использовать перечисления. Есть ли способ сделать эти целые числа читаемыми, если они генерируются во время выполнения?

Я знаю, что эта проблема имеет несколько тем по всему Интернету, но я не мог понять, насколько важно в каких случаях это.

Tudvari
источник
10
Почему бы не реализация обоих? Строковая версия соединяется с Dictionary <string, int>, который, в свою очередь, вызывает Dictionary <int, Asset>. Вы можете обойти слой на основе строк в коде, но использовать слой на основе строк для взаимодействия с пользователем.
Krythic
2
Я бы поддержал точку зрения @ Krythic. Если ваш код любит целые числа для скорости, пусть ваш код использует целые числа. Если вашим пользователям нравятся строки для удобочитаемости, пусть пользователи используют строки. Эти два могут сосуществовать довольно счастливо (и вы можете выборочно скомпилировать строковую версию только в сборки разработки, если вы хотите полностью исключить накладные расходы в выпуске)
DMGregory
Та же проблема в несколько ином контексте: разные методы реализации предметов - в чем различия?
Филипп

Ответы:

19

Вы можете поддержать оба.

Хотя во время выполнения часто эффективнее ссылаться на активы с помощью целого числа или другого быстрого ключа для сравнения, во время разработки часто эффективнее ссылаться на них по имени, потому что люди намного лучше работают с такими именами, как enemy_bullet_casing_soundчем 72910613.

Используйте целочисленный ключ для непосредственного поиска ресурсов и используйте это целое число в коде везде, где это возможно (где вы можете поместить фактическое значение целого числа в переменную и, таким образом, работать с ним проще). Укажите сопоставление имени с этим целочисленным ключом (а не непосредственно с ресурсом) и используйте это сопоставление всякий раз, когда вы сталкиваетесь с именованными ссылками на активы, чтобы разрешить фактический целочисленный ключ и найти актив.

Использование поиска на основе имен значительно облегчит работу с файлами данных, а сопоставление имени с более быстрым ключом сохранит все важные преимущества более быстрого ключа целого типа везде, где это необходимо.


источник
Мой случай: я хочу изменить материал Объекта, поэтому я отправляю запрос с именем нового материала. (строка) Затем в графической системе выполняется поиск в неупорядоченной карте <string, pointer>, и указатель материала объекта будет заменен новым указателем. Так что в моем случае мне не нужно преобразовывать его в целое число? (потому что я конвертирую его в указатель и в частых алгоритмах я использую указатели, я использую только строки для случайных вещей.)
Tudvari
Или я должен использовать целочисленные идентификаторы вместо указателей везде, где это возможно? (Поэтому мне не нужно включать заголовочный файл, например, материала.) Например, компонент рендерера теперь хранит указатель используемого материала, который может использоваться непосредственно графическим движком, но я должен включить Material.h , Но когда я храню только целые числа в компоненте рендерера, мне не нужно включать Material.h, но я должен выполнять поиск по целому числу в массиве указателей. Я думаю, что последний лучше. Это? Должен ли я рефакторинг это?
Тудвари
1

В моем проекте я использую хешированные строки, которые во время компиляции преобразуются в уникальные (я хочу!) Числа. Поэтому, когда мне нужен ресурс, например текстура, я просто называю

MngTexture->get(hash("my_texture"))

И так как я создаю простую структуру системы сущностей и мне нужно загружать данные компонентов из файлов, я создал простой язык, такой как json, для хранения данных, но его можно скомпилировать (преобразование слов и символов из цифр в число и из строк в хэшированные значения) , Так, например, если я хочу связать текстуру с идентификатором hash («my_texture») с «ball.PNG» в моем файле данных, я буду иметь

|my_texture| = "ball.PNG"

Где || это оператор, который говорит компилятору хешировать слово внутри.

Поэтому в основном я использую строки, которые сопоставляются с целочисленными значениями во время компиляции (чтобы у них не было никаких накладных расходов), как в реальном коде, так и в файлах, которые являются потоками для загрузки компонентов. Для вычисления хеша время компиляции просто Google, это простая функция из 5-10 строк кода.

Конечно, вы можете загрузить строку из ваших файлов и хэшировать ее во время выполнения, в этом случае вам не нужно писать словарь самостоятельно, потому что алгоритм сделает это за вас (создавая целые числа из строк), и я думаю, что хэширование, по крайней мере, так же быстро, как поиск по карте, из-за локальности памяти (вы просто перебираете строку длиной несколько байтов).

Надеюсь, это поможет.

Liuka
источник
0

Идентификация объекта по строкам не является оптимальной, целые числа гораздо более эффективны. Для удобства вы можете поддерживать таблицу строк (или словарь) строк в целые, чтобы помочь во время разработки и во время отладки.

Однако я бы рекомендовал, чтобы в вашем основном игровом коде вы ссылались на объекты только по их целочисленному идентификатору (или перечислению для удобства чтения). Это упрощает выделение таблицы строк как отдельного актива. Если код вашей основной игры не опирается на эту таблицу строк, то вы можете удалить ее из выпущенной игры, что может сэкономить значительный объем памяти - это важно учитывать, если вы работаете над мобильной игрой и хотите, чтобы размеры загрузок были такими маленькими, как возможно.

steeveeet
источник