Creating a Multiplayer Game
![]()
Multiplayer games are games that are designed to be played by multiple people at the same time. They can be made and played on the same computer (local multiplayer) or with different computers from different places through the use of cloud variables.
| Note: | Please remember the 256-character limit that was imposed on Cloud Variables with the release of Scratch 3.0. |
Contents
- 1 Local Multiplayer
- 2 Online Multiplayer
- 2.1 Variables
- 2.2 Coding
Local Multiplayer
Since local multiplayer games are played on the same computer for several players, they don’t use cloud variables. Local multiplayer games are based off the following scripts:
A script is made for the first player:
when green flag clicked forever if then move(-10) steps end if then move (10) steps end
A script for the second player is made. Notice the different keys both players press to move left and right.
when green flag clicked forever if then move(-10) steps end if then move (10) steps end
The scripts can be programmed differently depending on what is needed for the project. When creating a local multiplayer game, one player usually controls one side of the keyboard, such as the number keys or arrow keys, and the other player uses the other side of the keyboard, such as the W, A, S, D, and/or F keys. This makes the game easier to play. However, a downside is that on some laptop computers, a keyboard may only input a certain number of keys before reaching a maximum and not detecting any newer keys being pressed.
Online Multiplayer
Online multiplayer games use cloud data. There are many ways to make an online multiplayer game, however each way requires that you attain full scratcher status. Scratchers with the New Scratcher status cannot do this because of the restrictions placed upon cloud variables.
Realistic online multiplayer games or MMOGs are not very common due to cloud data limits and the non-existence of cloud lists. However the code below simplifies the basics of a multiplayer game.
Variables
Firstly, cloud variables need to be created to help with movement and detecting if a player is still active.
These variables have to be created:
Note: It is possible to use less variables by using a variable for 2 purposes, but that can be more complex. (☁ cloud check)//This checks to see if the two players are connected. set to 1. (☁ Player1 check)//This checks if player1 is still on (☁ Player2 check)//This checks if player2 is on (☁ Player1 coords)//This sends coordinates from player1 (☁ Player2 coords)//This sends coordinates from player2 (local player1 check)//This checks if player1 is still on (not cloud) (local player2 check)//This checks if player2 is still on (not cloud) (Player ID)//This says what sprite you are controlling
Coding
Once those variables are created, it is needed to check if anyone else is on the project and to connect the player to the cloud with a slot if needed.
Backdrop
Note: The connection test does not work if you are not signed in, disconnected from the Internet, or a New Scratcher. However, it can still see cloud data. You still have to make the variable be 0 in the editor, though. when green flag clicked broadcast (start v)//Have it so that there is only 1 green flag clicked wait (2) secs//This makes sure the project is connected to the cloud set [☁ cloud check v] to [0]//If the player is a new scratcher or offline this should not work set [☁ cloud check v] to [1]//Then this won't work either if <(☁ cloud check)=[1]>then//If it equals 1, they are connected, if not, they are not set [local player1 check v] to (☁ Player1 check) set [local player2 check v] to (☁ Player2 check) wait (5) secs //It's waiting because if a player is active, the player 1 and 2 cloud variables will change every second so it is needed to make sure by waiting 5 if <(local player1 check)=(☁ Player1 check)>then//If the cloud check has not changed it means that nobody is playing as player 1, therefore, the player has been set as player1 set [Player ID v] to [1]//Not cloud because the cloud variable for player1 will be updated so that other computers know that there is a player1 set [☁ Player1 check v] to [0]//So it does not get that variable up to a million eventually set [☁ Player1 coords v] to [500500]//The coordinate system adds 500 to each coordinate because then every number is a positive 3 digit number and an encoder or decoder is not necessary, basically, that is 0,0 broadcast (joined v)//This sends a message to every sprite telling them to do their code else if <(local player2 check)=(☁ Player2 check)>then//This is doing the same thing as above but if there already is a player1, it is needed to check for a player2 set [Player ID v] to [2] set [☁ Player2 check v] to [0] set [☁ Player2 coords v] to[500500] broadcast (joined v) else broadcast (full v)//If both slots are taken a sprite is needed to tell the player the game is full end end else broadcast (not connected v)//if the cloud test run at the beginning fails, it is needed to tell them they are not connected to the cloud or are a new scratcher end set [☁ cloud check v] to (0)
Add this script for Player1’s sprite.
when I receive [joined v] wait (1) secs//So that the sprite that tells you stuff has time if <(Player ID)=[1]>then forever//This is the movement script if then//This code is for the movement of Player1. change x by (3) end if then change x by (-3) end if then change y by (-3) end if then change y by (3) end set [☁ Player1 coords v] to (join((x position)+(500))((y position)+(500)))//Telling all the other computers player1's position with the plus 500 method mentioned earlier end else forever//If the player ID isn't one the sprite of player1 will go to the coordinates, again using the 500 method, but this time it is needed to subtract because these are the ones received from the other computer so they have already had 500 added go to x:((join (letter (1) of (☁ Player1 coords))(join (letter (2) of (☁ Player1 coords))(letter (3) of (☁ Player 1 coords))))-[500])y:((join (letter (4) of (☁ Player1 coords))(join (letter (5) of (☁ Player1 coords))(letter (6) of (☁ Player 1 coords))))-[500]) end end when I receive [joined v] if <(Player ID)=[1]>then forever change [☁ Player1 check v] by (1)//At the beginning, when the project is first run there is a five second wait for this variable to change, because after that whether there is a player1 or not is recorded wait (1) secs end
This script is for Player2’s sprite. All of player1’s variables are transferred to player2’s variables.
when I receive [joined v] wait (1) secs if <(Player ID)=[2]>then forever if then change x by (3) end if then change x by (-3) end if then change y by (-3) end if then change y by (3) end set [☁ Player2 coords v] to (join((x position)+(500))((y position)+(500))) end else forever go to x:((join (letter (1) of (☁ Player2 coords))(join (letter (2) of (☁ Player2 coords))(letter (3) of (☁ Player 2 coords))))-[500])y:((join (letter (4) of (☁ Player2 coords))(join (letter (5) of (☁ Player2 coords))(letter (6) of (☁ Player 2 coords))))-[500]) end end when I receive [joined v] if <(Player ID)=[2]>then forever change [☁ Player2 check v] by (1) wait (1) secs end
This script is for telling players of errors (such as an error connecting to the game).
when gf clicked go to x:(0) y:(0)//Makes the sprite go to the center so it's easier to see go to [front v] layer show switch costume to (connecting v)//Costume that tells the player "connecting" when I receive [full v] switch costume to (full v)//costume that tells the player "Sorry, there are no open slots, please try again later" when I receive [not connected v] switch costume to (not connected v)//Costume that tells the player "sorry you are either a new scratcher or are not connected to the cloud" when I receive [joined v] if<<<(Player ID)=[1]>and<(☁ Player2 check)=(local player2 check)>>or<<(Player ID)=[2]>and<(☁ Player1 check)=(local player1 check)>>> then//If the other player wasn't active switch costume to (no one else on v)//Costume that tells the player "slot found and connected but no one else is online" else switch costume to (someone else found v)//Tells the player "slot found and connected someone else is online" end wait (1) secs//The player(s) will get a second to read this message hide//Gameplay begins
Как создать свою первую игру: видеоуроки Scratch для детей
В сегодняшней статье я покажу видеоуроки Scratch и подробно разберу процесс создания игр на Scratch версии 3.0.
Визуальная среда Скретч идеально подходит для изучения программирования детьми уже с 6 лет. В Скретч код состоит из визуальных блоков, которые можно сцеплять между собой. Перетаскивая блоки и соединяя их между собой, дети учатся алгоритму построения кода и созданию простых игр и программ.
Среда Scratch разработана медиа-лабораторией Массачусетского технологического института, последняя версия — Scratch 3.0 — совместима с мобильными устройствами и наборами наборами LEGO Education, а также адаптирован интерфейс для работы с планшетами. Благодаря этому, в Scratch дети также могут создавать сложные интерактивные проекты: анимированные презентации, мультфильмы и игры, рассчитанные на нескольких пользователей.
Начать изучение Scratch ребенок может уже в 6 лет. Для дошкольников существует отдельная версия этого языка — Scratch Junior. Подробнее о нём я писал в этой статье.
В сегодняшней статье я подробнее разберу процесс создания игр на Scratch версии 3.0.
Охота за привидениями
Простая игра для двоих пользователей, где нужно стреляться по призракам и набирать баллы.

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

