Ownership.Actor:Role,RemoteRole,Relevancy,Priority.Traveling in Multiplayer.

Список разделов:
1.Введение
2.Framework & Network in Unreal Engine 4.
3.Dedicated vs Listen Server.Replication.Remote Procedure Calls.
4.Ownership.Actor:Role,RemoteRole,Relevancy,Priority.Traveling in Multiplayer. Вы здесь.
5.Online Subsystem Overview.How to Start a Multiplayer Game.

Ownership

Ownership (владение) важное для понимания понятие.
Ранее уже была приведена таблица, которая содержала такие вещи, как «клиент владеющий эктором».
Сервер или клиенты могут иметь собственных экторов.
Примером может служить PlayerController, который принадлежит Клиенту (или Listen-серверу).
Другим примером может быть спавненная/размещённая дверь в сцене.
Это в большинстве случаев будет принадлежать серверу.
Но почему это проблема?
Если вы посмотрите в таблицу снова, вы заметите, к примеру, что, Server RPC будет сброшен, если клиент вызывает его на эктора, которым он не владеет.
Таким образом, клиент не может вызвать «Server_OpenDoor» на дверь которой владет сервер.
Но как мы работаем с этим? …

Мы используем Class/Actor которым владеет клиент.
В этом месте PlayerController проявляет себя во всей красе.

111 Таким образом, вместо того, чтобы пытаться включить Input у двери и вызвать Server RPC, мы создаем Server RPC в PlayerController и даём Servercall функцию интерфейса на дверь (например: Interact() ). Если дверь применяет соответствующий интерфейс, то будет вызываться определенная логика, которая будет реплицировать открытое/закрытое положение правильно.
Примечание: Интерфейсы не имеют мультиплеерных спецификацмй, поэтому я рекомендую разузнать про них больше, если вы не понимаете их.
Actors and their Owning Connections

Как уже упоминалось в обзоре Class, PlayerController первый класс, которым владеет игрок, но что это значит?
Каждое соединение имеет PlayerController, созданный специально для этого соединения. PlayerController, который создается по этой причине, принадлежит этому соединению. Поэтому, когда мы определяем, принадлежит ли эктор кому либо, мы на самом деле совершаем запрос до самого внешнего владельца и, если им является PlayerController, то соединение, которое владеет PlayerController‘ом также владеет этим эктором.
Довольно просто или? Какой бы пример привести для этого?
Pawn/Character. Они являются собственность PlayerController‘а и в это время, PlayerController является владельцем принадлежащего ему Pawn‘а.
Это означает, что соединение, которое владеет этим PlayerController‘vом также владеет Pawn‘ом.
Но это до тех пор пока PlayerController является владельцем Pawn‘а.
Un-possessing — является результатом того, что клиент больше не владеет Pawn‘ом.

Так почему же это так важно и для чего мне это надо?
RPC необходимо определить, какой клиент будет выполнять Run-On-Client RPC.
Репликацию эктора и актуальность соединения.
Условия репликации свойств эктора, когда участвует владелец.
Вы уже читали, что RPC реагируют по-разному, когда получают вызов от клиента/сервера, в зависимости от того, кто владеет соединением.
Вы также прочитать об условной репликации, где (в C ++) переменные реплицируются только при определённых условиях.
В следующем разделе описывается актуальная часть списка.

Actor Relevancy and Priority
Relevancy

Итак, что такое «Релевантность» и зачем нам это надо?
Допустим у нас есть игра, в которой уровни/карты достаточно велики, когда игроки «неважны» по отношению друг к другу.
Зачем игроку А нужно видеть модельку игрока B, если они на огромном расстоянии друг от друга?
Для повышения пропускной способности, код сети Unreal’а делает это возможным, когда сервер только говорит клиентам об эктора, которые находятся в соответствующем наборе этого клиента.

Unreal применяет следующие правила (в указанном порядке), чтобы определить соответствующий набор экторов для игрока.
Эти тесты выполняются в вирутальной функии «AActor::IsNetRelevantFor()«.
1. Если эктор ‘bAlwaysRelevant‘, принадлежит Pawn‘у или PlayerController‘у, является ли Pawn зачинщиком какого-либо соответствующего действия какого как шум или повреждение.
2. Если эктор ‘bNetUserOwnerRelevancy‘ и имеет владельца, использовать актуальность владельца.
3. Если эктор «bOnlyRelevantToOwner«, и не проходит первую проверку, это не имеет значения.
4. Если эктор прикрепляется к скелету другого актера, то его релевантность определяется
по релевантности его основания.
5. Если эктор скрыт ( «bHidden == TRUE«) и корневой компонент не вступает в противоречие, то эктор не актуален.
◦ Если нет корневого компонента, «AActor :: IsNetRelevantFor ()» будет регистрировать предупреждение и спросит, если эктор должен быть установлен в «bAlwaysRelevant = true«.
6. Если «AGameNetworkManager» настроен на использование ревалентности на основе расстояния, эктор имеет значение, если она ближе, чем расстояние отрисовки.
Примечание: Pawn и PlayerController перезаписывают «AActor :: IsNetRelevantFor () » и имеют разные условия для ревалентности в качестве результата.

