Как стать автором
Обновить
10
0
Виктор Ковылин @tzay

Unreal Engine Engineer, CTO at DreamVR

Отправить сообщение

К сожалению принты так и не только так весьма часто ломаются :(

Обычно чиню подобное следующими способами:

Первый самый простой:

  1. Полностью вырезаю или трансинчу поломанные компоненты

  2. Пересохраняю всю иерархию макаронных наследников, что бы серриализовать все без поломанного компонента

  3. Возвращаю все как было и надеюсь, что починится

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

Третий вариант - самый душный: воссоздавать вручную и заменять всю макаронную иерархию наследования. Такое может помочь, если в уровнях есть куча поломанных акторов, потому что есть вероятность (и порой так оно и есть) что они не корректно сериализованы в пекеджах уровней. Порядок действий простой:

  1. Создаешь новые блюпринтовые классы

  2. Пишешь конвертер из поломанного инстанса в новый

  3. Пишешь код который проходится по всем уровням, заменяет всех акторов (и ссылки на них) и все сейвит

  4. Запускаешь, проверяешь, радуешься

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

Хорошая статья, тоже везде юзаю жсон конвертер и всем советую - оч удобная вещь.

Но, хочу заметить, что в последней кодовой вставке пропущены UPROPERTY для отметки полей структуры, которая подается на конвертер. Это может запутать читателя.

На кой черт с какой целью мне может понадобиться в 2022-2023 году костылить игровой сервер на пыхе и луа, когда у меня есть движки умеющие в мультиплеер из коробки или для каждого есть рабочее решение? Помимо этого, есть готовые решения общего типа, например https://www.photonengine.com/. И решения типа https://ims.improbable.io/products/spatialos для высокой нагрузки. А так же решения типа https://playfab.com/ для инфры.

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

Почти пол года используем пластик. По началу я его боготворил как мог, но потом нашел несколько очень бесячих нюансов:
1. Смена пользователя - один большой баг, когда хочешь настроить права - это прям боль, я 2 часа разбирался как сменить пользователя - оказалось, что надо удалять конфиг клиента :-/ (Мб уже починили)
2. 4 разных GUI с разными багами, например иногда бывают мержи которые один гуй мержит, а другой - нет
3. Конфликт злых близнецов на папках: кто это вообще придумал? В целом иногда он стандартные ситуации для того же Git видит как конфликт при мерже.
4. От изменения бинарника в 2-х ветках так же не спасает и не поддерживается фича статус бранчей. (Хотя это чекали весьма давно)
5. Ветки не удаляются
Но в остальном - все правда очень классно.

Кстати при помощи хлинков можно сделать весьма удобный аналог UGS/PBSync

А блин, не сразу увидел, что это перевод старой статьи Стива с острова.

Кстати, Chaos имеет поддержку фиксированных интервалов обработки физики. Сам не работал с Chaos но вот выдержка из пачноутса:

Asynchronous Physics Simulation

In Unreal Engine 5, users can now run the physics simulation in its own separate Physics Thread as opposed to running on the Game Thread.

The main advantage of running physics in its own thread is that the simulation runs on a fixed tick interval, which allows for more predictable results.

You can use this feature to fine-tune your simulations to always behave in a predictable way. This behavior also serves as the foundation for networked physics, as it allows the server and its clients to tick physics at the same rate, making it easier to synchronize the results.

https://docs.unrealengine.com/5.0/en-US/unreal-engine-5-0-release-notes/

Идеологически BeginPlay - начало игрового процесса (что твой актер делает, когда игра началась для него). В идеале оно происходит после инициализации всего от чего актер зависит. Основная именно проблемная проблема - в мультиплеере бегин плей не всегда вызывается на клиентах.
Так же актеры мог спавниться с отложенным бегин плеем (SpawnActorDeffered).
Например при загрузке уровня стримингом актеры и компоненты создаются и инитятся группами, но бегин плей вызывают вместе.
Что может нам говорить о том, что бегин плей должен быть легковесным.


Функции же приведенные как альтернативы - вызываются всегда при создании объектов и предназначены для инициализации объектов.

Если очень хочется то можно, конечно, но я бы не советовал.

@SmallSnowballи @AllexInблагодарю вас, что помогли сделать статью лучше, я исправил части, на которые вы указали (про степень 2-х и материалы) и немного дополнил сверху.

С nDisplay не работал. Возможно скоро придется, ченить напишу потом. А Split screen там просто все достаточно, вроде. Но тоже супер давно что то с ним делал

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

Пожалуй я скажу что не так хорошо разбираюсь у вопросе на столь глубоком уровне, однако все равно убежден:

  1. Текстуры стоит держать стороной в степень 2ки, да не обязательно квадраты

  2. Лоды нужны, даже если объекты легковесны. Ну или их можно просто калить на самом деле

На сколько я знаю при помощи gcc анриал тоже можно собрать, несколько лет назад при помощи него собирал ue 4.20 на линьке. Однако да, зачастую библиотеки сторонние нужно компилировать в другом месте и под все платформы (но не под все компиляторы)

О каких странных условиях вы говорите?)

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

Про размер текстур: Это на самом деле капец глубокий вопрос!
Во первых я говорю о видео памяти (VRAM), а не о оперативной памяти (RAM).
Однако, я изучил вопрос глубже: действительно в нынешней реальности текстуры не обязаны быть квадратными, однако они все еще должны быть стонрой в степени 2-х.
на это завязаны алгоритмы сжатия, выборки, интерполяции и генерации mip-карт. Да и многие другие на самом деле.
Однако сейчас есть алгоритмы, например в DirectX 11 которые относительно спокойно работают с текстурами не в степени 2-х, но для некоторых операций/оптимизаций, на сколько мне известно, они все равно расширяют текстуру до степени 2-х.

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

По поводу сжатия текстур. Почти все форматы сжатия используют тексели 4х4 пикселя, по этому что бы на текстуре нормально отработало сжатие ее стороны должны быть кратны - 4м. Это точно актуально для форматов: BC1-BC5
Вот несколько статей, которые вы можете почитать что бы лучше понимать о чем я говорю, но конкретно интересующей нас инфы там мало:
https://docs.microsoft.com/ru-ru/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro?redirectedfrom=MSDN
https://www.katsbits.com/tutorials/textures/make-better-textures-correct-size-and-power-of-two.php
https://docs.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#virtual-size-versus-physical-size

Про материалы и инстансы, опять же я говорю о видео памяти. Шейдерам для того что бы исполнятся на видеядрах нужно быть загруженным и вычисленным. Я сознательно опустил момент того, что шейдер нужно еще и вычислить перед использованием, заменив это просто термином "загрузка".
Работает это (загрузка и вычисление 1 раз) только со статическими инстансами .В видео память шейдер с 2-х одинаковых материалов или с динамических инстансов будет загружен и вычислен 2 раза.
Но в оперативной памяти будет висеть 1 объект материала.

Кажется UE уже сам инстансит материалы при постановке их в слот в редакторе, но я нигде не нашел информации про это.

Это обусловлено тем, что при изменении параметров материала шейдер должен быть так же изменен и как следствие вычислен заново. Про это можно почитать вот по этой ссылке: https://docs.unrealengine.com/5.0/en-US/instanced-materials-in-unreal-engine/ в разделе "Constant and Dynamic Instances"

Про лоды отвечу так: А вы много видели в относительно современных играх мешей манее нескольких тысяч полигонов?
Да и в целом в вопросе про лодирование я больше акцентирую внимание на снижение сложности шейдера, чем на количество полигонов.
Однако! Основная задача лодирования мешей - решение проблемы перерисовок - quad overdraw. Пережевать же сколь угодно большое число вертексов геометрическим шейдером - фигня вопрос. Вот есть статья на эту тему: https://unrealartoptimization.github.io/book/pipelines/pixel/
К примеру: если у вас будет стоять меш у которого мы видим 100 полигонов и на экране он будет занимать 2х2 пикселя - мы эти 4 пикселя будем перерисовывать столько раз, сколько полигонов мы видим, то есть - 100 раз. Это все будет в рамках одного дроукола, но все равно - 100 перерисовок, это оверкилл.

Большое спасибо за комментарий, рад что вам понравилось. В целом то, что вы сказали и побудило меня начать писать эти статьи. Когда я начинал свое становление, было весьма сложно искать информацию в принципе, не важно каким языком обладаешь. И поиск информации сжирал очень много времени и моральных ресурсов.
Сейчас на многие фундаментальные вопросы до сих пор нет четких ответов и я стараюсь это исправить. О сети очень советую network compendium, он правда не потерял актуальность и несет в себе все нужные знания, что бы делать сетевые игры. Но возможно и сам что нибудь напишу про сеть. :-)

Проблема дедиков тут в том, что для создания сессии требуется игрок, а точнее его NetId(SteamId в данном случае) и токен авторизации. И этот игрок будет являться владельцем сессии, а так же IP его машины (или в случае со стим его ID на магистрали vavle) будет записан в сессию, как URL подключения.
Дедикейтед сервер же не предоставляет игрока по определению. Можно конечно на машинах с серваками поднимать SteamCLI и делать сервисных игроков, которые будут хостить сессии. Я знавал одних челиков, которые так сделали, но куда проще взять какой нибудь PlayFab или GameLift и хостить дедики там.

Хорошая и полезная статья!

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

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

Куда логичнее, на мой взгляд, было бы реализовать показанный в туторе функционал в сабсистеме, как сделан DestroySession.


Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Game Developer, Software Architect
Lead
C++
Unreal Engine
AWS
Windows Azure
Game Development
Design games
Creating project architecture
Designing application architecture