Гонки на двоих
Давайте попробуем посоревноваться на гоночной трассе. Для этого сначала спроектируем ее, а потом запусти игру.

Мультиплеерная игра
Помимо создания сетевой игры, на этом уроке мы рассмотрим переменные и их значение в коде.

Звездные войны
Программируем космический корабль и атакуем корабль соперника.

Головоломка Minecraft
Воссоздаем мини-вселенную Майнкрафт и стараемся как можно быстрее добраться до сундука в игре.

Among Us. Часть 1
Воссоздаем любимую игру, а также пытаемся вычислить самозванца на борту.

Among Us. Часть 2
Совершенствуем карту и сбиваем астероиды.

Создаем Flappy Bird на Scratch
Моделируем игру-платформер с прыгающей птичкой.

Brawl Stars (Бравл Старс)
Пробуем создать игру менее, чем за 45 минут!

Собираем программу с нуля, в которой будут создаваться трехмерные объекты.

Создаем игру за 15 минут
Поверьте нам, это не так сложно!

Игровое меню на Скретч
Создаем игровое меню — лобби.

Обязательно попробуйте создать свои игры на Scratch, делитесь ими с друзьями и в официальном сообществе на сайте https://scratch.mit.edu/.

Следите за новыми постами по любимым темам
Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.
Как сделать игру Танчики на Scratch
Кружок «Робикс» приветствует вас на новом уроке по разработке игр для начинающих. Сегодня мы самостоятельно создадим вариант одной из самых культовых игр – Танчики. Особенность этой игры – мультиплеер, вы не только сами ее напишите и сделаете дизайн, но и сможете протестировать вместе с другом. Попробуем?
В этом цикле уроков мы используем программу Scratch – простая и интуитивно понятная среда для будущих гейм-дизайнеров и тех, кто хочет попробовать себя в программировании. Scratch бесплатный и для начала его можно даже не скачивать. Все, что необходимо, уже есть в онлайн-версии. Переходим на Scratch и начинаем.
На нашем сайте уже есть подробный обзор интерфейса и основных инструментов Scratch. Если вы впервые столкнулись с программой, то советуем начать с него – вам будет проще ориентироваться в уроке.
Полезные ссылки из нашей базы знаний:
- Интерфейс и инструменты Scratch
- Что такое спрайт?
- Блоки движения
- Условия в Scratch
Если вы будете внимательно читать урок и разберете каждый шаг, то уже совсем скоро сможете самостоятельно написать собственную игру без нашей помощи или усовершенствовать эту. Вперед!
Немного о Танчиках
Первая версия игры вышла в 1985 году в Японии и называлась она «Battle City». Уже больше 35 лет назад! Эта игра была для приставок, ее компьютерная версия вышла спустя несколько лет. Однако «Battle City» не пользовалась популярностью на родине. Зато в России – это настоящий символ эпохи. В 90-е годы появилась «пиратская» версия, сделанная в Китае – «Tank-1990», именно она произвела фурор и получила народное название «Танчики». С тех пор как вышла первая версия, разработчики перевыпускают улучшенные версии игры и насыщают ее дополнительными функциями. Забавно, что «Танчики» сохранили свой интерфейс, даже в самых последних современных версиях, где по карте передвигаются 3D танки, мы узнаем прототип 1985 года. Игрок смотрит на поле боя сверху вниз, а на экране – танки разных команд и препятствия.

Создаем первый танк
Переходим в режим рисования, программа автоматически переводит нас во вкладку «Костюмы». Для этого наводим мышь на круглую кнопку с мордочкой кота и выбираем кисть. Если вам не хочется рисовать, можно выбрать героя из встроенной галереи: для этого щелкаем по коту и выбираем любого понравившегося персонажа.


Но мы нарисуем танк сами. Он может быть каким угодно: с длинным дулом или коротким, ярким или нейтральным, с люком и без.
Танк состоит из 4 прямоугольников и 2 кругов. Сначала рисуем корпус танка – самый большой прямоугольник, по бокам два тонки и вытянутых – гусеница, прямо сверху на корпусе рисуем дуло и рядом с ним кружок – люк и кружок поменьше – крышка люка. Такой танк у нас получился.


