Краткое содержание
Завершение последнего набора функций перед его публикацией на моей странице itch.io.
Сборщик мусора
Как я обнаружил ошибку?
Когда я был близок к завершению своего прототипа, я профилировал игру и обнаружил, что пользовательский интерфейс выделяет 24 байта памяти на каждый кадр.
Почему это произошло?
Метод ToString выделял ненужную память, поскольку постоянно преобразовывал объект в строку в каждом кадре.
Как я решил эту проблему?
Установка четких правил для прототипа. Вместо того, чтобы указывать пользовательскому интерфейсу обновлять каждый кадр, он обновляется только тогда, когда игрок собирает болты и/или значение множителя изменилось.
Я сделал это, извлекая функцию за пределы функции обновления и переключаясь на шаблон наблюдателя. Я уменьшил выделение GC с 24 бит/кадр до 0 бит/кадр.
Объединение объектов
Я реализовал систему пула объектов, созданную OneWheelStudio (OWS).
Почему я реализовал этот вариант объединения объектов?
По общему признанию, я недостаточно знаю о пулах объектов, чтобы сказать, какую систему пулов объектов использовать. Но что мне нравится в решении OWS, так это то, что оно использует словари и его относительно легко изменить и адаптировать к другим проектам.
Почему я использую систему пула объектов?
Мне не обязательно использовать пул объектов для моего прототипа, но это хорошая практика, которую рекомендуют сами Unity, поскольку она предотвращает ненужное выделение сборщика мусора. И будущий мой проект на случай, если я продолжу реализовывать функции, связанные с появлением большого количества игровых объектов, таких как враги, пули и т. д.
Поддержка контроллера
Не первый раз внедряю поддержку контроллера и быстро настраивается с помощью новой системы ввода. Прототип поддерживает вариант контроллера, но я тестировал прототип только с использованием Dualsense. Тем не менее, я не рекомендую использовать его, если вы хотите получить наилучшие впечатления.
Ошибка правого джойстика
Вы можете перемещать камеру с помощью мыши, но при использовании контроллера PS5 вертикальная чувствительность очень медленная по сравнению с горизонтальной. Мне еще предстоит найти причину.
Аудио
У меня нет звуковых эффектов, потому что я расставил приоритеты по другим функциям и у меня был крайний срок. В противном случае я бы и должен был добавить по крайней мере sfx-заглушку, чтобы дать прототипу более визуальную обратную связь.
Шаблон наблюдателя
В одном из моих предыдущих журналов разработчиков мне предложили перейти от синглтонов к делегатам на основе событий. Это было то, что я уже планировал, но ждал, пока игровой цикл заработает.
Я использовал версию шаблона наблюдателя, созданную Райаном Хипплом на конференции Unity Unite Austin 2017.
Он может лучше объяснить, как это работает, но вкратце это вариант шаблона наблюдателя, который использует объекты Scriptable и события Unity, чтобы отделить код и меньше зависеть от функций жесткого кодирования.
Плюсы:
- Легко внедрить в существующий код
- Раздельный код
- Работает с несколькими типами (int, float, bool и т.д.)
Минусы:
- Отладка
- Скрытая зависимость (какие игровые объекты привязаны к какому игровому событию?)
Райан Хиггл демонстрирует, как можно тестировать и отлаживать игровые события, не обязательно повторяя ошибку в пользовательских редакторах.
Я, однако, не использовал его, потому что он мне не нужен, так как это сольный проект, поэтому я знаю, где (в основном) все идет и какие сценарии за что отвечают.
Другая проблема, которую я обнаружил, продолжая добавлять дополнительные функции, заключается в том, что, хотя вы можете отлаживать игровое событие, чтобы увидеть, работает ли оно, вы не можете видеть, какие игровые объекты привязаны к указанному событию. Даже мне пришлось несколько раз просмотреть свою иерархию, чтобы вспомнить, какие игровые события куда идут.
Если бы я сделал это снова
Если бы мне пришлось повторить шаблон наблюдателя объектов, доступных для сценариев, Райана Хиггла, я бы создал пользовательские значки, чтобы отличать тип данных от объекта, доступного для сценариев. Поскольку оба они наследуются от класса объектов, доступных для сценариев, оба используют один и тот же значок.
Я бы реализовал пользовательский инструмент отладки редактора Райана, но с добавленной функцией, позволяющей отслеживать, какие игровые объекты и/или сценарии связаны с игровыми событиями для упрощения отладки.
Зона респауна
Я создал зону возрождения на случай, если игрок намеренно упадет с края. Однако, несмотря на то, что ранее запрограммировали эту функцию, она не работала сразу из-за компонента контроллера персонажа, подключенного к игроку.
Как это работает?
Под боевой ареной находится невидимый коробчатый коллайдер с включенным триггером. Когда игрок проходит через зону возрождения, игрок телепортируется к точке возрождения.
Почему это не сработало?
После поиска ответов и, хотя я не смог найти официального объяснения от Unity, я нашел много сообщений на форумах, в которых обсуждалось, как контроллер персонажа переопределяет transform.position, потому что у него есть собственное внутреннее определение того, какова его позиция.
https://forum.unity.com/threads/character-controller-ignores-transform-position.617107/
Как я решил эту проблему?
Есть 2 решения, которые я узнал о том, как это исправить.
- Напишите функцию, которая временно деактивирует компонент персонажа, а затем устанавливает позицию игрока. Затем повторно активируйте контроллер персонажа.
2. Другой вариант, который я использовал, потому что это было первое решение, которое я нашел и сработал, — перейти в Редактировать › Настройки проекта › Физика › Auto Sync Transforms(AST) и включить его.
Хотя Unity рекомендует устанавливать для AST значение true только для проектов до Unity 2017.2, так как это может привести к снижению производительности из-за многократного изменения преобразования и последующего выполнения физического запроса. Однако я оставлю его включенным до тех пор, пока указанная проблема не возникнет в моем прототипе.
Спасибо за прочтение.
Крис
Программист игр