[свернуть]
Prioritization

Unreal использует метод балансировки нагрузки, с приоритетностью всех экторов, и дает каждому из них справедливую долю пропускной способности на основе того, насколько он важен, для игрового процесса.
Актеры имеют переменную с плавающей точкой под названием «NetPriority». Чем выше это число, тем больше пропускная способность, которую эктор получает по отношению к другим. Экторы с «NetPriority» 2,0 будет обновляться ровно в два раза чаще, нежели эктор с «NetPriority» 1.0.
Единственное, что имеет значение с приоритетами является их соотношение.
Таким образом, очевидно, что вы не можете улучшить производительность сети Unreal’а путем увеличения всех приоритетов.
В настоящее время приоритет эктора рассчитывается с использованием виртуальной функции «AActor :: GetNetPriority ()«.
Чтобы избежать недостатка «AActor :: GetNetPriority ()» умножает «NetPriority «со временем последней репликации эктора.
Функции «GetNetPriority» также рассматривает взаимное расположение и расстояние между эктором и зрителем.

Большинство из этих настроек можно найти в Class Defaults блупринта и, конечно же, могут быть установлены внутри класса C ++ каждого дочерного эктора.

111

bOnlyRelevantToOwner = false;
bAlwaysRelevant = false;
bReplicateMovement = true;
bNetLoadOnClient = true;
bNetUseOwnerRelevancy = false;
bReplicates = true;
NetUpdateFrequency = 100.0f;
bCullDistanceSquared = 225000000.0f;
NetPriority = 1.0f;
[свернуть]
Actor Role and RemoteRole
У нас есть еще 2 важных свойства репликации эктора.
Эти два свойства говорят вам:
• Кто имеет контроль над эктором.
• Является ли эктор реплицируемым или нет.
• Режим репликации.
Первое, что мы хотим, определить, кто имеет контроль над определённым эктором .
Для того, чтобы определить, является ли текущий запущенный инстанс движка полномочия, проверьте, что свойство Role является ROLE_Authority. Если это так, то этот экземпляр двжика отвечает за этого эктора(будь то репликация или нет).
Примечание: Это не то же самое, что и права собственности!
Role/RemoteRole Reversal

Role и RemoteRole может быть отменено в зависимости от того, кто проверяет эти значения.
Например, если на сервере вы имеете такую конфигурацию:
• Роль == Role_Authority
• RemoteRole = ROLE_SimulatedProxy
Тогда клиент увидит его, как это:
• Роль == ROLE_SimulatedProxy
• RemoteRole == ROLE_Authority
Это имеет смысл, так как сервер отвечает за актера и реплицирует его клиентам.
Клиенты просто должны получать обновления, а также симулировать эктора между обновлениями.

[свернуть]
Mode of Replication

Сервер не обновляет экторов при каждом обновлении. Это займет слишком много пропускной способности
и ресурсов процессора. Вместо этого сервер будет реплицировать экторов с частотой указаной в настройках
«AActor::NetUpdateFrequency«.
Это означает, что пройдёт некоторое время между обновлением экторов на клиенте. Это может привести к дёрганном/обрывистому перемещению экторов.
Чтобы компенсировать это, клиент будет симулировать эктора между обновлениями.
Есть в настоящее время два типа симулирования происходящего:
ROLE_SimulatedProxy и ROLE_AutonomousProxy.