Обязательно проследите, чтобы центр вашего танка — синий плюсик- сходился с центром поля (Рис. 5), потому что иначе танк потеряется в пространстве, запутается, а мы вместе с ним.
Давайте закончим оформление нашего танка настройками. На панели спрайтов есть есть графа для ввода, сейчас там написано «Спрайт 1». Мы предлагаем сразу изменять имена, чтобы в процессе программирования не путаться. Мы назовем наш спрайт – Танк 1, можно использовать свое имя и имя друга. Если вам покажется, что танк слишком большой и занимает много места на сцене, на этой же панели есть настройка размера. Базово это значение 100 (%), но мы предлагаем уменьшить до 50.
Когда рисунок будет готов, переходите во вкладку «Код» (сверху слева).
Настройки танка
Давайте закончим оформление нашего танка настройками. На панели спрайтов есть есть графа для ввода, сейчас там написано «Спрайт 1». Мы предлагаем сразу изменять имена, чтобы в процессе программирования не путаться. Мы назовем наш спрайт – Танк 1. Но вы можете использовать свое имя или имя того, с кем вы хотите сыграть.
Если покажется, что танк слишком большой и занимает много места на сцене, на этой же панели есть настройка размера. Базово значение 100 (100%), но мы предлагаем уменьшить до 50.
Когда рисунок будет готов, переходите во вкладку «Код» (сверху слева).
Учимся управлять танком
Научим наш танк передвигаться по сцене. Для того, чтобы это сделать переходим в группу «События» (слева) и выбираем блок «Когда зеленый флажок нажат». Именно эта кнопка запускает игру. Перетаскиваем его на рабочую панель справа. Мы будем перемещать сюда все блоки кода. Блоки магнитятся, достаточно приблизить их друг к другу.
Обратите внимания, что блоки разной геометрической формы – это подсказка. Если в блоке отверстие в виде ромба, то ни квадратный, ни круглый блок туда не подойдут. Нужно искать условие в соответствии с формой.

Далее: группа «Управление» и перетаскиваем блок «Повторять всегда».
Все действия, которые мы переместим внутрь этого блока, будут повторяться бесконечное количество раз, пока нажат зеленый флажок.
Добавляем внутрь нашей конструкции еще одно условие из группы «Управление»: «если , то». Дополнения условий хранятся в группе «Сенсоры». Посмотрите, их края в виде ромбов, такие же, как в отверстие блока «если, то». То, что надо! Наш первый танк будет управляться при помощи стрелок, поэтому мы перетаскиваем блок «клавиша нажата», а вместо пробела выбираем «стрелка вверх» (Рис. 7.).

Стрелка вверх – это движение вперед. Переходим в группу «Движение» и выбираем «идти 10 шагов». Получилось, что если «клавиша стрелка вверх нажата», то наш танк «идет 10 шагов». Повторяем условие для всех направлений движения. Обратите внимание, что для движения назад значение должно быть отрицательным: «идти -10 шагов», танк как будто отталкивается назад. Для движения в стороны выбираем блоки «повернуть на 15 градусов». У нас получилась такая структура (Рис. 8.).

Для скорости вы можете изменить значения в блоках: чем больше цифра, тем быстрее двигается танк.
Направление движения
Уже на этом этапе, вы можете нажать на зеленый флажок и покрутить танк с помощью стрелок. Если мы все сделали правильно – танк зашевелился по сцене. Он отлично крутится в стороны, а вот вперед-назад ходит как-то странно, верно? Давайте разбираться.
Чтобы прервать выполнение всех скриптов, используем красную кнопку рядом с зеленым флажком.
Если нажать на кнопку «Направление» в панели спрайтов, то вы увидите круг и стрелку. Стрелка показывает, куда на самом деле смотрит спрайт. Сейчас он смотрит по диагонали вправо, поэтому для него вперед и назад – это движение по диагонали, несмотря на то, что дуло смотрит совсем в другую сторону (Рис. 9.).

Как же это исправить? Нам нужно снова перейти во вкладку «Костюмы», выделить танк с помощью стрелки и покрутить его так, чтобы синхронизировать направление дула и стрелку на кружке справа, как показано на Рис. 10. Готово! Теперь танк правильно двигается во все стороны.

Поле боя
Танку необходима база. Давайте займемся сценой и нарисуем препятствия (стены и лабиринты).
Справа от панели спрайтов находится панель «Сцена», щелкаем на нее. Сверху место вкладки «Костюмы», появилась вкладка «Фон», выбираем ее и автоматически перемещаемся в режим рисования – сейчас будем строить.
Конфликт (взаимодействие/столкновение) между предметами в гейм-деве называется коллизия. Мы будем обрабатывать коллизию по цвету, то есть цвет стены должен быть уникальным. Если цвет танка и стены будет одинаковым, то могут возникнуть проблемы. Мы выбрали цвет и при помощи «Прямоугольника» нарисовали стену.

Обрабатываем коллизию
Переходим во вкладку «Код» и два раза щелкаем по танку. Если мы сейчас попробуем его подвигать, то увидим, что танк игнорирует препятствие и наезжает на стену, как будто это плоский рисунок на полу, а не объемное сооружение. Не дела…
Добавляем нашему танку еще одно условие из группы «Управление»: «если , то». Оно должно стоять внутри предыдущего! Заходим в группу «Сенсоры» и выбираем условие «касается цвета» (добавляем нужный — можно воспользоваться пипеткой). У нас получилось двойное условие: если стрелка вверх нажата, то танк едет вперед, и если танк идет вперед, он касается нашего запрещенного цвета, то он не может продолжать движение и идет назад (Рис. 12).

Повторяем конструкцию для движения назад. Только в этом случае танк должен двигаться вперед. Не забывайте добавлять и удалять минус в значение в зависимости от направления.
Стена может заблокировать наши действия, поэтому танк должен отталкиваться от нее, пружинить. Чтобы не попасть внутрь стены, в условии касания нужно прописать бОльшее количество шагов, чем в первом значении. Например, если по стрелке вверх танк делает 10 шагов, то касаясь запрещенного цвета, он едет 12 назад, чуть отпрыгивает.
Теперь наш танк не сможет заехать внутрь стены. Вы можете нарисовать любое количество стен или сделать игровое поле с лабиринтами. Главное – танку нужно место для движения!

Переходим к стрельбе
Чем стреляет танк? Вообще у этой техники свои специальные танковые снаряды, но чтобы скорее начать играть, мы нарисуем нашему танку ядра. Давай создадим новый спрайт, который так и назовем – Ядро 1. В нашем случае это просто красный круг, но вы можете включить фантазию и изобразить полноценный танковый снаряд!

Логика движения ядра
Как будет осуществляться стрельба: когда мы нажимаем любую клавишу, создается клон нашего спрайта, который переходит в координаты танка, как будто вылетает из него, и летит в ту сторону, куда смотрит танк. Вроде все просто.
Переход во вкладку «Код». Для ядра мы еще ничего не писали, поэтому как всегда переходим в группу «События» и выбираем блок «Когда зеленый флажок нажат». В начале игры наше ядро не должно быть видно, поэтому переходим в группу «Внешний вид» и выбираем «спрятаться».
Этот блок должен быть отдельно от блока «повторять всегда», так как ядро прячется один раз в начале игры и никогда не показывается.
Переходим в группу «Управление» и выбираем «повторять всегда». Из группы «Управление» вновь берем условие «если, то» и в «Сенсорах» выбираем «клавиша нажата». Этой кнопкой будет стреляться наш танк. Мы выбрали пробел.
Наше основное ядро спрятано, поэтому в тот момент, когда мы будем стрелять, по условию будет создаваться его клон. Переходим обратно в группу «Управление» и выбираем «создать клон самого себя».

Условие для клона ядра
Следующие условия мы будем задавать клону. Нам нужно синхронизировать положение Ядра 1 и положение Танка 1. В группе «Управление» выбираем блок «когда я начинаю как клон» и из группы «Внешний вид» обязательно добавляем «показаться», ведь на предыдущем шаге мы спрятали наше ядро. Переходим в группу «Движение» и выбираем: «перейти в x…, в y..». Вместо каких-либо значений, нам нужно задать унаследование от Танка 1. Для этого переходим в «Сенсоры» и выбираем блок (Рис. 16.). Добавляем его в оба кружка. Сначала меняем от кого – в нашем случае «Танк 1», а затем выбираем переменную – x, а затем y. Должно получится вот так (Рис. 17.).


Но ядро должно и лететь в направлении танка, поэтому из группы «Движение» выбираем «повернуть в направлении» и вновь вместо значения добавляем блок из группы «Сенсоры» (см. Рис. 16). Направление наследуется от Танка 1.
Если сейчас мы добавим нашему ядру блоки движения, то он будет игнорировать и нашего противника, и стены вокруг. Поэтому ядро должно лететь до тех пор, пока чего-нибудь не коснется. Переходим в группу «Управление» и выбираем «повторять пока не», а в качестве условия добавляем из группы «Операторы» блок «или». Так как условие тройное, мы создаем два ИЛИ и соединяем их как показано на Рис. 18.

Касания ядра
Из группы «Сенсоры» добавляем условия: «касается край», «касается цвета» (цвет наших стен) и последнее условия должно относится к Танку 2. Самое время его создать. Но сначала закончим с ядром, а пока оставь последнее условие пустым.
Внутрь условия добавляем блок из группы «Движение»: «идти на 10 шагов». Повторим, чем больше значение, тем быстрее движется предмет. 10 для ядра – это не серьезно, наш танк легко уедет от такого снаряда, поэтому мы поставим значение 20.
После того, как ядро попадает в одно из наших условий, оно должно исчезнуть. Заходим в группу «Управление» и завершает этот кусок кода блоком «удалить клон». Этот блок нужно вынести за пределы условия «повторять пока не«.
Давайте скорее настроим второй танк и попробуем пострелять!
Создаем второй танк
Чтобы на нашей сцене появился второй танк, продублируем первый. Нажимаем на него правой кнопкой мыши и выбираем «Дублировать».

На экране появился второй танк, но пока они двигаются одновременно, потому что оба настроены на движение по стрелкам. Сейчас мы это исправим. Но сначала давай поменяем название спрайта на Танк 2 (или имя) и попробуем пострелять! Возвращайся в код Ядра 1, и добавь в условие – «касается Танк 2».

У нас все заработало и Танк 1 стреляет, а у вас?
Давайте поработаем над дизайном Танк 2 – изменим его цвет и кнопки управления.
Чтобы изменить цвет, нажимаем на второй танк, выбираем «Костюм» и с помощью заливки изменяем цвет. Проверьте, чтобы центр этого танка также совпадал с центром поля!
Если первый танк у нас двигается с помощью стрелок, то второй будет двигаться классическим сочетанием букв – WASD. (w – вверх, s – вниз, a – лево, d- право). Нам практически не нужно менять код, осталось только заменить стрелки на буквы (Рис. 22).

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

Надеемся, у вас все получилось! Танки стреляют друг в друга, но сейчас они бессмертны, а в такие игры совершенно неинтересно играть. Давайте добавим ограниченное количество жизней для наших танков.
Жизни
Сегодня мы реализуем жизни в виде динамичных сердечек, привязанных к конкретному танку – они будут отображать над ним и их количество будет уменьшаться при попадании ядра соперника.
Переменные
Переходим в группу «Переменные» и нажимаем «Создать переменную». У нас их будет две – Жизнь 1 (для Танка 1) и Жизнь 2 (для Танка 2). Эти переменные можно ввести в любой участок кода, любого спрайта. Мы выбрали Ядро 1 и добавили переменные со значением 3 – у каждого танка по 3 жизни. В группе «Переменные» выбираем «задать .. значение».

Наши переменные уже отображаются в верхнем левом углу сцены.

Условие для ядра
Когда ядро касается вражеского танка, жизни должны уменьшаться. Давайте введем условие, при котором от касания ядра будут зависеть количество жизней танка. Для этого выберем наш Танк 1 и дополним его основной блок. Заходим в группу «Управление» и выбираем условие «если, то». Будьте внимательны, блок должен находится внутри «повторять всегда», но не попадать в остальные.
Далее переходим в «Сенсоры» и выбираем «касается». Для Танка 1 вражеское Ядро 2. Значит именно их он боится. В группе «Переменные» выбираем блок «изменить на». Танку 1 соответствуют Жизни 1, поэтому выбираем их, а в значении пишем -1. То же самое пишет для Танка 2, меняя условия на Ядро 1 и Жизни 2.
Коллизия взаимодействия может сработать несколько раз за короткий промежуток времени и отнять сразу все жизни у нашего танка, поэтому мы добавим небольшую задержку. Создадим ее искусственно, добавив в код условие «ждать 0.1 секунд». Переходим в группу «Управление» и выбираем нужное условие (Рис. 26).

Теперь, когда мы стреляем, количество жизней в переменных уменьшается. Если вы не хотите заниматься сердечками, то переходите к заголовку Winner! Но мы рекомендуем выполнить все части урока Танчики на Scratch. Показатель количества жизней есть в каждой игре и уметь их писать — универсальный навык.
Рисуем сердечки
Создаем новый спрайт и рисуем. Жизни могут быть и в виде звездочек, и в виде кружочков. Всего у этого спрайта должно быть 4 костюма: 1 костюм – 3 сердечка, 2 костюм – 2 сердечка, 3 костюм – 1 сердечко и 4 костюм – без сердечек.
Чтобы продублировать сердечки используем кнопки скопировать и вставить (Рис. 27.), а костюм размножим с помощью кнопки «Дублировать», нажатием правой кнопкой мыши на костюм слева (Рис. 28).

Не забывайте, что сердечки также необходим согласовывать с центром поля.
Мы хотим, чтобы сердечки отображались четко над танком. Переходим во вкладку Код. Начинаем с базовой схемы: «Событие» -> «когда зеленый флажок нажат», «Управление» -> «повторять всегда». Далее переходим в группу «Движение» и выбираем «перейти к x. y…». В качестве условий мы возьмем знакомый нам блок (Рис. 16.) и добавим его и к «x», и к «y».
Фиксируем уровень жизни над танком
И положение x, и положение y, наши сердечки наследуют от Танка 1. Но если мы закрепим сердечки, то увидим, что при поворотах они наезжают на танк и их практически не видно, поэтому мы решили их немного приподнять. Для этого заходим в «Операторы» и выбираем блок с +. Положение по y необходимо достать, а на его место поставить оператора: в первой области написать цифру – на сколько приподнимутся наши сердечки, а во вторую область вернуть зависимость от положения y. Вот что у нас получилось (Рис. 29).

Дублируем костюм с сердечками для второго танка с помощью клика правой частью мыши и меняем название спрайта на Жизни 2. В коде меняем положения от Танк 1 на Танк 2.
Сердечки отображаются, но их количество не изменяется при попадании снаряда. Нам необходимо ввести зависимость количества жизней в переменной и костюма с сердечками. Если у нас 3 жизни, то выбираем костюм 3, а если 2 жизни, то 2, и так далее.
Сердечки = жизни
Выбираем спрайт Жизнь 1 и добавляем новый кусок кода. Начинаем как всегда: «Событие» -> «когда зеленый флажок нажат», «Управление» -> «повторять всегда». В той же группе «Управление» выбираем условие «если, то». Заходим в группу «Операторы» и выбираем форму в виде ромба со знаком равно. В первой части у нас должна быть переменная. Заходим в группу «Переменные» и перетаскиваем Жизни 1.

После знака = пишем цифру 3. После этого заходим в группу «Внешний вид» и выбираем «изменить костюм на ..» И выбираем тот номер костюма, на котором изображено 3 сердечка. Теперь мы можем продублировать условие «если, то» еще 3 раза, и поменять количество жизней и номера костюмов. В конце последнего условия, когда количество жизней ровно 0, нам нужно не только сменить костюм на тот, у которого нет сердечек, но и добавить из группы «События» — «Конец игры». У нас получился вот такой код (Рис. 32).

Дублируем эту часть кода для спрайта Жизни 2.
Для того, чтобы переменные поспели за циклом и успели обновиться, нам нужно поставить перед ним маленькую искусственную задержку. В группе «Управление» выбираем блок «ждать 1 секунду». Но целая секунда для нас много, сократим до 0.1.

Не забывайте, что у нас 2 цикла с сердечками. Нужно добавить задержку и в Жизни 1, и в Жизни 2.
Winner!
Нам осталось вывести на экран имя победителя. Сделаем это в настройках сцены. Для этого нажимаем на панель «Сцена» рядом с панелью спрайтов. Переходим во вкладку «Фоны» и дублируем их. Всего у нас получится 3 фона – основной и 2 фона для победителей.
Выбираем текст и на одном пишем – «Победил игрок 1», а на втором – «Победил игрок 2». Если вы знаете с кем будете играть, можно ввести ваши имена или забавные псевдонимы.

Переходим во вкладку «Код». Нам нужно сделать так, чтобы игра всегда начиналась стандартным фоном без надписей. Из «События» выбираем знакомый нам блок «когда зеленый флажок нажат», а в группе «Внешний вид» выбираем «переключить фон на …» и выбираем название нашей стандартного фона.
Объявляем победителя
Но ведь в конце игры фон должен измениться? Да! Для этого в группе «События» выбираем «когда я получу конец игры», а в «Управлении» выбираем условие «если, то, иначе». Обратите внимание, что у этого блока два условия, он отличается от тех, что мы использовали ранее.
Эта часть работы похожа на наше решение с костюмами. Фоны также зависят от количества жизней. В группе «Операторы» выбираем блок со знаком больше (>) и добавляем в условие. На первом месте ставим Жизни 2, а на втором Жизни 1. Получается, что если в момент окончания игры значение переменной Жизни 2 больше, чем Жизни 1 победил Танк 2, и именно это нам должен сообщить фон.
В группе «Внешний вид» выбираем блок «переключить фон», и выбираем тот фон, на котором написано «Победил игрок 2». А после слова «иначе», добавляем такой же блок, но используем последний фон, который нам сообщит, что «Победил игрок 1».

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

Мы должно остановить все процессы в игре, а для этого нужно остановить процессы у всех двигающихся спрайтов, а именно у танков и ядер. Переходим в группу «События» и выбираем «когда я получу конец игры», а в «Управлении» — «стоп ..», по маленькой стрелочке выбираем «другие скрипты спрайта».

Дублируем это условие к обоим танкам и снарядам.
Ну что, пробуем? Нам кажется, что получилось здорово.
Если у вас еще остались силы, предлагаем выполнить задание под звездочкой и добавить респаун (англ. respawn) – место возрождения наших танчиков в начале каждой новой игры.
(*)Респаун
В серьезных играх у героя всегда есть место постоянного появление героя. Ваша игра будет выглядеть еще круче и профессиональнее. А делается респаун очень просто. Мы переходим во вкладку «Код» любого из танков. Заходим в группу «Движение» и выбираем «перейти в x, y», и еще одно условие «повернуть в направлении» и ввести нужные значения. Чтобы танк всегда оказывался в этом месте в начале, нам нужно поставить блок до начала цикла.

Координаты выбирайте любые.
Финал

Игра готова и наш урок Танчики на Scratch подошел к концу. Несмотря на то, что функционал игры простой, мы научились делать много полезных фишек, которые используются во всех играх! Например, теперь вы сможете подключить сердечки жизней к любому персонажу, научить его стрелять или кидать любые предметы и знаете как делать респаун.
Дальше вы сможете усложнить игру и придумать новые уровни, добавить больше стен или лабиринтов, сделать несколько типов снарядов. А можно подключить третьего игрока! Удачи!
Еще больше игр на Scratch на нашем онлайн-курсе! Итог каждого урока — новая игра. На курсе мы создаем змейку, Fruit ninja и даже свою версию легендарного Марио. Почитать о курсе вы можете ЗДЕСЬ.
Рабочая версия проекта по нашей инструкции
Setting up a Multiplayer Project from Scratch
This document describes steps to setup a new multiplayer project from nothing using the new networking system. This step-by-step process is generic, but can be customized for many types of multiplayer games once it is started.
To get started, create a new empty Unity project.
NetworkManager Setup
The first step is to create a NetworkManager object in the project:
- Add a new empty game object, from the menu Game Object -> Create Empty.
- Find the newly created object in the Hierarchy View and select it
- Rename the object to “NetworkManager” from the right-click context menu or by clicking on the object’s name and typing.
- In the inspector window for the object, click the Add Component button
- Find the component Network -> NetworkManager and add it to the object. This component manages the network state of the game.

- Find the component Network -> NetworkManagerHUD and add it to the object. This component supplies a simple user interface in your game for controlling the network state.

Setup the Player Prefab
The next step is to setup the Unity Prefab that represents the player in the game. By default, the NetworkManager instantiates an object for each player by cloning the player prefab. In this example, the player object will be a simple cube.
- Create a new Cube from the menu Game Object -> 3D Object -> Cube

- Find the cube in the Hierarchy view and select it
- Rename the object to “PlayerCube”
- In the inspector window for the object click the Add Component button
- Add the component Network -> NetworkIdentity to the object. This component is used to identify the object between the server and clients.

- Set the “Local Player Authority” checkbox on the NetworkIdentity to true. This will allow the client to control the movement of the player object

- Make a prefab from the player cube object by dragging it into the Assets window. This will create a prefab called “PlayerCube”
- Delete the PlayerCube object from the scene — we don’t need it now that we have a prefab
Register the Player Prefab
Once the player prefab is created, it must be registered with the network system.

- Find the NetworkManager object in the Heirarchy View and select it
- Open the “Spawn Info” foldout of the inspector for the NetworkManager
- Find the “Player Prefab” slot
- Drag the PlayerCube prefab into the “Player Prefab” slot
Now is a good time to save the project for the first time. From the menu File -> Save Project, save the project. You should also save the scene. Lets call this scene the “offline” scene.
Player Movement (Single Player Version)
The first piece of game functionality is to move the player object. This will first be done without any networking, so it will only work in a single-player mode.
- Find the PlayerCube prefab in the Asset view.
- Click the Add Component button and choose “New Script”
- Enter the name “PlayerMove” for the new script name. A new script will be created.
- Open this new script in an editor (such as Visual Studio) by double clicking it
- Add this simple movement code to the script:
using UnityEngine; public class PlayerMove : MonoBehaviour < void Update() < var x = Input.GetAxis("Horizontal")*0.1f; var z = Input.GetAxis("Vertical")*0.1f; transform.Translate(x, 0, z); >>This hooks up the cube to be controlled by the arrow keys or a controller pad. The cube only moves on the client right now — it is not networked.
Save the project again.
Test a Hosted Game
Enter play mode in the editor by clicking the play button. You should see the NetworkManagerHUD default user interface:

Press “Host” to start the game as the host of the game. This will cause a player object to be created, and the HUD will change to show the server is active. This game is running as a “host” — which is a server and a client in the same process.
Pressing the arrow keys should make the player cube object move around.
Exit play mode by pressing the stop button in the editor.
Test Player Movement for a Client

- Use the menu File -> Build Settings to open the Build Settings dialog.
- Add the current scene to the build by pressing the “Add Open Scenes” button
- Create a build by pressing the “Build and Run” button. This will prompt for a name for the executable, enter a name such as “networkTest”
- A stand-alone player will launch, and show a resolution choice dialogue.
- Choose the “windowed” checkbox and a lower resolution such as 640×480
- The stand-alone player will start and show the NetworkManager HUD.
- Choose “Host” from the menu to start as a host. A player cube should be created
- Press the arrow keys to move the player cube around a little
- Switch back to the editor and close the Build Settings dialog.
- Enter play mode with the play button
- From the NetworkManagerHUD user interace, choose “LAN Client” to connect to the host as a client
- There should be two cubes, one for the local player on the host and one for the remote player for this client
- Press the arrow keys to move the cube around
- Both cube currently move! This because the movement script is not network-aware.
Make Player Movement Networked
- Close the stand-alone player
- Exit play mode in the editor
- Open the PlayerMove script.
- Update the script to only move the local player
- Add “using UnityEngine.Networking”
- Change “MonoBehaviour” to “NetworkBehaviour”
- Add a check for “isLocalPlayer” in the Update function, so that only the local player processes input
using UnityEngine; using UnityEngine.Networking; public class PlayerMove : NetworkBehaviour < void Update() < if (!isLocalPlayer) return; var x = Input.GetAxis("Horizontal")*0.1f; var z = Input.GetAxis("Vertical")*0.1f; transform.Translate(x, 0, z); >>
- Find the PlayerCube prefab in the Asset View and select
- Click the “Add Component” button and add the Networking -> NetworkTransform component. This component makes the object sychronize it’s position across the network.
- Save the Project again
Test Multiplayer Movement
- Build and run the stand-alone player again and start as host
- Enter play mode in the editor and connect as a client
- The player objects should now move independently of each other, and are controlled by the local player on their client.
Identify Your Player
The cubes in the game are currently all white, so the user cannot tell which one is their cube. To identify the player, we will make the cube of the local player red.
- Open the PlayerMove script
- Add an implementation of the OnStartLocalPlayer function to change the player object’s color.
public override void OnStartLocalPlayer() < GetComponent().material.color = Color.red; >This function is only called on the local player on their client. This will make the user see their cube as red. The OnStartLocalPlayer function is a good place to do initialization that is only for the local player, such as configuring cameras and input.
There are also other useful virtual functions on the NetworkBehaviour base class. See Spawning.
- Build and run the game
- The cube controlled by the local player should now be red, while the others are still white.
Shooting Bullets (Not Networked)
A common feature in multiplayer games is to have player fire bullets. This section adds non-networked bullets to the example. Networking for bullets is added in the next section.
- Create a sphere game object

- Rename the sphere object to “Bullet”
- Change scale of the bullet from 1.o to 0.2
- Drag the bullet to the assets folder to make a prefab of the bullet
- Delete the bullet object from the scene
- Add a Rigidbody component to the bullet

- Set the “Use Gravity” checkbox on the rigidbody to false
- Update the PlayerMove script to fire bullets:
- Add a public slot for the bullet prefab
- Add input handling in Update() function
- Add a function to fire a bullet
using UnityEngine; using UnityEngine.Networking; public class PlayerMove : NetworkBehaviour < public GameObject bulletPrefab; public override void OnStartLocalPlayer() < GetComponent().material.color = Color.red; > void Update() < if (!isLocalPlayer) return; var x = Input.GetAxis("Horizontal")*0.1f; var z = Input.GetAxis("Vertical")*0.1f; transform.Translate(x, 0, z); if (Input.GetKeyDown(KeyCode.Space)) < Fire(); >> void Fire() < // create the bullet object from the bullet prefab var bullet = (GameObject)Instantiate( bulletPrefab, transform.position - transform.forward, Quaternion.identity); // make the bullet move away in front of the player bullet.GetComponent().velocity = -transform.forward*4; // make bullet disappear after 2 seconds Destroy(bullet, 2.0f); > >
- Save the script and return to the editor
- Select the PlayerCube prefab and find the PlayerMove component
- Find the bulletPrefab slot on the component
- Drag the bull prefab into the bulletPrefab slot
- Make a build then start the stand-alone player as the host
- Enter play mode in the editor and connect as a client
- Pressing the space bar should cause a bullet to be created and fired from the player object
- The bullet is not fired on other clients, only the one where the space bar was pressed.
Shooting Bullets with Networking
This section adds networking to the bullets in the example.
- Find the bullet prefab and select it
- Add NetworkIdentity to the bullet prefab
- Add NetworkTransform component to the bullet prefab
- Set the send rate to zero on the NetworkTransform component on the bullet prefab. The bullet doesnt change direction or velocity after it is shot, so it does not need to send movement updates.

- Select the NetworkManager and open the “Spawn Info” foldout
- Add a new spawn prefab with the plus button
- Drag the Bullet prefab into the new spawn prefab slot

