RustyBits | Дневник разработчика
207 subscribers
106 photos
47 videos
7 files
11 links
Дневник разработчика мобильной игры Genesyx
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Обновил UE до 5.1.1 - проблема с пропавшими текстурами ушла. К сожалению рендеринг на мобилках не исправлен, по прежнему мигают... Добавил пропуск интро к моменту начала драки, уже не могу смотреть одно и то же по кругу после любого изменения...
👏5👍1😨1
В начале своего повествования я писал о том, что в 2016м было разработано очень много моделей оружия и щитов по концептам иконок из веб-версии Genesyx. Наткнулся на них в старом проекте Unity и решил показать. Поклонники Genesyx увидят здесь много знакомого.
👍31🔥1🎄1
В копилку низкоуровневости UE...

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

Сразу после импорта меша в UE размещенный на сцене гекс просто не отображался. Спустя час сравнений с Unity выяснилось, что он импортится очень мелким, в 4.5 раза меньше нужного, и зачем-то повернут на 90 градусов, из-за чего его и не видно (материалы-то односторонние по умолчанию). Переимпортил с соответствующей трасформацией и все встало на свои места.

Дальше начались танцы с бубнами. Применяю текстуру - рендерит вот такой треш. Открыл в Blender'е - все ок, переэкспортил - проблема сохраняется.
🔥3👏3🤯3
Десятки запросов к ChatGPT не дают ответа... он постоянно говорит, что проблема в UV-координатах, но здесь все слишком просто, чтобы дело было в этом, плюс и в Blender, и в Unity все просто работает сразу без всяких танцев с бубном.

Чтобы исключить вопросы с UV, кинул материал на обычный куб - тоже фигня. Пишу ИИ, что проблема явно с импортом текстур, но он продолжает стоять на своем.

Сделал простейшую текстуру в Фотошопе, двуцветный квадрат, кинул на куб - все нормально, кинул на свой гекс - тоже все нормально. Добавил поверх этой текстуры изображение нужного мне гекса - тоже все ок. Значит проблема банально в прозрачности.

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

Unity, и Blender этот вопрос решают автоматически, но не UE.
Надеюсь кому-то этот пост сэкономит пару дней.
👍1😱1
Ребят, если вы присоединились недавно и вам не понятны какие-то технические термины в моих постах - просто читайте блог сначала, там все разобрано и история пока не настолько большая, чтобы сложно было осилить.
👍3🔥21🌚1
Коротко о том, за что я не люблю блюпринты...
😁3🤔1😱1
Ракурс для боя думаю сделать примерно таким.
🔥4👍3
Кажется я знаю как игроделы придумывают монстров. Достаточно что-то неправильно сделать со скелетом модели...
🤣9😁4🏆1
This media is not supported in your browser
VIEW IN TELEGRAM
Нет, не получится использовать сделанные под заказ анимации к сожалению, даже не смотря на продвинутый ретаргетинг в Unreal Engine 5. Технически это, конечно, работает, но различия слишком огромны и несовместимы с моими внутренними стандартами качества.

Излишнюю горбатость еще, может быть, можно было бы стерпеть, но плавающие ноги...

Профессиональный аниматор, наверняка, разобрался бы как нужно поправить кастомный скелет и соответствующие анимации для более адекватной конвертации, но в текущей команде (из одного человека :)) такого нет. Придется искать аналоги в Mixamo и сторах.
👌2🤯1😢1
This media is not supported in your browser
VIEW IN TELEGRAM
Ретаргетинг в Mixamo из стандартного в UE скелета Manny работает лучше. Но есть нюанс...
😁3👌1
Наткнулся на первое ограничение блюпринтов по сравнению с кодом - не поддерживаются двумерные массивы.

Мне нужно сгенеренную боевую сетку выставить наружу для того, чтобы дальше на ней позиционировать бойцов в блюпринтах сцен. Самый очевидный метод - создать двумерный массив, чтобы по координатам типа hex[0,2] можно было получить нужную клетку и дальше с ней работать. Но сделать это в блюпринтах оказалось невозможным.

Традиционно ChatGPT об этом не сказал, настойчиво придумывал сказки о том, как это можно нарулить через интерфейс. Причем он постоянно дает инструкции к UE4, в котором интерфейс IDE сильно отличался, и часто проблема решается уточнением типа "а теперь дай инструкцию к UE5". В этот раз такая директива только усугубила ситуацию - "Конечно, ты прав!" сказал ChatGPT и придумал еще какую-то инструкцию, которая тоже крайне далека от реальности, и на проверку которой я снова потратил время.

В общем пришлось гуглить и там ответ нашелся сразу - это невозможно. На C++ переключаться ради такой ерунды не хотелось, поэтому в голову сразу пришли 3 альтернативы:

1. Использовать одномерный массив, а индекс вычислять из двух координат. Например X*100+Y. Таким образом всегда получаем уникальное число и его можно использовать как индекс в одномерном массиве. Очевидная проблема такого подхода - фрагментация массива и лишнее отжирание памяти, ведь если для карты 8x4 в двумерном массиве нужно будет создать 32 элемента, то при таком подходе - 8*100+4=804, а заняты будут только 32. Лишний расход памяти.