ROLE_SimulatedProxyROLE_AutonomousProxy
Это стандартный способ симуляции, и, как правило, он основан на экстраполяции движения на основе последней известной скорости. Когда сервер отправляет обновление конкретному эктору, клиент будет корректировать свою позицию по отношению к новому месторасположению, а затем между обновлениями, клиент продолжит перемещение эктора основываясь на последней скорости полученой с сервера.
Симуляция с использованием последней известной скорости является лишь одним примером того, как вообще работает симуляция. Ничто не мешает вам написать собственный код для какой либо другой информации для экраполяции между обновлениями сервера.
Это, как правило, используется только на экторах, которые обладают PlayerControllers.
Это означает, что этот эктор получает входные сигналы от человеческого контроллера, поэтому, когда мы экстраполируем, у нас есть немного больше информации, и можем использовать фактические человеческие входы для заполнения недостающего информации (в то время как экраполяция основывается на последеней известной скорости).
[свернуть]
Traveling in Multiplayer
Non-/Seamless travel
Разница между «Seamless» (Бесшовным) и «Non-seamless» (Подзагрузки) перемещением проста.
Бесшовное перемещение является неблокирующей операцией, в то время как «Non-seamless» будет блокирующим вызовом.
«Non-seamless» перемещение означает, что клиент будет переподключаться к серверу каждый раз как будет готова к загрузке новая карта.
Эпики рекомендует использовать «Seamless» перемещение как можно чаще, так как это приведет к более гладкому игровому процессу, и позволит избежать каких-либо проблем, которые могут возникнуть в процессе повторного подключения.
Есть три момента в которых используетеся «Non-seamless» перемещением:
• При загрузке карты в первый раз.
• При подключении к серверу в первый раз в качестве клиента.
• Если вы хотите закончить многопользовательскую игру, и начать новую.
Main Traveling Functions
3 основные функции управляющие перемещением:
UEngine::Browse

• Является жёсткой перезагрузкой при загрузке новой карты.
• Всегда будет приводить к «Non-seamless» перемещениям.
• Приведет к тому, что сервер отсоединит текущих клиентов перед перемещением к назначенной карте.
• Клиенты отключатся от текущего сервера.
• Выделенный сервер не может перемещаться на другие серверы, так что карта должна быть локальной (не может быть URL).

[свернуть]
UWorld::ServerTravel

• Только для сервера.
• Перемещение сервера на новый уровень/карту.
• Все подключенные клиенты будут следовать.
• Способ мальтиплеерных игр перемещатся от карты к карте, и только сервер вызывает эту функцию.
• Сервер будет вызывать APlayerController::ClientTravel для всех подключённых клиентских игроков.

[свернуть]
APlayerController::ClientTravel

• При вызове от клиента, будет перемещатся на новый сервер.
• Если вызывается с сервера, проинструктирует конкретного клиента, для перемещения на новую карту (но оставаться на связи с текущим сервером).

[свернуть]
Enabling Seamless Travel
«Seamless» перемещения идут с переходной картой. Это настраивается через свойство «UGameMapsSettings::TransitionMap«. По умолчанию это свойство является пустым. Если ваша игра оставляет это свойство пустым, то для него будет создана пустая карта. Причина наличия переходной карты из-за того, что всегда должен быть загружен Мир (который держит карту), поэтому мы не можем освободить старую карту пока не загрузим новую. Так как карты могут быть очень большим, то содержать в памяти и старую и новую карту — не шибко умная затея, вот тут и вступает в работу переходная карта. Как только вы подготовите переходную карту, установите «AGameMode::bUseSeamlessTravel» в значение true, теперь бесшовное перемещение должно работать.

111 Также это может быть нестроено в блупринте GameMode, также во влкдаке “Maps and Nodes” в настройках проекта.
111
Persisting Actors / Seamless Travel
При использовании бесшовных перемещений, некоторые экторы могут переноситься (сохраняться) на новом уровне. Это полезно для некоторых экторов таких как инвентарь, игроки и тд.
По умолчанию эти экторы будут сохраняться автоматически:
GameMode эктор (только сервер).
• Любые экторы дополнительно добавлены с помощью «AGameMode::GetSeamlessTravelActorList«.
• Все контроллеры, которые имеют действительный PlayerState (Сервер только).
• Все PlayerControllers (Сервер только).
• Все локальные PlayerControllers(сервер и клиент).
• Любые экторы дополнительно добавленые с помощью «APlayerController::GetSeamlessTravelActorList» вызванные на локальных PlayerController‘ах.
Процесс выполнения бесшовного перемещения:
1. Маркировка экторов которые будут сохранены для проходного уровня (читай выше).
2. Перемещение на переходной уровень.
3. Маркировка экторов которые будут сохранены на финальном уровне (читай выше).
4. Перемещение на финальный уровень.
Сделал — Cedric ‘eXi’ Neukirchen ( cedric.bnslv.de )
Актуально для Unreal Engine 4 Version: 4.11.
Перевёл на великий и могучий — RedComrade
Оригинал
Если вы нашли какую-либо ошибку в текстах перевода, просьба, напишите об этом в ЭТОЙ теме.

Читайте также: