Tanks Multiplayer
Documentation
V1.6

 

Начиная
Следующие шаги в этой главе описывают, как включить многопользовательский сервис для использования с этим
актив. Без включения сетевой службы игра не будет работать. Поэтому, пожалуйста, прочтите
по крайней мере, первая глава этой документации.
Вы можете выбрать между Unity MLAPI, Photon или Mirror Networking в качестве многопользовательской игры и
служба знакомств. Для подробного сравнения функций и цен см.
официальные страницы для MLAPI / Photon / Mirror.
Чтобы увидеть (датированный) видеоурок о том, как начать, пожалуйста, загляните на мой канал YouTube.
Менеджер пакетов
При импорте актива вы увидите предупреждение о том, что ваш диспетчер пакетов
зависимости могут быть изменены. Отмените выбор файла manifest.json при импорте, если вы импортируете
актив в существующий проект (который уже содержит ваш собственный манифест).
Единство MLAPI
Если вы читали этот раздел, значит, вы решили использовать новую объектно-ориентированную сеть Unity.
услуга. Обратите внимание, что он все еще экспериментальный, поэтому интеграция тоже помечена как «бета».
В какой-то момент MLAPI будет доступен в диспетчере пакетов. Пока вы экспериментируете, вы
придется добавить его в свой проект вручную. Пожалуйста, обратитесь к этой странице для получения инструкций по установке.
Фотон (PUN)
Если вы читали этот раздел, значит, вы решили использовать Photon в качестве поставщика сетевых услуг. Сначала откройте
в Unity Asset Store и импортируйте либо PUN 2 FREE, либо Photon PUN 2+ (если у вас уже есть
что). После завершения импорта настройте свой AppID для сервисов Photon во всплывающих окнах.
что появляется. Если это не так, перейдите в Window> Photon Unity Networking> PUN Wizard> Setup.

Проект. Если вы уже создали приложение для Photon Cloud, вы найдете свой идентификатор приложения в
панель управления Photon Cloud.
Зеркальная сеть
Итак, вы решили использовать Mirror Networking, разработанную сообществом UNET, в качестве своего
сетевой провайдер. Mirror доступен бесплатно в Unity Asset Store. Загрузите и импортируйте его
в свой проект.
Настройка проекта
После импорта сетевого решения по вашему выбору пришло время импортировать соответствующие файлы.
Танков Мультиплеер. Каждое сетевое решение поставляется только с собственными сетевыми компонентами.
доступно для этого конкретного сетевого сценария. Это означает, что вы не сможете легко переключиться позже.
В проекте есть несколько префабов, которые требуют наличия этих сетевых компонентов.
прикреплены к ним. Например: для MLAPI это NetworkObject. Для Mirror это было бы
NetworkIdentity, а для Photon есть PhotonView. Чтобы импортировать сеть
скрипты, пожалуйста, перейдите в Window> Tanks Multiplayer> Network Setup.
Теперь вы готовы играть в игру — загрузите сцену «Вступление»!
Идите вперед и создайте один или два экземпляра, чтобы играть друг против друга (или против себя).
Танки Мультиплеер FLOBUK

Мы просто потратим здесь еще одну минуту, чтобы пройтись по настройкам сцены, используемым в игровых сценах.
Вы можете найти их на панели проекта в разделе Tanks Multiplayer> Scenes. В этих сценах
разные слои используются для окружения, сцены и объектов игрока. Это сделано для того, чтобы наши
настраиваемая физическая матрица столкновений (Правка> Настройки проекта> Физика) обеспечивает столкновения между
определенные объекты появляются только там, где мы хотим.
По умолчанию: статическая среда с коллайдерами для создания границ игрового мира.
TransparentFX: границы зоны возрождения команды, не должны ни с чем сталкиваться
IgnoreRaycast: предметы коллекционирования должны сталкиваться с игроками и зонами коллекционирования
Пользовательский интерфейс: все визуальные элементы игры на холсте, без столкновений
Игрок: сталкивается с окружающей средой, предметами коллекционирования или пулями, но не с другими игроками
HUD: визуальные элементы игрока, скрытые при смерти игрока, без столкновений
Пуля: сталкивается только с окружающей средой или игроками, но не с другими пулями

Вход в систему подбора игроков
Возможно, вы заметили, что во вступительной сцене есть кнопка Play, которая напрямую пытается ввести
онлайн-игра через сватовство. Код для этого находится в скрипте NetworkManagerCustom. Если
что-то не получается во время подключения, появляется окно с ошибкой. Таким образом, сватовство
рабочий процесс выглядит так:
В дальнейшем в этом документе и особенно в главах, связанных с сетями, вы найдете
дополнительные текстовые поля, такие как MLAPI, Photon или Mirror. Они специально предназначены для
сетевое решение, поэтому вам нужно прочитать только то, что вам нужно.

В сценарии NetworkManagerCustom в инспекторе есть несколько дополнительных переменных, которые можно сопоставить
Функциональность UNET, но также переменная в коде для определения количества команд для инициализации —
с именем «initialArrayLength». Вам необходимо изменить его значение в методе OnCreatedRoom (), если
вы хотите разное количество команд в игровом режиме

Игровые настройки
Во вступительной сцене под кнопкой «Воспроизвести» вы найдете раскрывающийся список для выбора игрового режима.
чтобы играть. В настоящее время этот актив поддерживает Team Deathmatch, который является режимом по умолчанию, поскольку
а также Capture The Flag. В каждом игровом режиме создается собственный список лобби для подбора игроков.
сервис, чтобы игроки могли только тот режим игры, который им интересен. Будьте осторожны
добавление слишком большого количества игровых режимов: если у вас мало населения, игры могут не заполниться

В правом верхнем углу у игрока есть возможность изменить некоторые настройки игры в
Окно настроек при запуске игры. Это окно содержит поле ввода для ввода
имя игрока, которое синхронизируется по сети и накладывается на модель игрока один раз.
связаны. Также возможен выбор желаемого режима сетевой игры. Более подробно
объяснение реализации сетевого режима приведено в разделе «Дополнительно». Другой
настройки в этом меню влияют только на локального пользователя, например, на управление громкостью музыки или звуковых эффектов.

Выбранные настройки в этом окне сохраняются на устройстве в момент его закрытия, затем
загружается каждый раз при запуске сцены. Скрипт UIMain обрабатывает все это и предоставляет по умолчанию
значения в его методе Start () (в случае первого запуска приложения).
Рядом с кнопкой «Настройки» вы найдете кнопку, которая позволяет пользователям оценивать ваше приложение. Оно делает
поэтому, открыв страницу App Store для вашего приложения с помощью идентификатора пакета вашего проекта.

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

Скрипт IAPProduct, который прикреплен к каждой записи магазина, обрабатывает покупки и
состояние выбора с помощью функции Toggle для всех моделей игроков в ToggleGroup. в
инспектор IAPProduct, необходимо определить значение выбора, чтобы определить, какая модель имеет
был выбран игроком во время выполнения. Это значение сохраняется на устройстве пользователя. Электрический ток
активный индекс выбора модели вместе с именем игрока, введенным в настройках игры.
отправляется на хост игры, завернутый в настраиваемое сообщение JoinMessage (расширяет MessageBase)
класс при подключении. В результате этого запроса на стороне клиента хост точно знает, какой игрок
префаба для создания, сопоставив значение выбора со списком доступных префабов проигрывателя на
NetworkManager Пользовательский инспектор, а также имя игрока.
Когда клиентское соединение со сценой «Игра» установлено, хост (через
NetworkManagerCustom), наконец, назначает команду только что созданному объекту player. Логика
За этим можно найти сценарий GameManager. Проще говоря: он перебирает все существующие
команд, пытается найти команду с наименьшим количеством членов команды и назначает нового игрока
в эту команду. Подробнее о том, что делает GameManager, будет рассказано позже в отдельном разделе.

Игрок
В этой главе объясняется, как клиент и сервер обрабатывают вводимые пользователем данные, выполняя запросы выстрелов,
регистрация полученного урона и возрождение игроков после смерти. Большинство из этих вещей уже сделано
авторитетный (где возможно), что означает, что сервер должен контролировать, что происходит
всегда рядом. Отправляя запросы на сервер вместо того, чтобы выполнять их непосредственно на каждом
клиент, существует более высокий барьер для мошенников при отправке фейковых событий.
К каждому сборному модулю игрока (расположенному в разделе Tanks Multiplayer> Prefabs) прикреплен скрипт Player.
он обрабатывает все сетевое взаимодействие с пользователем. См. Его справочник по сценариям для получения подробных сведений.
описание всех публичных переменных.
Фотон
Чтобы создать экземпляры префабов по сети, Photon необходимо поместить их в папку с именем
‘Ресурсы’. Таким образом, префабы игроков находятся в разделе «Сетевая игра в танках»> «Сборные элементы»> «Ресурсы».

Движение
Для перемещения объекта игрока реализованы два различных элемента управления вводом. На мобильном
устройства, управляемые касанием, одна ручка джойстика отвечает за отслеживание
положение относительно камеры (поэтому угол камеры не имеет значения). Игрок
положение можно изменить, перетащив джойстик. Точная скорость движения и
прослушивание фактических событий ввода перетаскивания выполняется сценарием Player, но направление ввода
изменения вычисляются скриптом UIJoystick, который прикреплен к самому игровому объекту джойстика.
Это означает, что сценарий Player принимает только это направление и применяет его к Rigidbody игрока.
при заданной скорости движения.
Вторая схема управления вводом предназначена для веб-плееров и настольных платформ, то есть устройств без сенсорного ввода. На этих платформах элементы управления джойстиком скрыты (кроме редактора Unity для
для целей отладки), а перемещение осуществляется с помощью клавиш со стрелками на клавиатуре.

Фотон
Движение игрока в Photon передается по сети с помощью его PhotonTransformView.
компонент, прикрепленный к префабам плеера. Подобно UNET / Mirror, этот скрипт выполняет ротацию.
обновления, чтобы сделать их более плавными. Единственная разница в том, что скорость передвижения не
определяется в сценарии Player, но непосредственно в инспекторе для этого сценария. Также PhotonView
Компонент необходим в префабе для наблюдения за поведением синхронизации движения.

Стрельба
Как и в случае с движением, съемка имеет разные схемы управления для мобильных устройств / сенсорных устройств и без сенсорных устройств.
устройства тоже. На мобильных платформах на экране есть еще один джойстик, который вычисляет
направление ввода для сценария игрока, но на этот раз направление используется для поворота турели игрока
и для автоматической стрельбы с небольшой задержкой. Задержка предусмотрена для того, чтобы пользователь мог
установите турель перед тем, как выстрелить первой пулей.
На устройствах без сенсорного управления положение мыши на экране используется для поворота турели. Стрельба из
пуля срабатывает при нажатии левой кнопки мыши (или при ее удерживании). Чтобы проиллюстрировать
текущее вращение башни и направление выстрела, на рабочем столе курсор мыши заменен
со значком в виде перекрестия, установленным в меню «Правка»> «Настройки проекта»> «Проигрыватель» — «Курсор по умолчанию». Поскольку мобильный
на устройствах курсор не виден постоянно, на
Скрипт UIGame, который создается и прикрепляется к турели игрока во время выполнения:

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

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

Только сервер отвечает за определение того, попала ли пуля в игрока или нет. Это потому что
даже если коллизии зарегистрированы на всех клиентах, например для создания эффектов частиц, только сервер
выполняет логику расчета урона игрока. Он делает это, получая значение урона от
пули и применение ее к значению здоровья игрока (или щиту, если таковой имеется). Узнать больше о
тип этих переменных в следующем разделе.
В этом активе есть три типа различных префабов пули, но все они имеют одну и ту же пулю.
к ним прикреплен скрипт. Хотя есть бесконечные боеприпасы для пули по умолчанию, игрок может
стрелять, две другие пули должны быть собраны с помощью бонусов, а также имеют ограниченное количество
боеприпасы — подробнее о бонусах читайте в разделе «Дополнительно». Выбранная пуля
управляется переменной currentBullet в скрипте Player. Замена пуль означает только
изменение этой индексной переменной, так как на все доступные префабы маркеров ссылаются в массиве на
Скрипт плеера для каждого префаба плеера. Это также означает, что разные префабы игроков могут иметь разные
bullets, что позволяет создавать настраиваемые сборки игроков и потрясающие игровые возможности.

Характеристики
В скрипте Player есть несколько сетевых переменных, которые обновляются
сервер всякий раз, когда они меняются. Другим игрокам нужно немедленно знать о переменных.
(текущее здоровье, количество щита и т. д.), которые меняются очень часто, но есть и переменные, в которых
последнее обновление не так важно (например, вращение башни) или вообще не синхронизировано с сетью (например, макс.
здоровье, скорость передвижения и т. д.). Для их синхронизации по сети используются разные подходы.

Фотон
Синхронизированные переменные называются Свойствами игрока и существуют для каждого сетевого объекта / клиента игрока.
Изменения всегда синхронизируются немедленно, т.е. при следующем обновлении сети. Для конкретных событий
изменения (например, здоровье, удары щита и т. д.), которые не меняют каждый кадр, эта функция
большое использование. Все определения пользовательских свойств проигрывателя и средства доступа содержатся в его собственном классе,
скрипт PlayerExtensions.
Если что-то меняется очень часто, свойства игрока могут не подойти. Это верно для
Величина поворота башни полностью контролируется заказчиком и может постоянно меняться. Для этого
сценарий OnPhotonSerializeView пригодится. Этот метод вызывается 10 раз в секунду на
PunBehaviours для синхронизации постоянно меняющихся переменных в сети.

Менеджеры
Менеджеры в Tanks Multiplayer — это скрипты, которые обрабатывают основные функции игры,
предоставление доступа к своим функциям через статические методы (чтобы их можно было вызывать из любого другого скрипта)
или получив прямой доступ через их методы GetInstance (). Мы рассмотрим все важное
сценарии менеджера в следующих разделах, чтобы понять их различные цели.

Игровой менеджер
Начнем с управляющего сценария самой игровой логики. В инспекторе для
Сценарий GameManager в игровой сцене, вы можете определить очень важную игру
такие аспекты, как количество команд в игре, цвет, которым они должны быть визуализированы, а также
в качестве зоны возрождения для каждой команды и максимального количества очков за один раунд. Для полного
Описание каждой переменной см. в справочнике по ее сценариям.
GameManager, скрытый от переменных публичного инспектора, также заботится о счете.
подсчет и заполнение команды для каждой команды, хранящиеся в отдельных списках, размер которых равен размеру команды. Если
игрок умер (что означает, что команда забила), соответствующее значение в списке очков для этой команды идет
вверх. То же самое происходит со списком заполнения, когда подключается новый игрок, но здесь он также может
уменьшение при отключении плеера. Последняя часть полностью обрабатывается NetworkManagerCustom.
скрипт, так как он знает все состояния подключения игрока. Теперь GameManager
отразите эти изменения значений в UIGame, обновив метки и ползунки, отвечающие за
отображение текущих результатов и заполнения команды конечному пользователю.

Фотон
В контексте хранения индивидуальных значений для каждого игрока в сети мы использовали
Свойства игрока уже в разделе Properties. Photon предлагает еще один тип сетевого хранилища
для переменных, которые привязаны не к конкретному игроку, а к игре (комнате) в целом. Этот
функция называется Свойства комнаты. Как и в случае со свойствами игрока, свойства комнаты синхронизируются сразу.
насколько это возможно, и в этом случае они идеально подходят для хранения результатов и командного наполнения игры как
сделано здесь. Определения свойств помещения содержатся в скрипте NetworkManagerCustom.
Скрипт GameManager также является основной точкой доступа для проверки наличия в игре
закончился (в случае, если был достигнут максимальный предел баллов) и потому что в нем есть ссылка на
UIGame, он также переключает отображение смерти игрока и игры поверх окон. С плеером
логика возрождения, показывающая таймер задержки или видеообъявление между смертью игроков, это в основном
все необходимое для работы с игровой логикой в ​​одном месте. Вы можете найти более подробную информацию на нашем
рабочий процесс респауна видеорекламы и раздел «Объявления Unity в разделе« Услуги ».