- Open the PlayerMove script
- Update the PlayerMove script to network the bullet:
- Change the Fire function to be a networked command, by adding the [Command] custom attribute and the “Cmd” prefix
- Use Network.Spawn() on bullet object
using UnityEngine; using UnityEngine.Networking; public class PlayerMove : NetworkBehaviour < public GameObject bulletPrefab; public override void OnStartLocalPlayer() < GetComponent().material.color = Color.red; > [Command] void CmdFire() < // This [Command] code is run on the server! // create the bullet object locally var bullet = (GameObject)Instantiate( bulletPrefab, transform.position - transform.forward, Quaternion.identity); bullet.GetComponent().velocity = -transform.forward*4; // spawn the bullet on the clients NetworkServer.Spawn(bullet); // when the bullet is destroyed on the server it will automaticaly be destroyed on clients Destroy(bullet, 2.0f); > void Update() < if (!isLocalPlayer) return; var x = Input.GetAxis("Horizontal")*0.1f; var z = Input.GetAxis("Vertical")*0.1f; transform.Translate(x, 0, z); if (Input.GetKeyDown(KeyCode.Space)) < // Command function is called from the client, but invoked on the server CmdFire(); >> >This code uses a [Command] to fire the bullet on the server. For more information see Networked Actions.
- Make a build then start the stand-alone player as the host
- Enter play mode in the editor and connect as a client
- Pressing the space bar should make bullet fire for the correct player (only) on all clients
Bullet Collisions
This adds a collision handler so that bullets will disappear when they hit a player cube object.
- Find the bullet prefab and select it
- Choose the Add Component button and add a new script
- Call the new script “Bullet”
- Open the new script and add the collision handler that destroys the bullet when it hits a player object
using UnityEngine; public class Bullet : MonoBehaviour < void OnCollisionEnter(Collision collision) < var hit = collision.gameObject; var hitPlayer = hit.GetComponent(); if (hitPlayer != null) < Destroy(gameObject); >> >Now when a bullet hits a player object it will be destroyed. When the bullet on the server is destroyed, since it is a spawned object managed by the network, it will be destroyed on clients too.
Player State (Non-Networked Health)
A common feature related to bullets is that the player object has a “health” property that starts at a full value and then is reduced when the player takes damage from a bullet hitting them. This section adds non-networked health to the player object.
- Select the PlayerCube prefab
- Choose the Add Component button and add a new script
- Call the script “Combat”
- Open the Combat script, add the health variables and TakeDamage function
using UnityEngine; public class Combat : MonoBehaviour < public const int maxHealth = 100; public int health = maxHealth; public void TakeDamage(int amount) < health -= amount; if (health > >The bullet script needs to be updated to call the TakeDamage function on a hit. * Open the bullet script * Add a call to TakeDamage() from the Combat script in the collision handler function
using UnityEngine; public class Bullet : MonoBehaviour < void OnCollisionEnter(Collision collision) < var hit = collision.gameObject; var hitPlayer = hit.GetComponent(); if (hitPlayer != null) < var combat = hit.GetComponent(); combat.TakeDamage(10); Destroy(gameObject); > > >This will make health on the player object go down when hit by a bullet. But you cannot see this happening in the game. We need to add a simple health bar. * Select the PlayerCube prefab * Choose the Add Component button and add a new script called HealthBar * Open the HealthBar script
This is a lot of code that uses the old GUI system. This is not very relevant for networking so we’ll just use it without explaination for now.
using UnityEngine; using System.Collections; public class HealthBar : MonoBehaviour < GUIStyle healthStyle; GUIStyle backStyle; Combat combat; void Awake() < combat = GetComponent(); > void OnGUI() < InitStyles(); // Draw a Health Bar Vector3 pos = Camera.main.WorldToScreenPoint(transform.position); // draw health bar background GUI.color = Color.grey; GUI.backgroundColor = Color.grey; GUI.Box(new Rect(pos.x-26, Screen.height - pos.y + 20, Combat.maxHealth/2, 7), ".", backStyle); // draw health bar amount GUI.color = Color.green; GUI.backgroundColor = Color.green; GUI.Box(new Rect(pos.x-25, Screen.height - pos.y + 21, combat.health/2, 5), ".", healthStyle); >void InitStyles() < if( healthStyle == null ) < healthStyle = new GUIStyle( GUI.skin.box ); healthStyle.normal.background = MakeTex( 2, 2, new Color( 0f, 1f, 0f, 1.0f ) ); >if( backStyle == null ) < backStyle = new GUIStyle( GUI.skin.box ); backStyle.normal.background = MakeTex( 2, 2, new Color( 0f, 0f, 0f, 1.0f ) ); >> Texture2D MakeTex( int width, int height, Color col ) < Color[] pix = new Color[width * height]; for( int i = 0; i < pix.Length; ++i ) < pix[ i ] = col; >Texture2D result = new Texture2D( width, height ); result.SetPixels( pix ); result.Apply(); return result; > >- Save the project
- Build and Run the game and see health bar on the player object
- If a player shoots another player now, the health goes down on that particular client, but not on other clients.
Player State (Networked Health)
Changes to health are being applied everywhere now — independently on the client and host. This allows health to look different for different players. Health should only be applied on the server and the changes replicated to clients. We call this “server authority” for health.
- Open the Combat script
- Change script to be a NetworkBehaviour
- Make health a [SyncVar]
- Add isServer check to TakeDamage, so it will only be applied on the server
For more information on SyncVars, see State Synchronization.
using UnityEngine; using UnityEngine.Networking; public class Combat : NetworkBehaviour < public const int maxHealth = 100; [SyncVar] public int health = maxHealth; public void TakeDamage(int amount) < if (!isServer) return; health -= amount; if (health > >Death and Respawning
Currently, nothing currently happens when the health of a player reaches zero except a log message. To make it more of a game, when health reaches zero, the player should be teleported back to the starting location with full health.
- Open the Combat script
- Add a [ClientRpc] function to respawn the player object. For more information see Networked Actions.
- Call the repawn function on the server when health reaches zero
using UnityEngine; using UnityEngine.Networking; public class Combat : NetworkBehaviour < public const int maxHealth = 100; [SyncVar] public int health = maxHealth; public void TakeDamage(int amount) < if (!isServer) return; health -= amount; if (health > [ClientRpc] void RpcRespawn() < if (isLocalPlayer) < // move back to zero location transform.position = Vector3.zero; >> >In this game, the client controls the position of the player object — the player object has “local authority” on the client. If the server just set the player’s position to the start position, it would be overridden by the client, since the client has authority. To avoid this, the server tells the owning client to move the player object to the start position.
- Build and run the game
- Move the player objects away from the start position
- Shoot bullets at one player until their health reaches zero
- The player object should teleport to the starting position.
Non-Player Objects
While player objects are spawned when client connect to the host, most games have non-player objects that exist in the game world, such as enemies. In this section a spawner is added that creates non-player objects that can be shot and killed.
- From the GameObject menu create a new empty game object
- Rename this object to “EnemySpawner”
- Select the EnemySpawner object
- Choose the Add Component button and add a NetworkIdentity to the object
- In the NetworkIdentity click the “Server Only” checkbox. This makes the spawner not be sent to clients.
- Choose the Add Component button and create a new script called “EnemySpawner”
- Edit the new script
- Make it a NetworkBehaviour
- Implement the virtual function OnStartServer to create the enemies
using UnityEngine; using UnityEngine.Networking; public class EnemySpawner : NetworkBehaviour < public GameObject enemyPrefab; public int numEnemies; public override void OnStartServer() < for (int i=0; i < numEnemies; i++) < var pos = new Vector3( Random.Range(-8.0f, 8.0f), 0.2f, Random.Range(-8.0f, 8.0f) ); var rotation = Quaternion.Euler( Random.Range(0,180), Random.Range(0,180), Random.Range(0,180)); var enemy = (GameObject)Instantiate(enemyPrefab, pos, rotation); NetworkServer.Spawn(enemy); >> >Now create an Enemy prefab:
- From the GameObject menu create a new Capsule.
- Rename the object to “Enemy”
- Choose the Add Component button add a NetworkIdentity component to the Enemy
- Choose the Add Component button add a NetworkTransform component to the Enemy
- Drag the Enemy object into the Asset view to create a prefab
- there should be a prefab asset now called “Enemy”
- Delete the Enemy object from the scene
- Select the Enemy prefab
- Choose the Add Component button and add the Combat script to the Enemy
- Choose the Add Component button and add the HealthBar script to the Enemy
- Select the NetworkManager and in Spawn Info add a new spawnable prefab
- Set the new spawn prefab to the Enemy Prefab
The bullet script was setup to only work for players. Now update the bullet script to work with any object that has the Combat script on it:
- Open the Bullet script
- Change the collision check to use Combat instead of PlayerMove:
using UnityEngine; public class Bullet : MonoBehaviour < void OnCollisionEnter(Collision collision) < var hit = collision.gameObject; var hitCombat = hit.GetComponent(); if (hitCombat != null) < hitCombat.TakeDamage(10); Destroy(gameObject); >> >Hookup the EnemySpawner with the Enemy object:
- Select the EnemySpawner object
- Find the “Enemy” slot on the EnemySpawner component
- Drag the Enemy prefab into the slot
- Set the numEnemies value to 4
- Build and run the game
- When starting as Host, four enemies should be created at random locations
- The player should be able to shoot enemies, and their health should go down
- When the client joins they should see the enemies in the same positions, and same health values as on the server
Destroying Enemies
While the enemies can be shot by bullets and their health goes down, then respawn like players. Enemies should be destroyed when their health reaches zero instead of respawning.
- Open the Combat script
- Add a “destroyOnDeath” variable
- Check destroyOnDeath when health reaches zero
using UnityEngine; using UnityEngine.Networking; public class Combat : NetworkBehaviour < public const int maxHealth = 100; public bool destroyOnDeath; [SyncVar] public int health = maxHealth; public void TakeDamage(int amount) < if (!isServer) return; health -= amount; if (health else < health = maxHealth; // called on the server, will be invoked on the clients RpcRespawn(); >> > [ClientRpc] void RpcRespawn() < if (isLocalPlayer) < // move back to zero location transform.position = Vector3.zero; >> >- Select the Enemy prefab
- Set the destroyOnDeath checkbox to true for the Enemy
Now the enemy will be destroyed when health reaches zero, but players will respawn.
Spawn Positions for players
Players currently all appear at the zero point when they are created. This means that they are potentially on top of each other. Player should spawn at different locations. The NetworkStartPosition component can be used to do this.
- Create a new empty GameObject
- Rename the object to “Pos1”
- Choose the Add Component button and add the NetworkStartPosition component
- Move the Pos1 object to the position (–3,0,0)
- Create a second empty GameObject
- Rename the object to “Pos2”
- Choose the Add Component button and add the NetworkStartPosition component
- Move the Pos2 object to the position (3,0,0)
- Find the NetworkManager and select it.
- Open the “Spawn Info” foldout
- Change the “Player Spawn Method” to “Round Robin”
- Build and run the game
- Player objects should now be created at the locations of the Pos1 and Pos2 objects instead of at zero.