2. Не использовать массив вообще, вместо этого проименовать добавляемые гексы как 0x0, 0x1,... 7x3, потом искать элементы по имени. Очевидный минус такого подхода - сам поиск. Ведь получение элемента массива - это O(1), а поиск по имени - O(n). Получаем лишнюю нагрузку на CPU.
🤯3🤪1
3. Создать кастомную структуру, единственный элемент которой - одномерный массив, потом создать массив этих кастомных структур и его заполнять. С т.з. производительности это наилучший вариант. С т.з. использования - не очень, потому что если в коде это выглядело бы просто как hexagons[0].arrayItem[2], то в блюпринте получаем целую портянку. Ну да ладно, просто запихну это в отдельный удобный метод.
👍1👌1
RustyBits | Дневник разработчика
Наткнулся на первое ограничение блюпринтов по сравнению с кодом - не поддерживаются двумерные массивы. Мне нужно сгенеренную боевую сетку выставить наружу для того, чтобы дальше на ней позиционировать бойцов в блюпринтах сцен. Самый очевидный метод - создать…
В комментариях к посту коллега справедливо заметил, что опция #1 вполне рабочая если для множителя вместо константы (в моем примере 100) использовать максимальную длину массива (в моем случае размер поля по горизонтали). Более того в C двумерные массивы - всего лишь синтаксический сахар, а под капотом лежит одномерный массив, индексы которого так и рассчитываются. Т.е. опция #1 - это фактически и есть реализация двумерного массива в языках, и если об этом подумать - максимально логичная реализация. Век живи - век учись...

И еще один момент по кастомным структурам - это реально структуры, а не классы. Т.е. хранятся в куче и передаются по значению, а не по ссылке. Да, наверное они не просто так называются структурами, но мы уже сталкивались с кейсом Material и Material Instance где терминология не отражает фактического поведения, поэтому этот момент важно уточнить. Причем при использовании кастомных структур возникают странности (от моего незнания движка конечно же) - если создать инстанс структуры, сохранить в переменную, добавить ее (переменную) в массив, а потом что-то изменить в этой переменной - изменение происходит не в том инстансе, который был добавлен в массив, даже не смотря на то, что все манипуляции происходят внутри одного блюпринта. Видимо он где-то под капотом неявно передает переменную как параметр, в результате чего она копируется. Записали, запомнили.
👍6
This media is not supported in your browser
VIEW IN TELEGRAM
Убираем трупы с поля боя через динамический material instance, смешивающий основную текстуру персонажа со стандартной текстурой шума и применение маски непрозрачности (opacity mask).
👍7🔥1👏1
Прокрастинирую
👍5🌭21😁1
Я долго думал стоит ли первый бой делать настоящим, т.е. привязанным к серверу и управляемым с него. С одной стороны это хорошо потому, что весь код сразу получится переиспользуемым для других боев, но пришел к выводу, что не стоит, и вот почему.

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

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

В-третьих первый бой - это точка отсечки тех игроков, кому не зайдет жанр. Запускаю рекламу - приходит 10,000 игроков, из них 9,000 отваливается. Если первый бой пускать через сервер - он должен выдерживать такие скачки нагрузки, а если не привязывать - все скалируется автоматически, потому что интро целиком и полностью выполняется на устройстве пользователя.

И в-четвертых я все еще изучаю движок и по мере продвижения нахожу более правильные варианты решения своих задач, как это обычно и бывает. Например уже понятно, что для всех персонажей должен быть один переиспользуемый блюпринт, который позволит выполнять все базовые действия (типа взять оружие, пройти на клетку вперед, умереть и т.п.) через методы этого блюпринта. Также уже понятно как можно упростить блюпринт самого интро и т.п.. Всей этой информации у меня не было в начале пути и будет лучше сначала пройти его до конца как получится, собрав все грабли, а потом уже сделать все правильно, но отдельно.
👍6🔥3
Самый желанный результат рефакторинга - чтобы все работало также как до него :). Наконец удалось этого добиться.

Сделал общий блюпринт бойцов, перевел все модели и блюпринт сцены на его использование. Набитые шишки:

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

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

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

4. При удалении объекта со сцены, его чайлды не удаляются и в движке нет для этого стандартного метода. Придется написать свой, благо статические классы и методы в UE есть.

5. UE очень часто падает при замене базовых классов объектов, которые уже используются в блюпринтах, при этом оставляя кучу файлов измененными в неконсистентном состоянии. Хорошей идеей будет свой проект сразу пихать в сорс контрол и коммититься часто, потому что откатиться до предыдущего состояния зачастую проще чем пытаться понять что он наворотил в этот раз и исправлять.

6. Иногда просто перезапуск редактора убирает странные артефакты, появившиеся после рефакторинга.
👍1👾1
В своем рассказе о декалях я писал, что они работают по принципу прожектора, соответственно если вы добавили трещины на асфальте с помощью декалей, а потом на их место встал боец - трещины будут на нем, а не на асфальте, потому что прожектор - есть прожектор. Чтобы этого избежать нужно отключить рендеринг декалей на бойцах. Делается это одной галочкой, но я тут, как обычно это и бывает, сделал все по классике... Т.е. рассказал и не сделал.
😁5🤯1