Фотон
Photon использует тот же подход RPC, что и Mirror (см. Выше), только терминология отличается.
При использовании этого типа RPC авторитетные методы, которые должны быть вызваны на сервере:
с атрибутом [PunRPC]. Затем клиенты могут отправлять сообщения типа запросов для
выполнение на сервере путем инициирования вызова RPC для компонента PhotonView с указанием имени
метода PunRPC. Этот принцип широко используется в скрипте Player.

Аудио менеджер
Скрипт AudioManager прикреплен к неразрушаемому игровому объекту в сцене «Вступление».
во время смены сцены, обрабатывая длинные (фоновая музыка) и короткие (разовые эффекты)
воспроизведение звука по сценам. Используя этот менеджер, мы предлагаем уникальный
компонент для воспроизведения всех видов аудиоклипов, легко доступных с помощью статических методов. У нас нет
чтобы предоставить компоненты AudioSource в сценах, потому что у объекта менеджера есть два
из них — один для музыки, один для однократных звуков), уже прикрепленных к нему. Для одноразовых клипов
которые обычно создаются и уничтожаются по умолчанию, мы также используем собственные
поведение пула объектов, чтобы еще больше уменьшить сборку мусора. За исключением фона
музыкальные клипы, которые можно использовать в разных сценах и на которые есть ссылки в инспекторе
AudioManager, все однократные клипы упоминаются в исходных скриптах (звуки пули
в сценарии Bullet вместо этого воспроизводится звук в сценарии Player и т. д.).


Управляющий пулом
Объединение объектов в пул означает повторное использование игровых объектов вместо их создания и уничтожения каждый раз.
время, когда они нужны. Поскольку сборщик мусора Unity очень требователен к производительности и может
приводить к серьезной икоте и пропуску кадров во время игры, этот актив реализует строгие
объединение (активация / деактивация) игровых объектов, необходимых несколько раз в одной сцене. Таким образом
instantiate и destroy следует заменить на PoolManager.Spawn и .Despawn.
Настроить пул объектов в вашей сцене очень просто:
— иметь контейнерный игровой объект со сценарием PoolManager в сцене
— под этим контейнером добавьте один или несколько дочерних игровых объектов и назовите их по своему усмотрению
— добавьте скрипт Pool к этим дочерним игровым объектам и введите свою конфигурацию в инспекторе
— если префаб имеет NetworkIdentity / NetworkObject, он автоматически считается подключенным к сети
Выполнено!

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


Сетевой режим
В самом начале в меню настроек вступительной сцены у вас есть возможность выбрать
сетевой режим, с которым вы хотите поиграть. Каждый сетевой режим использует совершенно разные сети.
слой, но все они обрабатываются внутри сценария NetworkManagerCustom автоматически, поэтому
чтобы игроков не путали сложные интерфейсы или дополнительные кнопки типа ввода IP
адреса (кроме Photon LAN) и так далее.
Онлайн: выбрано по умолчанию. Это пытается использовать серверы облачного сопоставления для автоматического сопоставления
создание и объединение, как описано ранее в этом документе, что является самым простым способом получить правильные
в бой и играйте против других игроков. Тайм-аут для поиска совпадения и присоединения к нему установлен на
10 секунд, которые могут быть достигнуты из-за проблем с подключением или сетевым подключением устройства.

Фотон
Обратите внимание, что в Photon нет явного режима LAN. Вы загрузили и запустили
Photon Server на вашем собственном компьютере / сервере, подключенном к Интернету, чтобы настроить
частная сеть. Вы можете узнать больше об этом процессе здесь. Если вы выберете режим LAN в
В меню настроек Intro появится дополнительное поле ввода, чтобы вы могли ввести адрес своего сервера.

Оффлайн: игра против ботов. Этот режим моделируется путем создания частной игры по локальной сети, но без
сделать его общедоступным для других устройств. Большим преимуществом этого является отсутствие изменений в
необходим существующий сетевой код. Боты управляются классом PlayerBot, производным скриптом от
класс Player, который использует навигационную систему Unity для перемещения. Затем они получают
порождается BotSpawner после того, как игрок присоединяется к игровой сцене.


Миграция хоста
Host Migration описывает концепцию, при которой игра продолжает работать с минимальным прерыванием.
когда хозяин матча ушел. Суть этого заключается в том, что после отключения хоста один из
подключенные клиенты берут на себя роль хостинга игры, чтобы поддерживать ее жизнь. Отключенный
хост может даже позже присоединиться к той же игре в качестве клиента. Использование миграции хоста прекращено
игры из-за временной потери соединения и выхода из-за ярости хоста. Для
эффективно используя миграцию хостов, следует отметить, что при переключении хостов используются только те данные, которые
доступный на клиенте, став новым хостом, будет сохранен в игре. Это, в свою очередь, означает, что
любые данные, доступные только на сервере, теряются после миграции хоста. Итак, вы должны планировать
заранее определить, какие данные должны быть синхронизированы между всеми клиентами, и построить сеть клиент / сервер
код вокруг этого принципа.

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

Коллекционные предметы
Коллекционирование — это предметы, которые игроки могут использовать для повышения своей эффективности в игре.
Скрипт Collectible работает как шаблон для различных бонусов, например, для
Скрипты PowerupBullet или PowerupHealth. Если вы хотите создать новые бонусы, просто
расширите свой скрипт из Collectible и переопределите его метод Apply. Этот метод отвечает за
что делать, когда игрок собирает усиление, поэтому вся ваша логика коллекционирования должна быть здесь.
Сборные элементы для всех типов коллекционных предметов находятся на панели проекта в разделе «Сетевая игра с танками»>
Сборные. Как и пули, у предметов коллекционирования есть собственный бассейн в игровой сцене, использующий наши
PoolManager в их поведении при появлении. Фактическая инструкция по нересту исходит от
ObjectSpawner в сцене, который позволяет вам определять точное положение и задержку респауна.
Сетевые переменные в этом активе (см. Главу Свойства) совместимы с миграцией хоста.
уже, поскольку они распространяются среди всех клиентов. Коллекционирование — отличный пример
что-то, что несовместимо с миграцией хоста с самого начала, потому что они полагаются на
синхронизированные состояния игрового объекта, то есть изменения иерархии (активный / неактивный) в сцене. Какие мы есть
синхронизация состояний игровых объектов (и таймера возрождения) осуществляется через управляющий скрипт ObjectSpawner. В
В этом случае у нас есть три возможных результата для синхронизации:
✓ Активные бонусы должны быть видны всем клиентам: каждому ObjectSpawner и Collectible.
к экземпляру подключен уникальный сетевой компонент, поэтому все клиенты знают о своих
существование на сцене уже. Когда хост запускает powerup, каждый клиент сохраняет
ссылка на локальный игровой объект, который он только что порождал через ObjectSpawner.
✓ Неактивные включения питания должны быть невидимы для всех клиентов: инструкции удаления по сети
обрабатываются нашим PoolManager автоматически. Присоединение к клиентам создаст неактивный
сами по себе, в соответствии с инструкциями главного клиента или сценария миграции хоста.
✓ Текущий таймер возрождения: после сбора бонуса сервер запускает
сопрограмма на ObjectSpawner, ожидающая окончания задержки респауна. Если хозяин
отключается сейчас, новый хост не будет знать, где он остановился, т.е. когда возродить
powerup. Из-за этого ObjectSpawner экономит оставшееся время респауна на всех
клиенты исчезают. Это гарантирует, что мы полностью осведомлены обо всех сценариях миграции хоста.

Фотон
В Photon единственный объект, которому требуется PhotonView, — это ObjectSpawner. Каждый предмет коллекционирования
Затем экземпляр может обрабатываться локально на клиенте. Отношения между предметами коллекционирования и
их источник также устанавливается локально, напрямую через ObjectSpawner, который создает экземпляр бонуса.
Синхронизация коллекционных состояний для присоединения клиентов или нового главного клиента осуществляется через Photon’s
обратные вызовы:
OnPlayerEnteredRoom: главный клиент отправляет, следует ли создать экземпляр объекта или
порожденный позже
OnMasterClientSwitched: новый главный клиент решает, нужно ли
запустить

Режимы игры
В каждом игровом режиме есть отдельная очередь подбора игроков, как описано в настройках игры.
раздел. В указанном игровом режиме карта, загружаемая для новой комнаты, случайна. Это работает
путем определения режимов игры и назначения сцен.
Если вы хотите создать совершенно новый игровой режим, сначала вам нужно
определите его в перечислении GameManager с именем GameMode.
Чтобы назначить сцены для этого игрового режима для службы подбора игроков,
тогда ваши сцены должны соответствовать соглашению об именах GameMode.
Это означает, что для сцены командного боя насмерть сцена должна начинаться с «TDM».
Кроме того, выбираются только сцены, которые добавляются и активны в настройках сборки Unity. Этот
позволяет тестировать новые карты, не влияя на живые сборки. Наконец, в GameManager сцены
инспектор, выберите GameMode, для которого карта была разработана

Поскольку командный бой насмерть является режимом по умолчанию, в следующем разделе описываются только
отличия от Capture The Flag (CTF). CTF основан на предметах коллекционирования. Упомянутые бонусы
раньше расходуются непосредственно при столкновении, но собираемые предметы можно подобрать,
упал и вернулся тоже! Все это также обрабатывается управляющим ObjectSpawner.
К флагам в CTF прикреплен скрипт CollectibleTeam,
который отвечает за проверку команды игрока перед выполнением
желаемая логика: поднять флаг врага, вернуть свой флаг, если его сбросили.
В связи с этим переменная «Индекс команды», присвоенная в инспекторе, является
команда, владеющая этим предметом коллекционирования.
Чтобы охватить несколько различных сетевых подходов в этом активе, новый тип
синхронизация используется для получения / сброса / возврата предметов коллекционирования.

Фотон
Буферизованные RPC похожи на обычные RPC, но запоминаются на сервере и выполняются для новых
присоединение к игрокам. Мы используем эту концепцию для коллекционирования, просто вызывая обычный метод RPC.
на целевом ObjectSpawner и передав RpcTarget.AllBuffered при вызове. В зависимости от
выполненное действие (поднять или сбросить), тогда дополнительная переменная (носитель или позиция)
предоставляется всем клиентам. Исключением является RPC для возврата сброшенного Коллекционного предмета, который
без буферизации: по умолчанию используется предмет коллекционирования в исходном положении, поэтому нам не нужно
явно сохраните это для подключения игроков — Коллекционный предмет в любом случае появится там. Каждый
при отправке нового буферизованного RPC мы удаляем все предыдущие RPC, связанные с этим PhotonView.
С нашей реализацией для предметов коллекционирования мы не хотели бы хранить бесконечное количество записей.
каждый раз, когда игрок поднимает или роняет коллекционный предмет — только последнее действие. Для этого,
мы сначала ищем существующую запись об этом, а затем изменяем ее. Обратите внимание, что буферизованный
RPC для Photon — это образец для демонстрации другого сетевого подхода. В этом случае,
поскольку мы храним только самые последние RPC, те же функции могут быть легко достигнуты
сохраняя необходимые переменные в самом коллекционном объекте и позволяя клиентам запрашивать их
с сервера с помощью одного вызова RPC.

С сетевой функциональностью для
сборы сделаны, нам все еще нужен способ
определить, забил ли игрок
получить вражеский флаг на свой собственный
база. В режиме CTF у нас есть
добавлена CollectibleZone
компонент по этой причине.
Компонент CollectibleZone, включая BoxCollider для обнаружения игрока или предмета коллекционирования.
collisions, прикрепляется к игровому объекту в сцене, определяя базу для одной команды. Если
переменной «Require Object» назначается ObjectSpawner, этот конкретный объект должен
присутствовать на своей домашней базе до того, как игрок сможет забить. В CTF-сцене и на скриншоте
выше, это означает, что Команда = 0 (Красная команда) может забить, только получив синий флаг, если
требуемый объект (свой — красный флаг) находится у их основания. Если параметр «Требовать объект» не назначен,
игроки также могут забивать, когда кто-то другой взял их собственный флаг.

Сервисы Unity
Согласно их собственной целевой странице, Unity предлагает ряд услуг, чтобы помочь разработчикам игр.
взаимодействовать со своими игроками, понимать, как они играют в ваше приложение, и монетизировать их в
самый действенный способ. В этом активе мы постарались интегрировать как можно больше сервисов в
области это имело наибольший смысл. Обратите внимание, что ни одна из следующих служб не требуется для запуска
игра. Вы можете просто отключить их на панели сервисов в редакторе Unity, и никто не будет жаловаться.
ИПД
Этот актив использует Unity IAP и интегрирует очень простую реализацию для внутри приложения.
покупки. Если вы хотите изучить полнофункциональную систему магазинов с реальными деньгами и виртуальными
покупки валюты, ознакомьтесь с нашим активом Simple IAP System в Unity Asset Store.
Чтобы покупки в приложении работали, вы должны сначала создать приложение в соответствующем магазине приложений.
аккаунт, а затем создайте там продукты. Обратите внимание, что в зависимости от App Store, который вы развертываете
до, при тестировании покупок в приложении действуют определенные ограничения. Например, для Google Play требуется
ваше приложение будет отправлено и опубликовано как альфа / бета версия (не черновик).
Создав свое приложение и продукты в App Store, откройте сцену вступления и посмотрите на
наш магазин IAPProducts снова в инспекторе. У них есть идентификатор и тип, определенные в
там. Это должен быть ваш идентификатор и тип, используемый при создании продуктов в Приложении.
Магазин. Вы также заметите, что при открытии окна магазина на iOS есть дополнительная
кнопку вверху (выделено на следующем снимке экрана). Эта кнопка обрабатывает восстановление
покупок, потому что в соответствии с требованиями Apple ваше приложение будет отклонено, не получив его.
Сценарий UnityIAPManager обрабатывает инициирование и обработку покупок в приложении. Если ты
используя записи в магазине, как и в случае с продуктами IAP, представленными в этом активе, у вас уже есть покупка
Танки Мультиплеер FLOBUK

связанная с ними кнопка в пользовательском интерфейсе. Если вместо этого вы хотите инициировать покупку напрямую с помощью кода,
вы можете сделать это, вызвав UnityIAPManager.PurchaseProduct. В этом случае вам нужно будет добавить
идентификатор продукта для построителя закупок в методе Start () вручную.
Объявления
Здесь объясняется, как включить Unity Ads (вы можете пропустить части кодирования).
Вместо того, чтобы подталкивать пользователей к покупкам в приложении, лучше всего подходят видеорекламы (или реклама в целом).
альтернатива монетизации игр Free2Play. Особенно не быть навязчивым и ограничивать рекламу
количество за сеанс пользователя, чтобы максимизировать доход от рекламы. В этом активе, когда игрок
dies отображается счетчик респауна. Если Unity Ads включен, мы заменяем респаун
счетчик с видеообъявлением один раз в каждом раунде. Одно объявление за раунд (~ 0,5 цента на пользователя) должно быть
достаточно, чтобы оплатить счет за сервер за этот раунд. Процентный шанс показа видеообъявления
увеличивается при каждой смерти игрока, пока не будет показано одно объявление максимум через 6
попытки / смерти. См. Скрипт UnityAdsManager для подробных комментариев о шансе показа рекламы.
расчет. Сценарий также полностью обрабатывает неудавшиеся запросы объявлений.
Подводя итог, рабочий процесс видеорекламы при смерти игрока выглядит так:
Объявление готово пропущено / завершено
Показать рекламное объявление не готово
Показать счетчик
с объявлениями True
Ложь
Результат
без рекламы
респаун
респаун
Танки Мультиплеер FLOBUK

Контакт
Поскольку предоставляется полный исходный код и каждая строка хорошо документирована, пожалуйста, посмотрите
в сценариях и измените их в соответствии со своими потребностями.
Если у вас есть какие-либо вопросы, комментарии, предложения или другие опасения по поводу нашего продукта,
не стесняйтесь обращаться ко мне. Вы найдете все важные ссылки в окне «О программе», расположенном
в разделе Window> Tanks Multiplayer.
Если вы хотите поддержать меня в Unity Asset Store, напишите здесь небольшой обзор, чтобы
другие разработчики могут составить мнение. Еще раз спасибо за вашу поддержку и удачи с
ваши приложения!