Пишем арканоид на Unity. Настройка проекта


Оглавление (нажмите, чтобы открыть):

Как сделать движение в unity 2d. Пишем арканоид на Unity. Механика мяча и платформы

В второй главе о разработке игры на Unity мы добавим игрока и его врагов в сцену

Создание игрока в Unity

Создание объекта, контролируемого игроком, требует наличия определенных элементов: спрайт, способ управления им и способ его взаимодействия с игровым миром. Рассмотрим этот процесс шаг за шагом и начнем, пожалуй, со спрайта. Вот изображение, которое мы будем использовать:

  1. Скорируйте картинку в папку «Textures»
  2. Создайте новый спрайт и назовите его «Player»
  3. Настройте спрайт так, чтобы он отображался в свойстве «Sprite» компонента «Sprite Renderer»

Если у вас возникли проблемы, обратитесь к предыдущему уроку. Мы проделали точно такие же действия для фона и «реквизита».

  1. Поместите игрока в слой «2 — Foreground»
  2. Измените масштаб на (0.2, 0.2, 1)

Теперь несколько слов о компонентах. Мы только что говорили о компоненте «Sprite Renderer». Если вы еще не заметил, объект игры состоит из нескольких компонентов, видимых в панели «Инспектор».

По умолчанию пустой объект игры выглядит так:

Этот объект имеет только один компонент: Transform . Этот компонент является обязательным и не может быть отключен или удален. Вы можете добавить к объекту столько компонентов, сколько захотите. Например, скрипты добавляются в качестве компонента. Большинство компонентов может быть включено или отключено пока существует объект.

(Вы можете нажать на галочку чекбокса, чтобы отключить его. Вы можете щелкнуть правой кнопкой мыши на компоненте, чтобы вернуть прежнее свойство, удалить его и т.д.

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

Sprite Renderer является компонентом, который способен отображать спрайт-текстуру. Теперь, когда мы узнали о концепции компонента, давайте добавим один к игроку!

Добавляем бокс-коллайдер (Box Collider)

Нажмите на кнопку «Добавить компонент» объекта игрока. Выберите «Box Collider 2D». Вы можете увидеть коллайдер в редакторе «Сцена» зрения и настройки его размера в «Инспекторе» в поле «Размер» (Size).

Существует еще один способ редактирования бокс-коллайдера. Выберите игровой объект с помощью бокс-коллайдера и зажмите клавишу shift на клавиатуре. Вы увидите, что на бокс-коллайдере (зеленый прямоугольник ) появились четыре маленьких рычажка. Перетащите один из них, чтобы изменить форму бокс-коллайдера. Будьте осторожны, синий прямоугольник представляет собой компонент Transform вашего игрового объекта, а не коллайдер.

Мы будем устанавливать размер коллайдера равным (10, 10) .

Это слишком много для настоящего шмапа, но все же меньше, чем спрайт:

В настоящее время, этого вполне достаточно.

Совет : Если вы планируете создать шмап , вам придется уделить много времени настройке хитбоксов – они должны точно соответствовать маленькому элементу внутри игрового спрайта. Вы также можете изменить такой параметр коллайдера, как shape – например, с помощью «Circle Collider 2D». Благодаря Unity, его поведение при этом не меняется, но это позволяет немного улучить геймплей.

Сохраним объект игрок как префаб. Теперь у вас есть базовую сущность игрока!

2D полигональный коллайдер

Если вы хотите супер точный и произвольный формы хитбокс, воспользуйтесь компонентом Unity «Полигоннальный коллайдер 2D» (Polygon Collider 2D). Эффект от этого будет незначительный, но зато вы получите такую форму, какую вы хотите.

«Polygon Collider 2D» похож на остальные коллайдеры: вы можете изменять форму с помощью мышки в режиме «Scene». Для удаления точки зажмите cmd или ctrl , а чтобы отрегулировать положение точки или добавить ее в форму коллайдера, используйте shift

Магия Rigidbody

Последний компонент, необходимый для добавления на нашего игрока: «Rigidbody 2D». Это поможет физическому движку правильно задействовать объект в игровом пространстве. Более того, это позволит вам использовать столкновения в скрипте.

  1. Выберите объект Player в «Hierarchy».
  2. Добавьте компонент «Rigidbody 2D».

Теперь, нажмите кнопку «играть» и смотрите, что у нас вышло:

Корабль падает! И как падает! Передвайте привет нашей любимой силе тяжести. По мере того, как сменяются кадры с заранее заданной гравитацией и rigidbodies прибавляет объекту массы, корабль притягивается к нижней части экрана.

По-умолчанию, ускорние свободного падения в Unity равно 9.81 , т.е. мы имеем дело с земной гравитацией.

Гравитация может быть использована в любой игре, но нам она не нужна. К счастью, гравитацию на Rigidbody можн легко отключить. Просто установите «гравитационный масштаб» равным нулю. Вот и все, корабль снова летит. Не забудьте поставить галочку в окошке «Fixed Angles», чтобы предотвратить вращение корабля, обусловленное такой физикой.

Перемещение игрока

Настало время написать скриптик (вы ведь не думали, что все будет двигаться само)? Создайте в Unity C#-скрипт в папке «Scripts» и назовите это «PlayerScript». Откройте ваш любимый редактор или используйте подменю «Sync» (нажмите на «Assets» в строке меню, затем на «Sync MonoDevelop Project») для правки созданного Unity скрипта.

«Sync MonoDevelop Project» : Это подменю немного странное.Во-первых, невозможно изменить имя, даже если сменить редактора.
Мы также рекомендуем использовать это меню при создании первого скрипта, так как Unity создаст решения и привяжет их к библиотекам Unity (для Visual Studio, Xamarin Studio или MonoDevelop).
Если вместо этого вы просто откроете скрипт, компилятор вашего IDE, скорее всего, зарегистрирует определенные ошибки, не Unity. Это не имеет значения, потому что вам не придется использовать его напрямую, но функция автоматического завершения объектов Unity не помешает.

По умолчанию в скрипте уже прописаны методы Start и Update . Вот краткий список наиболее часто используемых функций:

  • Awake() вызывается один раз, когда объект создается. По сути аналог обычной функции-конструктора.
  • Start() выполняется после Awake() . Отличается тем, что метод Start() не вызывается, если скрипт не включен (remember the checkbox on a component in the «Inspector»).
  • Update() выполняется для каждого кадра in the main game loop.
  • FixedUpdate() вызывается каждый раз через определеннок число кадров. Вы можете вызывать этот метод вместо Update() когда имеете дело с физикой («RigidBody» и др.).
  • Destroy() вызывается, когда объект уничтожается. Это ваш последний шанс, чтобы очистить или выполнить код.

У вас также есть некоторые функции для обработки столкновений:

  • OnCollisionEnter2D(CollisionInfo2D info) выполняется, когда коллайдер объекта соприкасается с другим коллайдером.
  • OnCollisionExit2D(CollisionInfo2D info) выполняется, когда коллайдер объекта не соприкасается ни с одним другим коллайдером.
  • OnTriggerEnter2D(Collider2D otherCollider) выполняется, когда коллайдер объекта соприкасается с другим коллайдером с пометкой «Trigger».
  • OnTriggerExit2D(Collider2D otherCollider) выполняется, когда коллайдер объекта перестает соприкасаться с коллайдером, помеченным как «Trigger».

Итак, с теорией покончено, пора в бой. Или нет, погодите еще немного: обратите внимание, что почти все, о чем мы говорили с вами имеет, суффикс «2D». Box Collider 2D , a Rigidbody 2D , OnCollisionEnter2D , OnTriggerEnter2D и т.д. Эти новые компоненты или методы появились с Unity 4.3. Используя их, вы работаете с физическим движком, встроенным в Unity 4.3, для 2D-игр (на основе Box2D) вместо движка для 3D-игр (PhysX). Два движка имеют аналогичные концепции и объекты, но они не работают точно так же. Если вы начинаете работать с одним (например, Box2D для 2D-игр), придерживаqntcm его. Именно поэтому мы используем все объекты или методы с суффиксом «2D».

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

Using UnityEngine; /// /// Контроллер и поведение игрока /// public ); // 4 — движение в каждом направлении movement = new Vector2(speed.x * inputX, speed.y * inputY); > vo >

Поясню цифры в комментариях к коду:

  1. Сначала определим публичную переменную, которая будет отображаться в окне «Инспектор». Это скорость, используемая для корабля.
  2. Сохраним движение для каждого кадра.
  3. Используем дефолтную ось, которую можно отредактировать в «Edit» -> «Project Settings» -> «Input» . При этом мы получим целые значения между [-1, 1] , где 0 будет означать, что корабль неподвижен, 1 — движение вправо, -1 — влево.
  4. Умножим направление на скорость.
  5. Изменим скорость rigidbody. Это даст движку команду к перемещению объекта. Сделаем это в FixedUpdate() , предназначенном для всего, что связано с физикой.

Заметка о соглашениях C# : Посмотрите на видимость speed члена класса – он обозначен как публичный. В C# переменная члена класса должна быть приватной для соответствующего сохранения его внутренней репрезентации.
Но смена типа переменной на публичный позволяет редактировать ее в Unity через панель «Inspector», даже в процессе игры. Это одна из самых мощных возможностей Unity, позволяющая изменять геймплей без использования кода.
Помните, что в данном случае мы создаем скрипты, а это не то же самое, что классическое программирование на C#. Это предполагает некоторых правил и соглашений.

Теперь добавим скрипт к игровому объекту. Для этого перетащите скрипт из окна «Проект» (Project) на игровой объект в «Иерархии» (Hierarchy). Вы также можете нажать на «Add Component» и добвить его вручную.

Нажмите кнопку «Play» в верхней части окна редактора. Корабль движется! Congratulations, Вы только что сделали эквивалент «Hello, World!» для игры:)

Попробуйте настроить скорость: нажмите на игрока, измените значения скорости в «Инспекторе», и посмотрите что из этого получится.

Будьте осторожны: изменения параметров, сделанные во время, игры теряются, когда вы ее остановите! Инспекторе — это отличный инструмент для настройки геймплея, но запомните или запишите, что вы делали, если хотите сохранить изменения. Этот же трюк подходит, если вы хотете проверить что-то новое, но не хотите вносить изменения в реальный проект.

Первый враг

Теперь добавим неприятелей, стремящихся уничтожить наш корабль. Пусть им будет зловещий спрут, названный «Poulpi»:

Создадим новый спрайт. Для этого:

  1. Скопируйте картинку в папку «Textures».
  2. Создайте новый спрайт, используя это изображение.
  3. Измените свойство «Масштаб» (Scale) в разделе Трансформирование (Transform) на (0.4, 0.4, 1) .
  4. Добавьте «Box Collider 2D» размером (4, 4) .
  5. Add a «Rigidbody 2D» with a «Gravity Scale» of 0 and «Fixed Angles» ticked.

Сохраните префаб и. вуаля!

Скрипт

Теперь напишем простенький скрипт, отвечающий за движение осьминога в определенном направлении. Для этого создайте новый скрипт, назвав его «MoveScript».

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

Скопируем некоторые части кода, который мы написали в «PlayerScript» для движения персонажа. We will add another designer (a public member you can alter in the «Inspector») variable for the direction:

Прикрепите скрипт к осьминогу. Нажмите «Play» и убедитесь, что спрут движется так, как показано на рисунке ниже:

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

Вы узнали, как добавить игрока, движущегося с помощью клавиатуры. Также, мы создали врага с зачаточным AI. Теперь мы хотим иметь возможность уничтожить его! А для этого, нам нужны боеприпасы, которые мы создадим в следующем уроке .

Итак. Всем привет. И сегодня я расскажу, как сделать простое движение персонажа. Сейчас только от третьего лица. Приступим.
Начнём, пожалуй, с создания персоажа. У меня это будет куб. Кто не знает, как создавать кубы или круги, поясняю — «GameObject» => «CreateOther» => «Cube». Создаём таким же образом камеру и привязываем к кубу (то бишь просто в иерархии перетаскиваем камеру на куб).
Так. Теперь создадим поверхность, по которой персонаж будет ходить. Пусть это будет просто «Plane». Ах, да. В конце урока будет ссылка с исходником по туториалу для тех, кто не понял.
Итак. Теперь создадим скрипт «Move». Добавим переменную игрока и переменную скорости.

Public GameObject player;
public int speed = 5;

Теперь укажем в методе старта, что это объект, на котором висит скрипт.

Void Start () <
player = (GameObject)this.gameObject;
>

Теперь сделаем само передвижение игрока вперёд при нажатии на «W» или стрелку вверх. Это делаем в методе void Update()! Для этого мы будем прибавлять позицию. Например вперёд.

If (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
>

Мы прибавили позицию вперёд (forward) и умножили на скорость, а точнее её переменную. И обязательно надо умножить на кадры в секунду (deltaTime).
Таким же образом сделаем движение назад. Только будем отнимать позицию.

If (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>

Таким же образом можем сделать и вправо и влево (right, left), но я сделаю просто поворот игрока, при нажатии на «A» или «D».
Я буду использовать «Rotate()». Чтобы поворачивать по оси «Y», я буду использовать «up» и «down». Кстати, для этого ещё надо объявить переменную «public int speedRotation = 3». И пишем в условиях.

If (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>

Ну. Сейчас пришло время анимировать. Я записываю анимацию в самой юнити. Это можно открыть в «Window» => «Animation». В этом окне мы можем анимировать куб. Итак. Пропустим момент создания анимации. Давайте теперь создадим переменную анимации.

Public AnimationClip anima;

Теперь в старте добавим клип.

Теперь мы будем его воспроизводить через «CrossFade». Воспроизводить буду в условиях ходьбы вперёд и назад. Чтобы воспроизвести, нужно написать.

Итак. У нас получился хороший код. Сейчас мы сделаем прыжок. Всё так же просто. Опять мы будем прибавлять позицию. Только вверх (up).
И так же с новой переменной анимации «public AnimationClip anima2;»? так же добавим и переменной «public int jumpSpeed = 50;». И мы получаем условие.

If (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

Всё. Наш код готов.

using UnityEngine;
using System.Collections;
public class Move: MonoBehaviour <
public GameObject player;
public int speedRotation = 3;
public int speed = 5;
public AnimationClip anima;
public int jumpSpeed = 50;

Vo courier new font-size: text-align: justify> player = (GameObject)this.gameObject;
animation.AddClip(anima, «animCube»);
>
void Update() <
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
player.transform.position += player.transform.forward * speed * Time.deltaTime;
animation.CrossFade(«animCube»);
>
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>
if (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

Всем привет. Продолжаем дело, начатое в первой части. Сейчас у нас есть платформа и стоящий на ней персонаж с анимацией покоя. Настало время научить нашего персонажа бегать вправо-влево по платформе.

Загрузим сцену из первой части. Напомню, что в прошлый раз мы импортировали несколько спрайтов в папку AssetsSprites . На всякий случай, внизу поста еще раз приведу ссылку на спрайты. Среди них должен быть спрайт под названием Run . Мы будем использовать его для создания анимации бега. Для этого нам надо проделать те же действия по превращению одиночного спрайта в коллекцию, как и при создании анимации покоя. Вкратце напомню: выделяем спрайт, в окне Inspector устанавливаем свойство Sprite Mode как Multiple , нажимаем ниже Sprite Editor , нарезаем изображение в режиме Grid или Automatic .

Теперь в окне Hierarchy выбираем Character и переходим в окно Animation . Нажимаем на поле с анимацией Idle и выбираем Create New Clip , чтобы создать анимацию бега. Сохраним файл анимации в папке AssetsAnimations под именем Run .

Новая созданная анимация Run стала текущей в окне Animation . Разворачиваем спрайт Run в окне Project , выделяем все фалы Run_0… Run_9 и перетаскиваем в окно Animation . Установим пока значение Sample равное 24.

Все это мы уже делали в первой части, а теперь будет нечто новое. Перейдем в окно Animator . Сейчас там отображены три анимации: Any State , Idle и Run . Нам предстоит задать условия перехода из анимации Idle в анимацию Run , то есть из состояния покоя в состояние бега. В нижнем левом углу есть поле Parameters . Нажимаем на плюсик, выбираем Float и называем новый параметр как Speed . Тем самым мы создали параметр типа число с плавающей запятой, обозначающий скорость перемещения персонажа. Именно в зависимости от значения этого параметра будет происходить переключение из анимации покоя в анимацию бега. Теперь нажимаем правой кнопкой мыши на анимацию Idle , выбираем Make Transition и нажимаем левой кнопкой мыши на анимацию Run . Между анимациями появится линия со стрелкой. Передвиньте мышкой прямоугольники анимации, если плохо видно. Кликнем по линии со стрелкой. В окне Inspector отобразятся свойства перехода между анимациями. Обратим внимание на низ окна, в раздел Conditions . Кликнем на параметр Exit Time и поменяем его на Speed . Второе поле Greater оставим без изменений, а в третьем введем значение 0.01 . Мы создали условие перехода из анимации покоя в анимацию бега — оно происходит, когда значение параметра скорости становится немногим больше нуля.

Теперь нужно сделать обратный переход — из Run в Idle . Делаем все с точностью наоборот: Make Transition от Run к Idle , выделяем переход, в Conditions устанавливаем SpeedLess0.01 .

Теперь у нас есть две анимации и условия перехода между ними. Но пока ничего работать не будет, потому что все что мы сделали нужно «оживить» при помощи скрипта. Давайте перейдем в окно Project и создадим в папке Assets подпапку Scripts . Добавим в нее новый C# Script , назовем его CharacterControllerScript и откроем на редактирование.

Я приведу полный листинг скрипта с подробными комментариями, а ниже еще поясню, что в нем происходит.
using UnityEngine; using System.Collections; public > /// Начальная инициализация /// private vo > /// Выполняем действия в методе FixedUpdate, т. к. в компоненте Animator персонажа /// выставлено значение Animate Physics = true и анимация синхронизируется с расчетами физики /// private vo , Mathf.Abs(move)); //обращаемся к компоненту персонажа Rig > 0 && !isFacingRight) //отражаем персонажа вправо Flip(); //обратная ситуация. отражаем персонажа влево else if (move /// Метод для смены направления движения персонажа и его зеркального отражения /// private vo >

Итак, мы завели несколько переменных: для задания максимальной скорости перемещения, для определения направления (вправо/влево) и для работы с компонентом Animator . Почти все действия происходят в методе FixedUpdate . В нем мы получаем значение оси Х , которое меняется при нажатии на клавиатуре клавиш влево-вправо или A-D (если не меняли соответствующие настройки проекта!). Затем устанавливаем это значение параметру Speed компонента Animator . Обратите внимание, что мы берем модуль этого значения при помощи метода Mathf.Abs , так как при создании условий перехода между анимациями покоя и бега мы сравниваем значение параметра с положительным числом 0.01 . Нам здесь не важно, в какую сторону бежит персонаж. Важно лишь величина значения. Далее задаем скорость перемещения по оси Х в соответствии со значением максимальной скорости. И, наконец, проверяем, в какую сторону бежит персонаж, и в какую сторону он в этот момент повернут. Если он бежит вправо, а повернут влево — разворачиваем его вправо путем инвертирования его размера по оси Х . И наоборот. Этим нехитрым способом мы избавились от необходимости делать две анимации вместо одной: для бега вправо и для бега влево.

Сохраняем скрипт. В Unity перетаскиваем его на нашего Character в окне Hierarchy . Запускаем игру, нажимаем влево-вправо или A-D.

Капитан Коготь теперь умеет бегать! Скорость анимации получилась быстроватой. Ее можно снизить путем уменьшения значения Sample в окне Animation для анимации Run (значение 12 будет нормально). Если одновременно с игрой у вас видно окно Animator , то вы увидите, что во время покоя работает анимация Idle (бегает синий прогрессбар), а во время бега происходит переход на анимацию Run , и, соответственно, работает она.

На этом пока все. Нам осталось разобраться с прыжками… и узнать при этом еще несколько новых вещей!

Введение:

1. Шаг

2. Шаг

Сначала создайте землю для нашей игры. Импортируйте largeGround из загруженного архива ( ссылка снова, если ещё не скачали. Распакуйте архив.zip после его загрузки).

Перетащите largeGround в сцену. Переименуйте созданный игровой объект как Ground . Проверьте, что Z-позиция равна нулю (измените её на , если отличается). Добавьте к нему Box Collider 2D.

3. Шаг

Теперь мы можем сделать игрока. Для этого у меня есть лист спрайтов с крысой. Импортируйте ratIdle (из скаченного архива) в окно Assets . Нам надо разделить спрайты. Выберите ratIdle и переключите Sprite Mode на Multiple . Нажмите Apply .

Нажмите на Sprite Editor и новое окно будет открыто. Нажмите Slice . Измените Type на Grid By Cell Count . Установите Column на 4 и Row на 5 . Нажмите на кнопку Slice . Нажмите на Apply . Закройте это окно.

Раскройте спрайт. В нем должно быть теперь 20 кадров. Перетащите первый кадр в сцену. Будет создан новый игрвой объект. Выделите этот объект и назовите его Rat . Посмотрите на его Inspector . Измените Tag на Player . Убедитесь, что его Z-позиция 0. Добавьте к нему Capsule Collider 2D . Измените Direction на Horizontal . Нажмите на кнопку Edit и настройте размер коллайдера (тяните за зеленые точки). Теперь добавьте Rigidbody 2D . Установите Interpolate на Interpolate . Разверните Constraints и включите Freeze Rotation Z .

4. Шаг

public float speed;

Выберите крысу в иерархии и добавьте к ней скрипт PlayerMove . Измените переменную Speed (около 3). Вы можете запустить игру и проверить сцену. Крыса должна двигаться влево и вправо (использовать левую/правую стрелку или A/D).

5. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove: MonoBehaviour <

public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;

void Start () <
//делаем ссылку на Rigidbody2D
rb = GetComponent ();
>

//переключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
>
>

void FixedUpdate () <
//изменяем переменную, зависящую от результата Physics2D.OverlapPoint

//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis («Horizontal» );
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f );
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
>
>

Выберите Rat в иерархии, щелкните по нему правой кнопкой мыши и выберите Create Empty . Выберите этот созданный объект и переименуйте его в GroundCheck .

Выберите GroundCheck и включите иконку для лучшей видимости (смотрите скриншот). Включите moving tool и передвиньте GroundCheck под крысу, но не в сам коллайдер крысы. Убедитесь, что его Z-Position равна 0.

Выберите Ground в иерархии и смените Layer на Ground (добавьте новый Layer с этим названием, если в списке нет такого).

Выделите Rat в иерархии. В компоненте PlayerMove есть теперь новые поля. Включите Ground в whatIsGround . Поместите GroundCheck в поле GroundCheck . Измените JumpForce на 5.

Проверьте игру. Крыса должна теперь двигаться налево/направо и прыгать.

6. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove: MonoBehaviour <

//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//переменная контроля направления крысы
public bool isLookingLeft;

void Start () <
//делаем ссылку на Rigidbody2D
rb = GetComponent ();
>

//я буду использовать Update() для более точного определения прыжка
void Update () <
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input .GetButtonDown («Jump» ) && isGrounded) <
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2 .up * jumpForce, ForceMode2D .Impulse);
//sпереключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
>
>

void FixedUpdate () <
//изменяем переменную, зависит от результата Physics2D.OverlapPoint
isGrounded = Physics2D .OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis («Horizontal» );
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f );
//изменить скорость игрока на вычисленный вектор
rb.velocity = move;

//функция поворота крысы
void TurnTheRat ()
<
//смена переменной показывающей направление взгляда на обратное значение
isLookingLeft = !isLookingLeft;
//поворот крысы через инвертацию размера по оси х
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>

Выберите крысу. В скрипте PlayerMove появилась новая переменная для обозначения направления взгляда. Включите её, так как крыса смотрит налево.

Крыса может теперь бежать влево и вправо и менять направление взгляда. Вы можете проверить сцену.

7. Step

Теперь можем начать анимировать крысу. Выберите Rat в иерархии и добавьте Animator к ней.

Создайте Animator Controller в Assets . Назовите его RatAnimator .

Выберите Rat и добавьте RatController в поле Controller .

Нам понадобится окно Animation . Включите его в меню Window м поместите его там, где вам удобно (я поместил над Assets ).

Выберите Rat в иерархии. Создайте новую анимацию (нажмите на кнопку Create ). Назовите эту новую анимацию IdleRatAnimation .

Теперь можем добавить спрайтовый лист. Выделите Rat в иерархии. Разверните ratIdle спрайт. Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key Animation

Включите окошко Animator в меню Window .

Анимация должна быть зацикленна. Убедитесь в этом на всякий случай. Перейдите к окну Animator и сделайте двойной клик на IdleRatAnimation Проверьте Loop Time .

У крысы есть теперь анимация покоя. Запустите сцену и проверьте.

8. Шаг

Теперь создадим анимацию бега. Импортируйте спрайт ratRun в Assets . Смените Sprite Mode на Multiple . Перейдите в Sprite Editor и переключите на Grid By Cell Count и установите Column 4 , Row 5 (смотрите 3. Шаг ). Выделите Rat в иерархии. Перейдите в окно Animations и нажмите на IdleRatAnimation потом нажмите на Create New Clip . Назовите новую анимацию RunRatAnimations .

Раскройте спрайт ratRun и выделите все 20 кадров (нажмите первый кадр, держите кнопку шифт и нажмите последний кадр). Перетащите все кадры в окошко Animations . Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).

Откройте окно Animator (включите его в меню Window , если не видите его).

IdleRatAnimation стандартная анимация. Нам нужны transition (переходы) к другим анимациям и параметры контроля этих transition. Нажмите на закладку Parameters . Добавьте новый float speed параметр. Сделайте правый клик на IdleRatAnimation и сделайте transition из IdleRatAnimation в RunRatAnimation . Потом правый клик на RunRatAnimation и добавьте transition на IdleRatAnimation .

Выберите transition от IdleRatAnimation к RunRatAnimation . Отключите Has Exit Time speed greater 0.01 .

Выберите transition от RunRatAnimation к IdleRatAnimation . Отключите Has Exit Time . Добавьте новое condition (условие). Измените его на speed less 0.01 .

Анимация бега сейчас слишком медленная. Выберите RunRatAnimation в Animator и измените скорость на 2.5 (можете потом настроить по желанию).

9. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

void Update () <
//меняем параметр speed в Animator. Используем значение скорости по оси х

Добавьте этот скрипт к крысе Rat .

Запустите сцену. У крысы должна появиться анимация бега

10. Шаг

Теперь сделаем анимацию прыжка. Выберите Rat в иерархии. Добавьте новую анимацию (в окошке Animation ) и назовите её JumpRatAnimation .

Я не сделал анимацию прыжка, просто используем замедленную анимацию бега. Выделите Rat в иерархии. Проверьте в окошке Animation , что JumpRatAnimation выбранна. Разверните спрайт ratRun . Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key и выделите последний кадр. Все 20 кадров должны выбраться. Перетащите все кадры в окошко Animation . Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).

11. Шаг

Переключитесь на Animator . Нам нужно условие для анимации прыжка. Добавьте новую Bool и назовите её isJumping . Сделайте теперь transition (переход) (правый клик) из Any State к JumpRatAnimation . Добавьте transition от JumpRatAnimation к IdleRatAnimation .

Выделите transition от Any State к JumpRatAnimation . Отключите Has Exit Time . Разверните Settings и отключите Can Transition To (чтобы избежать перезапуска анимации, пока isJumping true). Добавьте condition (условие) isJumping true .

Выберите transition от JumpRatAnimation к IdleRatAnimation . Отключите Has Exit Time . Добавьте condition isJumping false .

Выделите JumpRatAnimation и измените Speed на 0.5. Замедленная анимация бега должна заменить анимацию прыжка.

12. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAnim: MonoBehaviour <

//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
//ссылочная переменная для PlayerMove
PlayerMove pm;

void Update () <
//проверка, находится ли крыса на земле
if (pm.isGrounded) <
//меняем параметр isJumping на false
anim.SetBool («isJumping» , false );
//меняем параметр speed. Используем абсолютное значение вектора скорости по х
anim.SetFloat («speed» , Mathf .Abs (rb.velocity.x));
// если крыса не на земле
> else <
//меняем параметр speed на 0
anim.SetFloat («speed» , 0 );
//меняем параметр isJumping на true
anim.SetBool («isJumping» , true );
>
>

Можете проверить сцену.

13. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//ссылочная переменная для звукового файла
public AudioClip footsteps;

Выберите Rat в иерархии и добавьте этот скрипт к крысе. Импортируйте аудио-файл ratStep . И добавьте ratStep в Footsteps поле компонента PlayerSound .

Выделите Rat в иерархии и перейдите в Animation . Смените анимацию на RunRatAnimation . Выберите кадр, когда хотите воспроизвести звук (кликните на полоску времени). Нажмите на Add Event (смотрите скриншот). Выберите добавленный Animations Event и установите Function на FootStepsAudio() .

14. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerSound: MonoBehaviour <

//ссылочная переменная для аудио-файла
public AudioClip footsteps;

//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () <
//воспроизвести заданный звук на позиции крысы
AudioSource .PlayClipAtPoint (footsteps, transform.position);
>

//запустится если было касание другого Collider2D
void OnCollisionEnter2D (Collision2D coll) <
//проверка тэга на тэг «Ground»
if (coll.gameObject.tag == «Ground» ) <
//воспроизвести заданный звук на позиции крысы
AudioSource .PlayClipAtPoint (footsteps, transform.position);
>
>

Выберите Ground в иерархии. Добавьте новый тэг Ground и измените тэг объекта Ground на тэг Ground .

15. Шаг

Выберите Ground в иерархии. Создайте prefab Ground (перетащите объект в Assets ). Поместите prefab Ground в сцену, как следующую платформу.

Выберите Main Camera и сделайте её дочерним объектом Rat (перетащите Main Camera на Rat ). Камера будет следовать за крысой.

Можете изменить X-position камеры на 0, чтобы убрать рывки при повороте.
Я думаю, этого достаточно для первой части. Надеюсь, что вторая часть будет готова в мае-июне (у меня сейчас мало времени).

Пишем арканоид на Unity. Настройка проекта

Всем привет! Сразу хочу напомнить вам терминологию:

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

1) Я переименовал все и привел в подобающий вид.
2) Я добавил объект Mouse для управления платформой.

Теперь давайте рассмотри базовую механику:

1) У нас будет мячик. Он будет отбиваться от стен, блоков и платформы.
2) Стены будут находится на левой, правой и верхней границах экрана.
3) У нас будет платформа, как говорилось ранее ей мы будем манипулировать мышкой, но вы вполне можете сделать это с помощью клавиатуры, главное чтобы это было сделано грамотно .
4) Собственно, блоки разной прочности. Если прочность блока больше единицы, то блок удаляется и на его место ставится менее прочный, а если прочность блока равна единице, то блок просто удаляется.

Приступаем: Для начала переименуем слой «Layer 0» в «Background» и создадим слой «Game».

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

Примерно такой результат должен быть у вас:

Теперь бонус:
Как вы заметили, платформа залезает за стены — это можно исправить в одну строчку:

Здесь записана вот такая строка в поле X: Код: Выделить всё max(paddle.Width / 2, min(Mouse.X, LayoutWidth — paddle.Width / 2))

Домашняя работа:
На тройку — выполнить все в точности как сказано
На четыре — выполнить все в точности как сказано и здраво назвать все переменные, чтобы человек знающий английский мог понять, что здесь происходит
На пять — выполнить все в точности как сказано и здраво назвать все переменные, чтобы человек знающий английский мог понять, что здесь происходит; объяснить как работает бонус в сообщении или реализовать блоки рациональней (Такой вариант точно есть)

Если что-то не поняли — ЛС мне . Всегда рад ответить.

Большое количество уровней в арканоиде

16.09.2015, 20:40

Сила мяча в Арканоиде
Здравствуйте! Нужна помощь с механикой мяча в Арканоиде. Дело в том, что когда мяч падает, он.

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

200 vlozhennyx funkcij rabotaut kak chasy. Dal’she ne proveryal. Kod.

Определить количество уровней в TreeView
Как мне узнать, сколько уровней узлов есть в TreeView?

Требуется определить количество уровней дерева
Подскажите пожалуйста как можно определить количество уровней дерева Приведу код: public.

17.09.2015, 15:16 2 18.09.2015, 08:07 3 19.09.2015, 01:19 4 22.09.2015, 15:56 5

Вы ошибаетесь, здесь гораздо больше вариантов. То, что вы предлагаете, является худшей практикой, и делать так категорически нельзя. Я говорю это не чтобы подколоть или задеть как-то, просто я делал так же раньше, и наблюдал объемные утечки памяти в пустоту.
Если 50 уровней арканоида будут загружаться через App.LoadScene, ну кто угодно устанет ждать. А если новые уровни появятся? Всех их заносить в билд? А как удобно среди них ориентироваться в иерархии — слов нет! Короче, не вариант.

«Хватит болтать», скажете вы, и будете правы. Я тут не нотации пришел читать, а предлагать решение. То, что у меня есть — это ScriptableObject, универсальный объект для хранения данных. Его не нужно держать на сцене, на него можно делать прямые ссылки и обращаться к тому, что в нем хранится. А храниться может все подряд — префабы, вектора, данные любого типа (см. скриншот).

Unity 2d движение к цели. Пишем арканоид на Unity

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

Вот список всех статей:

Где мы остановились?

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

Превью результата

Движение платформы

Сама платформа у нас уже есть — мы ее создали еще в прошлом уроке. Осталось научить ее двигаться, причем исключительно влево или вправо, т.е. по оси X. Для этого нам потребуется написать сценарий (Script ).

Сценарии представляют собой фрагменты программного кода, которые ответственны за какую-то конкретную задачу. Unity может работать со скриптами, написанными на трех языках программирования: Boo, JavaScript и C#. Мы будем использовать последний, но вы можете попробовать свои силы и с другими языками.

Итак, для создания скрипта перейдем на вкладку Project , найдем там одноименную папку Scripts и кликнем на нее правой кнопкой мыши. Выберем Create -> C# Script . Появится новый файл с названием NewBehaviourScript . Переименуйте его в PlayerScript для удобства. На вкладке Inspector вы можете видеть содержимое скрипта.

Двойным кликом откройте скрипт. Запуститься среда разработки MonoDevelop, которую вы впоследствии можете изменить на любой удобный для вас редактор. Вот то, что вы увидите:

Using UnityEngine; using System.Collections; public class NewBehaviourScript: MonoBehaviour < // используйте этот метод для инициализации void Start () < >// Update вызывается при отрисовке каждого кадра игры void Update () < >>

Все сценарии на Unity имеют по умолчанию два метода:

  • Start() : используется для инициализации переменных или параметров, необходимых нам в коде.
  • Update() : вызывается каждый кадр игры, необходим для обновления состояния игры.

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

Таким образом, необходимо создать две переменные для сохранения этой информации:

public float playerVelocity;
private Vector3 playerPosition;

Обратите внимание, что одна переменная объявлена публично, а вторая — приватно. Для чего это делается? Дело в том, что Unity позволяет редактировать значения публичных переменных не переходя в редактор MonoDevelop, без необходимости изменения кода. Эта возможность очень полезна в тех случаях. когда необходимо «на лету» корректировать какое-то значение. Скорость платформы — одно из таких значений, и именно поэтому мы объявили его публично.

Сохраните сценарий в редакторе MonoDevelop и перейдите в редактор Unity. Теперь у нас есть сценарий и нам нужно присвоить его какому то объекту, в нашем случае — платформе. Выберите нашу платформу во вкладке Hierarchy и в окне Inspector добавьте компонент, кликнув на кнопку Add Component .

Добавление нашего скрипта в компонент можно сделать и по-другому. Перетащите наш сценарий в область кнопки Add Component . Во вкладке Inspector вы должны увидеть что-то подобное:

Обратите внимание, что в компоненте скрипта появилось поле Player Velocity , которое можно тут же изменить. Это получилось возможным благодаря публичному объявлению переменной. Установите параметр в значение 0.3 и перейдите в редактор MonoDevelop.

Теперь нам надо узнать позицию платформы: playerPosition . Для того, чтобы инициализировать переменную, следует обратиться к объекту сценария в методе Start() :

// используйте этот метод для инициализации vo >

Отлично, мы определили начальную позицию платформы, и теперь можно ее двигать. Так как нам надо, чтобы платформа перемещалась только по оси X, то мы сможем использовать метод GetAxis класса Input . Этой функции мы передадим строку Horizontal , и она вернет нам 1, если была нажата клавиша «вправо», и -1 — «влево». Умножив полученное число на скорость и прибавив эту величину к текущей позиции игрока, мы и получим движение.

Также добавим проверку на выход из приложения по нажатию на клавишу Esc .

Вот то, что у нас должно получиться в итоге:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; > >

Сохраните скрипт и вернитесь в редактор Unity. Нажмите кнопку Play и попробуйте передвинуть платформу при помощи кнопок «влево» и «вправо».

Определение игровой области

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

Давайте добавим в наш существующий скрипт еще одну публичную переменную и назовем его boundary .

Эта переменная будет хранить максимальную координату платформы по оси X. Так как мы собираемся строить уровни в симметричной форме вокруг точки с координатами (0, 0, 0), то абсолютное значение переменной boundary будет одинаковым и для положительной части оси X, и для отрицательной.

А теперь добавим пару условий. Поступим достаточно просто: если вычисленная нами позиция будет больше boundary или меньше -boundary , то мы просто зададим новую позицию по оси X, равную значению переменной boundary . Таким образом, мы гарантируем, что платформа не уедет за пределы наших границ и никогда не покинет игровую зону. Вот код:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; // проверка выхода за границы if (playerPosition.x boundary) < transform.position = new Vector3(boundary, playerPosition.y, playerPosition.z); >> >

Теперь вернитесь в редактор и, переключаясь в игру, найдите оптимальное значение переменной boundary . В нашем случае подошло число 5.46. Откройте Inspector и сбросьте позицию платформы по оси X на 0, а параметр Boundary выставьте согласно найденному вами значению.

Нажмите кнопку Play и убедитесь в том, что вы все сделали правильно. Платформа должна двигаться только в пределах игрового поля.

Включение физики

Чтобы столкновения были более реалистичные — воспользуемся симуляцией физики. В этой статье мы добавим физические свойства мячику, платформе и границам поля. Так как мы пишем 2D игру, то будем использовать 2D коллайдеры. Коллайдер — это отдельный тип компонентов, который позволяет объекту реагировать на коллайдеры других объектов.

В окне Hierarchy выберем нашу платформу, перейдем в Inspector и нажмем на кнопку Add Component . В появившемся окошке наберем collider . Как вы можете увидеть — вариантов достаточно много. Каждый коллайдер имеет специфические свойства, соответствующие связанным объектам — прямоугольникам, кругам и т.д.

Так как наша платформа имеет прямоугольную форму, мы будем использовать Box Collider 2D . Выберите именно его, и компонент автоматически определит размеры платформы: вам не нужно будет задавать их вручную, Unity сделает это за вас.

Сделайте то же самое и для 3 границ (Hierarchy -> Inspector -> Add Component -> Box Collider 2D ).

С мячиком чуть-чуть по другому: он имеет круглую форму. Выберем мяч и добавим для нее компонент Circle Collider 2D .

На самом деле коллайдер окружности и прямоугольника очень похожи, за исключением того, что вместо параметра Size , определяющим ширину и длину, в окружности используется Radius . Объяснения здесь, думаем, излишни.

Упругое столкновение

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

Откройте окно Project и внутри папки Asset создайте новую папку под названием Physics . Кликните по только что созданной папке правой кнопкой мыши и выберите Create -> Physics2D Material . Задайте название BallPhysicsMaterial .

Каждая поверхность в Unity имеет два параметра: трение (friction) и упругость (bounciness) . Более подробно вы можете прочитать про физический движок и ряд физических параметров . Если вам требуется абсолютно упругое тело, то следует выставить трение на 0, а упругость на 1.

Сейчас у нас есть готовый материал, но он пока никак не связан с мячом. Выберите объект мяча во вкладке Hierarchy и в окне Inspector вы увидите поле Material компонента Circle Collider 2D . Перетащите сюда недавно созданный материал.

Добавление компонента Rigid Body

Для того, чтобы наш мячик двигался под контролем физики, мы должны добавить ему еще один компонент: Rigid Body 2D . Выберите объект мяча в окне Hierarchy и добавьте вышеупомянутый компонент — хоть он и имеет несколько параметров, нас интересует только один: Gravity Scale . Так как наш шарик будет двигаться только за счет отскоков, то мы зададим этому параметру 0 — таким образом мы гарантируем, что гравитация не будет реагировать на объект. Все остальное можно не менять.

Поведения шарика

Давайте создадим для шарика отдельный скрипт (снова воспользуемся C# в качестве языка программирования) и назовем его BallScript . Свяжите созданный скрипт с объект (Hierarchy -> Inspector -> Add Component ).

Перед тем, как начать писать скрипт, давайте определим поведение шарика:

  1. Шар имеет два состояния: неактивное (когда он в начале игры находится на платформе) и активное (когда находится в движении).
  2. Шар будет становиться активным только один раз.
  3. Когда шар становится активным, мы применяем к нему силу для того, что он начал движение.
  4. Если шар вышел за пределы игрового поля, он переводится в неактивное состояние и помещается на платформу.
Мастер Йода рекомендует:  Мехмет Ялчиндаг стал главой совета директоров Яндекс.Турция

Основываясь на этой информации, давайте создадим глобальные переменные ballIsActive , ballPosition и ballInitialForce:

private bool ballIsActive;
private Vector3 ballPosition;
private Vector2 ballInitialForce;

Теперь, когда у нас есть набор переменных, мы должны подготовить объект. В методе Start() мы должны:

  • создать силу, которая будет применена к шару;
  • перевести шар в неактивное состояние;
  • запомнить позицию шара.

Вот, как это можно сделать:

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

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

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

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

В методе Update мы должны проверять состояние шарика, и в случае если оно неактивное, нам надо задать позицию мячика по оси X таким же, какое оно у платформы.

Решение достаточно простое, но как нам получить координату совсем другого объекта? Элементарно — мы создадим переменную типа GameObject и сохраним ссылку на объект платформы:


public GameObject playerObject;

Вернемся к методу Update() :

Сохраните скрипт и вернитесь в редактор Unity. Вы наверняка заметили, что переменная playerObject объявлена, используется, но нигде не инициализирована. Да, так и есть. Чтобы ее проинициализировать, перейдите во вкладку Hierarchy , найдите шар и в окне Inspector найдите компонент Ball Script . У данного компонента есть параметр Player Object , в настоящее время пустующий:

Найдите во вкладке Hierarchy нашу платформу и перетащите ее на поле Player Object . Запустите игру, нажав кнопку Play , и убедитесь, что все работает.

Сброс игры

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

Это состояние отловить очень просто: шар будет активен, а его положение по оси Y отрицательно. Если это так, то мы переводим шар в неактивное состояние и ставим его на платформу:

If (ballIsActive && transform.position.y

А вот теперь точно все. Запустите игру и проверьте, все ли работает как положено.

В следующей части

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

В второй главе о разработке игры на Unity мы добавим игрока и его врагов в сцену

Создание игрока в Unity

Создание объекта, контролируемого игроком, требует наличия определенных элементов: спрайт, способ управления им и способ его взаимодействия с игровым миром. Рассмотрим этот процесс шаг за шагом и начнем, пожалуй, со спрайта. Вот изображение, которое мы будем использовать:

  1. Скорируйте картинку в папку «Textures»
  2. Создайте новый спрайт и назовите его «Player»
  3. Настройте спрайт так, чтобы он отображался в свойстве «Sprite» компонента «Sprite Renderer»

Если у вас возникли проблемы, обратитесь к предыдущему уроку. Мы проделали точно такие же действия для фона и «реквизита».

  1. Поместите игрока в слой «2 — Foreground»
  2. Измените масштаб на (0.2, 0.2, 1)

Теперь несколько слов о компонентах. Мы только что говорили о компоненте «Sprite Renderer». Если вы еще не заметил, объект игры состоит из нескольких компонентов, видимых в панели «Инспектор».

По умолчанию пустой объект игры выглядит так:

Этот объект имеет только один компонент: Transform . Этот компонент является обязательным и не может быть отключен или удален. Вы можете добавить к объекту столько компонентов, сколько захотите. Например, скрипты добавляются в качестве компонента. Большинство компонентов может быть включено или отключено пока существует объект.

(Вы можете нажать на галочку чекбокса, чтобы отключить его. Вы можете щелкнуть правой кнопкой мыши на компоненте, чтобы вернуть прежнее свойство, удалить его и т.д.

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

Sprite Renderer является компонентом, который способен отображать спрайт-текстуру. Теперь, когда мы узнали о концепции компонента, давайте добавим один к игроку!

Добавляем бокс-коллайдер (Box Collider)

Нажмите на кнопку «Добавить компонент» объекта игрока. Выберите «Box Collider 2D». Вы можете увидеть коллайдер в редакторе «Сцена» зрения и настройки его размера в «Инспекторе» в поле «Размер» (Size).

Существует еще один способ редактирования бокс-коллайдера. Выберите игровой объект с помощью бокс-коллайдера и зажмите клавишу shift на клавиатуре. Вы увидите, что на бокс-коллайдере (зеленый прямоугольник ) появились четыре маленьких рычажка. Перетащите один из них, чтобы изменить форму бокс-коллайдера. Будьте осторожны, синий прямоугольник представляет собой компонент Transform вашего игрового объекта, а не коллайдер.

Мы будем устанавливать размер коллайдера равным (10, 10) .

Это слишком много для настоящего шмапа, но все же меньше, чем спрайт:

В настоящее время, этого вполне достаточно.

Совет : Если вы планируете создать шмап , вам придется уделить много времени настройке хитбоксов – они должны точно соответствовать маленькому элементу внутри игрового спрайта. Вы также можете изменить такой параметр коллайдера, как shape – например, с помощью «Circle Collider 2D». Благодаря Unity, его поведение при этом не меняется, но это позволяет немного улучить геймплей.

Сохраним объект игрок как префаб. Теперь у вас есть базовую сущность игрока!

2D полигональный коллайдер

Если вы хотите супер точный и произвольный формы хитбокс, воспользуйтесь компонентом Unity «Полигоннальный коллайдер 2D» (Polygon Collider 2D). Эффект от этого будет незначительный, но зато вы получите такую форму, какую вы хотите.

«Polygon Collider 2D» похож на остальные коллайдеры: вы можете изменять форму с помощью мышки в режиме «Scene». Для удаления точки зажмите cmd или ctrl , а чтобы отрегулировать положение точки или добавить ее в форму коллайдера, используйте shift

Магия Rigidbody

Последний компонент, необходимый для добавления на нашего игрока: «Rigidbody 2D». Это поможет физическому движку правильно задействовать объект в игровом пространстве. Более того, это позволит вам использовать столкновения в скрипте.

  1. Выберите объект Player в «Hierarchy».
  2. Добавьте компонент «Rigidbody 2D».

Теперь, нажмите кнопку «играть» и смотрите, что у нас вышло:

Корабль падает! И как падает! Передвайте привет нашей любимой силе тяжести. По мере того, как сменяются кадры с заранее заданной гравитацией и rigidbodies прибавляет объекту массы, корабль притягивается к нижней части экрана.

По-умолчанию, ускорние свободного падения в Unity равно 9.81 , т.е. мы имеем дело с земной гравитацией.

Гравитация может быть использована в любой игре, но нам она не нужна. К счастью, гравитацию на Rigidbody можн легко отключить. Просто установите «гравитационный масштаб» равным нулю. Вот и все, корабль снова летит. Не забудьте поставить галочку в окошке «Fixed Angles», чтобы предотвратить вращение корабля, обусловленное такой физикой.

Перемещение игрока

Настало время написать скриптик (вы ведь не думали, что все будет двигаться само)? Создайте в Unity C#-скрипт в папке «Scripts» и назовите это «PlayerScript». Откройте ваш любимый редактор или используйте подменю «Sync» (нажмите на «Assets» в строке меню, затем на «Sync MonoDevelop Project») для правки созданного Unity скрипта.

«Sync MonoDevelop Project» : Это подменю немного странное.Во-первых, невозможно изменить имя, даже если сменить редактора.
Мы также рекомендуем использовать это меню при создании первого скрипта, так как Unity создаст решения и привяжет их к библиотекам Unity (для Visual Studio, Xamarin Studio или MonoDevelop).
Если вместо этого вы просто откроете скрипт, компилятор вашего IDE, скорее всего, зарегистрирует определенные ошибки, не Unity. Это не имеет значения, потому что вам не придется использовать его напрямую, но функция автоматического завершения объектов Unity не помешает.

По умолчанию в скрипте уже прописаны методы Start и Update . Вот краткий список наиболее часто используемых функций:

  • Awake() вызывается один раз, когда объект создается. По сути аналог обычной функции-конструктора.
  • Start() выполняется после Awake() . Отличается тем, что метод Start() не вызывается, если скрипт не включен (remember the checkbox on a component in the «Inspector»).
  • Update() выполняется для каждого кадра in the main game loop.
  • FixedUpdate() вызывается каждый раз через определеннок число кадров. Вы можете вызывать этот метод вместо Update() когда имеете дело с физикой («RigidBody» и др.).
  • Destroy() вызывается, когда объект уничтожается. Это ваш последний шанс, чтобы очистить или выполнить код.

У вас также есть некоторые функции для обработки столкновений:

  • OnCollisionEnter2D(CollisionInfo2D info) выполняется, когда коллайдер объекта соприкасается с другим коллайдером.
  • OnCollisionExit2D(CollisionInfo2D info) выполняется, когда коллайдер объекта не соприкасается ни с одним другим коллайдером.
  • OnTriggerEnter2D(Collider2D otherCollider) выполняется, когда коллайдер объекта соприкасается с другим коллайдером с пометкой «Trigger».
  • OnTriggerExit2D(Collider2D otherCollider) выполняется, когда коллайдер объекта перестает соприкасаться с коллайдером, помеченным как «Trigger».

Итак, с теорией покончено, пора в бой. Или нет, погодите еще немного: обратите внимание, что почти все, о чем мы говорили с вами имеет, суффикс «2D». Box Collider 2D , a Rigidbody 2D , OnCollisionEnter2D , OnTriggerEnter2D и т.д. Эти новые компоненты или методы появились с Unity 4.3. Используя их, вы работаете с физическим движком, встроенным в Unity 4.3, для 2D-игр (на основе Box2D) вместо движка для 3D-игр (PhysX). Два движка имеют аналогичные концепции и объекты, но они не работают точно так же. Если вы начинаете работать с одним (например, Box2D для 2D-игр), придерживаqntcm его. Именно поэтому мы используем все объекты или методы с суффиксом «2D».

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

Using UnityEngine; /// /// Контроллер и поведение игрока /// public ); // 4 — движение в каждом направлении movement = new Vector2(speed.x * inputX, speed.y * inputY); > vo >

Поясню цифры в комментариях к коду:

  1. Сначала определим публичную переменную, которая будет отображаться в окне «Инспектор». Это скорость, используемая для корабля.
  2. Сохраним движение для каждого кадра.
  3. Используем дефолтную ось, которую можно отредактировать в «Edit» -> «Project Settings» -> «Input» . При этом мы получим целые значения между [-1, 1] , где 0 будет означать, что корабль неподвижен, 1 — движение вправо, -1 — влево.
  4. Умножим направление на скорость.
  5. Изменим скорость rigidbody. Это даст движку команду к перемещению объекта. Сделаем это в FixedUpdate() , предназначенном для всего, что связано с физикой.

Заметка о соглашениях C# : Посмотрите на видимость speed члена класса – он обозначен как публичный. В C# переменная члена класса должна быть приватной для соответствующего сохранения его внутренней репрезентации.
Но смена типа переменной на публичный позволяет редактировать ее в Unity через панель «Inspector», даже в процессе игры. Это одна из самых мощных возможностей Unity, позволяющая изменять геймплей без использования кода.
Помните, что в данном случае мы создаем скрипты, а это не то же самое, что классическое программирование на C#. Это предполагает некоторых правил и соглашений.

Теперь добавим скрипт к игровому объекту. Для этого перетащите скрипт из окна «Проект» (Project) на игровой объект в «Иерархии» (Hierarchy). Вы также можете нажать на «Add Component» и добвить его вручную.

Нажмите кнопку «Play» в верхней части окна редактора. Корабль движется! Congratulations, Вы только что сделали эквивалент «Hello, World!» для игры:)

Попробуйте настроить скорость: нажмите на игрока, измените значения скорости в «Инспекторе», и посмотрите что из этого получится.

Будьте осторожны: изменения параметров, сделанные во время, игры теряются, когда вы ее остановите! Инспекторе — это отличный инструмент для настройки геймплея, но запомните или запишите, что вы делали, если хотите сохранить изменения. Этот же трюк подходит, если вы хотете проверить что-то новое, но не хотите вносить изменения в реальный проект.

Первый враг

Теперь добавим неприятелей, стремящихся уничтожить наш корабль. Пусть им будет зловещий спрут, названный «Poulpi»:

Создадим новый спрайт. Для этого:

  1. Скопируйте картинку в папку «Textures».
  2. Создайте новый спрайт, используя это изображение.
  3. Измените свойство «Масштаб» (Scale) в разделе Трансформирование (Transform) на (0.4, 0.4, 1) .
  4. Добавьте «Box Collider 2D» размером (4, 4) .
  5. Add a «Rigidbody 2D» with a «Gravity Scale» of 0 and «Fixed Angles» ticked.

Сохраните префаб и. вуаля!

Скрипт

Теперь напишем простенький скрипт, отвечающий за движение осьминога в определенном направлении. Для этого создайте новый скрипт, назвав его «MoveScript».

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

Скопируем некоторые части кода, который мы написали в «PlayerScript» для движения персонажа. We will add another designer (a public member you can alter in the «Inspector») variable for the direction:

Прикрепите скрипт к осьминогу. Нажмите «Play» и убедитесь, что спрут движется так, как показано на рисунке ниже:

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

Вы узнали, как добавить игрока, движущегося с помощью клавиатуры. Также, мы создали врага с зачаточным AI. Теперь мы хотим иметь возможность уничтожить его! А для этого, нам нужны боеприпасы, которые мы создадим в следующем уроке .

Всем привет. Продолжаем дело, начатое в первой части. Сейчас у нас есть платформа и стоящий на ней персонаж с анимацией покоя. Настало время научить нашего персонажа бегать вправо-влево по платформе.

Загрузим сцену из первой части. Напомню, что в прошлый раз мы импортировали несколько спрайтов в папку AssetsSprites . На всякий случай, внизу поста еще раз приведу ссылку на спрайты. Среди них должен быть спрайт под названием Run . Мы будем использовать его для создания анимации бега. Для этого нам надо проделать те же действия по превращению одиночного спрайта в коллекцию, как и при создании анимации покоя. Вкратце напомню: выделяем спрайт, в окне Inspector устанавливаем свойство Sprite Mode как Multiple , нажимаем ниже Sprite Editor , нарезаем изображение в режиме Grid или Automatic .

Теперь в окне Hierarchy выбираем Character и переходим в окно Animation . Нажимаем на поле с анимацией Idle и выбираем Create New Clip , чтобы создать анимацию бега. Сохраним файл анимации в папке AssetsAnimations под именем Run .

Новая созданная анимация Run стала текущей в окне Animation . Разворачиваем спрайт Run в окне Project , выделяем все фалы Run_0… Run_9 и перетаскиваем в окно Animation . Установим пока значение Sample равное 24.

Все это мы уже делали в первой части, а теперь будет нечто новое. Перейдем в окно Animator . Сейчас там отображены три анимации: Any State , Idle и Run . Нам предстоит задать условия перехода из анимации Idle в анимацию Run , то есть из состояния покоя в состояние бега. В нижнем левом углу есть поле Parameters . Нажимаем на плюсик, выбираем Float и называем новый параметр как Speed . Тем самым мы создали параметр типа число с плавающей запятой, обозначающий скорость перемещения персонажа. Именно в зависимости от значения этого параметра будет происходить переключение из анимации покоя в анимацию бега. Теперь нажимаем правой кнопкой мыши на анимацию Idle , выбираем Make Transition и нажимаем левой кнопкой мыши на анимацию Run . Между анимациями появится линия со стрелкой. Передвиньте мышкой прямоугольники анимации, если плохо видно. Кликнем по линии со стрелкой. В окне Inspector отобразятся свойства перехода между анимациями. Обратим внимание на низ окна, в раздел Conditions . Кликнем на параметр Exit Time и поменяем его на Speed . Второе поле Greater оставим без изменений, а в третьем введем значение 0.01 . Мы создали условие перехода из анимации покоя в анимацию бега — оно происходит, когда значение параметра скорости становится немногим больше нуля.

Теперь нужно сделать обратный переход — из Run в Idle . Делаем все с точностью наоборот: Make Transition от Run к Idle , выделяем переход, в Conditions устанавливаем SpeedLess0.01 .

Теперь у нас есть две анимации и условия перехода между ними. Но пока ничего работать не будет, потому что все что мы сделали нужно «оживить» при помощи скрипта. Давайте перейдем в окно Project и создадим в папке Assets подпапку Scripts . Добавим в нее новый C# Script , назовем его CharacterControllerScript и откроем на редактирование.

Я приведу полный листинг скрипта с подробными комментариями, а ниже еще поясню, что в нем происходит.
using UnityEngine; using System.Collections; public > /// Начальная инициализация /// private vo > /// Выполняем действия в методе FixedUpdate, т. к. в компоненте Animator персонажа /// выставлено значение Animate Physics = true и анимация синхронизируется с расчетами физики /// private vo , Mathf.Abs(move)); //обращаемся к компоненту персонажа Rig > 0 && !isFacingRight) //отражаем персонажа вправо Flip(); //обратная ситуация. отражаем персонажа влево else if (move /// Метод для смены направления движения персонажа и его зеркального отражения /// private vo >

Итак, мы завели несколько переменных: для задания максимальной скорости перемещения, для определения направления (вправо/влево) и для работы с компонентом Animator . Почти все действия происходят в методе FixedUpdate . В нем мы получаем значение оси Х , которое меняется при нажатии на клавиатуре клавиш влево-вправо или A-D (если не меняли соответствующие настройки проекта!). Затем устанавливаем это значение параметру Speed компонента Animator . Обратите внимание, что мы берем модуль этого значения при помощи метода Mathf.Abs , так как при создании условий перехода между анимациями покоя и бега мы сравниваем значение параметра с положительным числом 0.01 . Нам здесь не важно, в какую сторону бежит персонаж. Важно лишь величина значения. Далее задаем скорость перемещения по оси Х в соответствии со значением максимальной скорости. И, наконец, проверяем, в какую сторону бежит персонаж, и в какую сторону он в этот момент повернут. Если он бежит вправо, а повернут влево — разворачиваем его вправо путем инвертирования его размера по оси Х . И наоборот. Этим нехитрым способом мы избавились от необходимости делать две анимации вместо одной: для бега вправо и для бега влево.

Сохраняем скрипт. В Unity перетаскиваем его на нашего Character в окне Hierarchy . Запускаем игру, нажимаем влево-вправо или A-D.

Капитан Коготь теперь умеет бегать! Скорость анимации получилась быстроватой. Ее можно снизить путем уменьшения значения Sample в окне Animation для анимации Run (значение 12 будет нормально). Если одновременно с игрой у вас видно окно Animator , то вы увидите, что во время покоя работает анимация Idle (бегает синий прогрессбар), а во время бега происходит переход на анимацию Run , и, соответственно, работает она.

На этом пока все. Нам осталось разобраться с прыжками… и узнать при этом еще несколько новых вещей!

Пишем арканоид на Unity. Механика мяча и платформы

Всем привет. Продолжаем дело, начатое в первой части. Сейчас у нас есть платформа и стоящий на ней персонаж с анимацией покоя. Настало время научить нашего персонажа бегать вправо-влево по платформе.

Загрузим сцену из первой части. Напомню, что в прошлый раз мы импортировали несколько спрайтов в папку AssetsSprites . На всякий случай, внизу поста еще раз приведу ссылку на спрайты. Среди них должен быть спрайт под названием Run . Мы будем использовать его для создания анимации бега. Для этого нам надо проделать те же действия по превращению одиночного спрайта в коллекцию, как и при создании анимации покоя. Вкратце напомню: выделяем спрайт, в окне Inspector устанавливаем свойство Sprite Mode как Multiple , нажимаем ниже Sprite Editor , нарезаем изображение в режиме Grid или Automatic .

Теперь в окне Hierarchy выбираем Character и переходим в окно Animation . Нажимаем на поле с анимацией Idle и выбираем Create New Clip , чтобы создать анимацию бега. Сохраним файл анимации в папке AssetsAnimations под именем Run .

Новая созданная анимация Run стала текущей в окне Animation . Разворачиваем спрайт Run в окне Project , выделяем все фалы Run_0… Run_9 и перетаскиваем в окно Animation . Установим пока значение Sample равное 24.

Все это мы уже делали в первой части, а теперь будет нечто новое. Перейдем в окно Animator . Сейчас там отображены три анимации: Any State , Idle и Run . Нам предстоит задать условия перехода из анимации Idle в анимацию Run , то есть из состояния покоя в состояние бега. В нижнем левом углу есть поле Parameters . Нажимаем на плюсик, выбираем Float и называем новый параметр как Speed . Тем самым мы создали параметр типа число с плавающей запятой, обозначающий скорость перемещения персонажа. Именно в зависимости от значения этого параметра будет происходить переключение из анимации покоя в анимацию бега. Теперь нажимаем правой кнопкой мыши на анимацию Idle , выбираем Make Transition и нажимаем левой кнопкой мыши на анимацию Run . Между анимациями появится линия со стрелкой. Передвиньте мышкой прямоугольники анимации, если плохо видно. Кликнем по линии со стрелкой. В окне Inspector отобразятся свойства перехода между анимациями. Обратим внимание на низ окна, в раздел Conditions . Кликнем на параметр Exit Time и поменяем его на Speed . Второе поле Greater оставим без изменений, а в третьем введем значение 0.01 . Мы создали условие перехода из анимации покоя в анимацию бега — оно происходит, когда значение параметра скорости становится немногим больше нуля.

Теперь нужно сделать обратный переход — из Run в Idle . Делаем все с точностью наоборот: Make Transition от Run к Idle , выделяем переход, в Conditions устанавливаем SpeedLess0.01 .

Теперь у нас есть две анимации и условия перехода между ними. Но пока ничего работать не будет, потому что все что мы сделали нужно «оживить» при помощи скрипта. Давайте перейдем в окно Project и создадим в папке Assets подпапку Scripts . Добавим в нее новый C# Script , назовем его CharacterControllerScript и откроем на редактирование.

Я приведу полный листинг скрипта с подробными комментариями, а ниже еще поясню, что в нем происходит.
using UnityEngine; using System.Collections; public > /// Начальная инициализация /// private vo > /// Выполняем действия в методе FixedUpdate, т. к. в компоненте Animator персонажа /// выставлено значение Animate Physics = true и анимация синхронизируется с расчетами физики /// private vo , Mathf.Abs(move)); //обращаемся к компоненту персонажа Rig > 0 && !isFacingRight) //отражаем персонажа вправо Flip(); //обратная ситуация. отражаем персонажа влево else if (move /// Метод для смены направления движения персонажа и его зеркального отражения /// private vo >

Итак, мы завели несколько переменных: для задания максимальной скорости перемещения, для определения направления (вправо/влево) и для работы с компонентом Animator . Почти все действия происходят в методе FixedUpdate . В нем мы получаем значение оси Х , которое меняется при нажатии на клавиатуре клавиш влево-вправо или A-D (если не меняли соответствующие настройки проекта!). Затем устанавливаем это значение параметру Speed компонента Animator . Обратите внимание, что мы берем модуль этого значения при помощи метода Mathf.Abs , так как при создании условий перехода между анимациями покоя и бега мы сравниваем значение параметра с положительным числом 0.01 . Нам здесь не важно, в какую сторону бежит персонаж. Важно лишь величина значения. Далее задаем скорость перемещения по оси Х в соответствии со значением максимальной скорости. И, наконец, проверяем, в какую сторону бежит персонаж, и в какую сторону он в этот момент повернут. Если он бежит вправо, а повернут влево — разворачиваем его вправо путем инвертирования его размера по оси Х . И наоборот. Этим нехитрым способом мы избавились от необходимости делать две анимации вместо одной: для бега вправо и для бега влево.

Сохраняем скрипт. В Unity перетаскиваем его на нашего Character в окне Hierarchy . Запускаем игру, нажимаем влево-вправо или A-D.

Капитан Коготь теперь умеет бегать! Скорость анимации получилась быстроватой. Ее можно снизить путем уменьшения значения Sample в окне Animation для анимации Run (значение 12 будет нормально). Если одновременно с игрой у вас видно окно Animator , то вы увидите, что во время покоя работает анимация Idle (бегает синий прогрессбар), а во время бега происходит переход на анимацию Run , и, соответственно, работает она.

На этом пока все. Нам осталось разобраться с прыжками… и узнать при этом еще несколько новых вещей!

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

Вот список всех статей:

Где мы остановились?

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

Превью результата

Движение платформы

Сама платформа у нас уже есть — мы ее создали еще в прошлом уроке. Осталось научить ее двигаться, причем исключительно влево или вправо, т.е. по оси X. Для этого нам потребуется написать сценарий (Script ).

Сценарии представляют собой фрагменты программного кода, которые ответственны за какую-то конкретную задачу. Unity может работать со скриптами, написанными на трех языках программирования: Boo, JavaScript и C#. Мы будем использовать последний, но вы можете попробовать свои силы и с другими языками.

Итак, для создания скрипта перейдем на вкладку Project , найдем там одноименную папку Scripts и кликнем на нее правой кнопкой мыши. Выберем Create -> C# Script . Появится новый файл с названием NewBehaviourScript . Переименуйте его в PlayerScript для удобства. На вкладке Inspector вы можете видеть содержимое скрипта.

Двойным кликом откройте скрипт. Запуститься среда разработки MonoDevelop, которую вы впоследствии можете изменить на любой удобный для вас редактор. Вот то, что вы увидите:

Using UnityEngine; using System.Collections; public class NewBehaviourScript: MonoBehaviour < // используйте этот метод для инициализации void Start () < >// Update вызывается при отрисовке каждого кадра игры void Update () < >>

Все сценарии на Unity имеют по умолчанию два метода:

  • Start() : используется для инициализации переменных или параметров, необходимых нам в коде.
  • Update() : вызывается каждый кадр игры, необходим для обновления состояния игры.

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

Таким образом, необходимо создать две переменные для сохранения этой информации:

public float playerVelocity;
private Vector3 playerPosition;

Обратите внимание, что одна переменная объявлена публично, а вторая — приватно. Для чего это делается? Дело в том, что Unity позволяет редактировать значения публичных переменных не переходя в редактор MonoDevelop, без необходимости изменения кода. Эта возможность очень полезна в тех случаях. когда необходимо «на лету» корректировать какое-то значение. Скорость платформы — одно из таких значений, и именно поэтому мы объявили его публично.

Сохраните сценарий в редакторе MonoDevelop и перейдите в редактор Unity. Теперь у нас есть сценарий и нам нужно присвоить его какому то объекту, в нашем случае — платформе. Выберите нашу платформу во вкладке Hierarchy и в окне Inspector добавьте компонент, кликнув на кнопку Add Component .

Добавление нашего скрипта в компонент можно сделать и по-другому. Перетащите наш сценарий в область кнопки Add Component . Во вкладке Inspector вы должны увидеть что-то подобное:

Обратите внимание, что в компоненте скрипта появилось поле Player Velocity , которое можно тут же изменить. Это получилось возможным благодаря публичному объявлению переменной. Установите параметр в значение 0.3 и перейдите в редактор MonoDevelop.

Теперь нам надо узнать позицию платформы: playerPosition . Для того, чтобы инициализировать переменную, следует обратиться к объекту сценария в методе Start() :

// используйте этот метод для инициализации vo >

Отлично, мы определили начальную позицию платформы, и теперь можно ее двигать. Так как нам надо, чтобы платформа перемещалась только по оси X, то мы сможем использовать метод GetAxis класса Input . Этой функции мы передадим строку Horizontal , и она вернет нам 1, если была нажата клавиша «вправо», и -1 — «влево». Умножив полученное число на скорость и прибавив эту величину к текущей позиции игрока, мы и получим движение.

Также добавим проверку на выход из приложения по нажатию на клавишу Esc .

Вот то, что у нас должно получиться в итоге:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; > >

Сохраните скрипт и вернитесь в редактор Unity. Нажмите кнопку Play и попробуйте передвинуть платформу при помощи кнопок «влево» и «вправо».

Определение игровой области

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

Давайте добавим в наш существующий скрипт еще одну публичную переменную и назовем его boundary .

Эта переменная будет хранить максимальную координату платформы по оси X. Так как мы собираемся строить уровни в симметричной форме вокруг точки с координатами (0, 0, 0), то абсолютное значение переменной boundary будет одинаковым и для положительной части оси X, и для отрицательной.

А теперь добавим пару условий. Поступим достаточно просто: если вычисленная нами позиция будет больше boundary или меньше -boundary , то мы просто зададим новую позицию по оси X, равную значению переменной boundary . Таким образом, мы гарантируем, что платформа не уедет за пределы наших границ и никогда не покинет игровую зону. Вот код:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; // проверка выхода за границы if (playerPosition.x boundary) < transform.position = new Vector3(boundary, playerPosition.y, playerPosition.z); >> >

Теперь вернитесь в редактор и, переключаясь в игру, найдите оптимальное значение переменной boundary . В нашем случае подошло число 5.46. Откройте Inspector и сбросьте позицию платформы по оси X на 0, а параметр Boundary выставьте согласно найденному вами значению.

Нажмите кнопку Play и убедитесь в том, что вы все сделали правильно. Платформа должна двигаться только в пределах игрового поля.

Включение физики

Чтобы столкновения были более реалистичные — воспользуемся симуляцией физики. В этой статье мы добавим физические свойства мячику, платформе и границам поля. Так как мы пишем 2D игру, то будем использовать 2D коллайдеры. Коллайдер — это отдельный тип компонентов, который позволяет объекту реагировать на коллайдеры других объектов.

В окне Hierarchy выберем нашу платформу, перейдем в Inspector и нажмем на кнопку Add Component . В появившемся окошке наберем collider . Как вы можете увидеть — вариантов достаточно много. Каждый коллайдер имеет специфические свойства, соответствующие связанным объектам — прямоугольникам, кругам и т.д.

Так как наша платформа имеет прямоугольную форму, мы будем использовать Box Collider 2D . Выберите именно его, и компонент автоматически определит размеры платформы: вам не нужно будет задавать их вручную, Unity сделает это за вас.

Сделайте то же самое и для 3 границ (Hierarchy -> Inspector -> Add Component -> Box Collider 2D ).

С мячиком чуть-чуть по другому: он имеет круглую форму. Выберем мяч и добавим для нее компонент Circle Collider 2D .

На самом деле коллайдер окружности и прямоугольника очень похожи, за исключением того, что вместо параметра Size , определяющим ширину и длину, в окружности используется Radius . Объяснения здесь, думаем, излишни.

Упругое столкновение

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

Откройте окно Project и внутри папки Asset создайте новую папку под названием Physics . Кликните по только что созданной папке правой кнопкой мыши и выберите Create -> Physics2D Material . Задайте название BallPhysicsMaterial .

Каждая поверхность в Unity имеет два параметра: трение (friction) и упругость (bounciness) . Более подробно вы можете прочитать про физический движок и ряд физических параметров . Если вам требуется абсолютно упругое тело, то следует выставить трение на 0, а упругость на 1.

Сейчас у нас есть готовый материал, но он пока никак не связан с мячом. Выберите объект мяча во вкладке Hierarchy и в окне Inspector вы увидите поле Material компонента Circle Collider 2D . Перетащите сюда недавно созданный материал.

Добавление компонента Rigid Body

Для того, чтобы наш мячик двигался под контролем физики, мы должны добавить ему еще один компонент: Rigid Body 2D . Выберите объект мяча в окне Hierarchy и добавьте вышеупомянутый компонент — хоть он и имеет несколько параметров, нас интересует только один: Gravity Scale . Так как наш шарик будет двигаться только за счет отскоков, то мы зададим этому параметру 0 — таким образом мы гарантируем, что гравитация не будет реагировать на объект. Все остальное можно не менять.

Поведения шарика

Давайте создадим для шарика отдельный скрипт (снова воспользуемся C# в качестве языка программирования) и назовем его BallScript . Свяжите созданный скрипт с объект (Hierarchy -> Inspector -> Add Component ).

Перед тем, как начать писать скрипт, давайте определим поведение шарика:

  1. Шар имеет два состояния: неактивное (когда он в начале игры находится на платформе) и активное (когда находится в движении).
  2. Шар будет становиться активным только один раз.
  3. Когда шар становится активным, мы применяем к нему силу для того, что он начал движение.
  4. Если шар вышел за пределы игрового поля, он переводится в неактивное состояние и помещается на платформу.

Основываясь на этой информации, давайте создадим глобальные переменные ballIsActive , ballPosition и ballInitialForce:

private bool ballIsActive;
private Vector3 ballPosition;
private Vector2 ballInitialForce;

Теперь, когда у нас есть набор переменных, мы должны подготовить объект. В методе Start() мы должны:

  • создать силу, которая будет применена к шару;
  • перевести шар в неактивное состояние;
  • запомнить позицию шара.

Вот, как это можно сделать:

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

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

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

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

В методе Update мы должны проверять состояние шарика, и в случае если оно неактивное, нам надо задать позицию мячика по оси X таким же, какое оно у платформы.

Решение достаточно простое, но как нам получить координату совсем другого объекта? Элементарно — мы создадим переменную типа GameObject и сохраним ссылку на объект платформы:

public GameObject playerObject;

Вернемся к методу Update() :

Сохраните скрипт и вернитесь в редактор Unity. Вы наверняка заметили, что переменная playerObject объявлена, используется, но нигде не инициализирована. Да, так и есть. Чтобы ее проинициализировать, перейдите во вкладку Hierarchy , найдите шар и в окне Inspector найдите компонент Ball Script . У данного компонента есть параметр Player Object , в настоящее время пустующий:

Найдите во вкладке Hierarchy нашу платформу и перетащите ее на поле Player Object . Запустите игру, нажав кнопку Play , и убедитесь, что все работает.

Сброс игры

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

Это состояние отловить очень просто: шар будет активен, а его положение по оси Y отрицательно. Если это так, то мы переводим шар в неактивное состояние и ставим его на платформу:

If (ballIsActive && transform.position.y

А вот теперь точно все. Запустите игру и проверьте, все ли работает как положено.

В следующей части

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

Итак. Всем привет. И сегодня я расскажу, как сделать простое движение персонажа. Сейчас только от третьего лица. Приступим.
Начнём, пожалуй, с создания персоажа. У меня это будет куб. Кто не знает, как создавать кубы или круги, поясняю — «GameObject» => «CreateOther» => «Cube». Создаём таким же образом камеру и привязываем к кубу (то бишь просто в иерархии перетаскиваем камеру на куб).
Так. Теперь создадим поверхность, по которой персонаж будет ходить. Пусть это будет просто «Plane». Ах, да. В конце урока будет ссылка с исходником по туториалу для тех, кто не понял.
Итак. Теперь создадим скрипт «Move». Добавим переменную игрока и переменную скорости.

Public GameObject player;
public int speed = 5;

Теперь укажем в методе старта, что это объект, на котором висит скрипт.

Void Start () <
player = (GameObject)this.gameObject;
>

Теперь сделаем само передвижение игрока вперёд при нажатии на «W» или стрелку вверх. Это делаем в методе void Update()! Для этого мы будем прибавлять позицию. Например вперёд.

If (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
>

Мы прибавили позицию вперёд (forward) и умножили на скорость, а точнее её переменную. И обязательно надо умножить на кадры в секунду (deltaTime).
Таким же образом сделаем движение назад. Только будем отнимать позицию.

If (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>

Таким же образом можем сделать и вправо и влево (right, left), но я сделаю просто поворот игрока, при нажатии на «A» или «D».
Я буду использовать «Rotate()». Чтобы поворачивать по оси «Y», я буду использовать «up» и «down». Кстати, для этого ещё надо объявить переменную «public int speedRotation = 3». И пишем в условиях.

If (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>

Ну. Сейчас пришло время анимировать. Я записываю анимацию в самой юнити. Это можно открыть в «Window» => «Animation». В этом окне мы можем анимировать куб. Итак. Пропустим момент создания анимации. Давайте теперь создадим переменную анимации.

Public AnimationClip anima;

Теперь в старте добавим клип.

Теперь мы будем его воспроизводить через «CrossFade». Воспроизводить буду в условиях ходьбы вперёд и назад. Чтобы воспроизвести, нужно написать.

Итак. У нас получился хороший код. Сейчас мы сделаем прыжок. Всё так же просто. Опять мы будем прибавлять позицию. Только вверх (up).
И так же с новой переменной анимации «public AnimationClip anima2;»? так же добавим и переменной «public int jumpSpeed = 50;». И мы получаем условие.

If (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

Всё. Наш код готов.

using UnityEngine;
using System.Collections;
public class Move: MonoBehaviour <
public GameObject player;
public int speedRotation = 3;
public int speed = 5;
public AnimationClip anima;
public int jumpSpeed = 50;

Vo courier new font-size: text-align: justify> player = (GameObject)this.gameObject;
animation.AddClip(anima, «animCube»);
>
void Update() <
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
player.transform.position += player.transform.forward * speed * Time.deltaTime;
animation.CrossFade(«animCube»);
>
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>
if (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

В второй главе о разработке игры на Unity мы добавим игрока и его врагов в сцену

Создание игрока в Unity

Создание объекта, контролируемого игроком, требует наличия определенных элементов: спрайт, способ управления им и способ его взаимодействия с игровым миром. Рассмотрим этот процесс шаг за шагом и начнем, пожалуй, со спрайта. Вот изображение, которое мы будем использовать:

  1. Скорируйте картинку в папку «Textures»
  2. Создайте новый спрайт и назовите его «Player»
  3. Настройте спрайт так, чтобы он отображался в свойстве «Sprite» компонента «Sprite Renderer»

Если у вас возникли проблемы, обратитесь к предыдущему уроку. Мы проделали точно такие же действия для фона и «реквизита».

  1. Поместите игрока в слой «2 — Foreground»
  2. Измените масштаб на (0.2, 0.2, 1)

Теперь несколько слов о компонентах. Мы только что говорили о компоненте «Sprite Renderer». Если вы еще не заметил, объект игры состоит из нескольких компонентов, видимых в панели «Инспектор».

По умолчанию пустой объект игры выглядит так:

Этот объект имеет только один компонент: Transform . Этот компонент является обязательным и не может быть отключен или удален. Вы можете добавить к объекту столько компонентов, сколько захотите. Например, скрипты добавляются в качестве компонента. Большинство компонентов может быть включено или отключено пока существует объект.

(Вы можете нажать на галочку чекбокса, чтобы отключить его. Вы можете щелкнуть правой кнопкой мыши на компоненте, чтобы вернуть прежнее свойство, удалить его и т.д.

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

Sprite Renderer является компонентом, который способен отображать спрайт-текстуру. Теперь, когда мы узнали о концепции компонента, давайте добавим один к игроку!

Добавляем бокс-коллайдер (Box Collider)

Нажмите на кнопку «Добавить компонент» объекта игрока. Выберите «Box Collider 2D». Вы можете увидеть коллайдер в редакторе «Сцена» зрения и настройки его размера в «Инспекторе» в поле «Размер» (Size).

Существует еще один способ редактирования бокс-коллайдера. Выберите игровой объект с помощью бокс-коллайдера и зажмите клавишу shift на клавиатуре. Вы увидите, что на бокс-коллайдере (зеленый прямоугольник ) появились четыре маленьких рычажка. Перетащите один из них, чтобы изменить форму бокс-коллайдера. Будьте осторожны, синий прямоугольник представляет собой компонент Transform вашего игрового объекта, а не коллайдер.

Мы будем устанавливать размер коллайдера равным (10, 10) .

Это слишком много для настоящего шмапа, но все же меньше, чем спрайт:

В настоящее время, этого вполне достаточно.

Совет : Если вы планируете создать шмап , вам придется уделить много времени настройке хитбоксов – они должны точно соответствовать маленькому элементу внутри игрового спрайта. Вы также можете изменить такой параметр коллайдера, как shape – например, с помощью «Circle Collider 2D». Благодаря Unity, его поведение при этом не меняется, но это позволяет немного улучить геймплей.

Сохраним объект игрок как префаб. Теперь у вас есть базовую сущность игрока!

2D полигональный коллайдер

Если вы хотите супер точный и произвольный формы хитбокс, воспользуйтесь компонентом Unity «Полигоннальный коллайдер 2D» (Polygon Collider 2D). Эффект от этого будет незначительный, но зато вы получите такую форму, какую вы хотите.

«Polygon Collider 2D» похож на остальные коллайдеры: вы можете изменять форму с помощью мышки в режиме «Scene». Для удаления точки зажмите cmd или ctrl , а чтобы отрегулировать положение точки или добавить ее в форму коллайдера, используйте shift

Магия Rigidbody

Последний компонент, необходимый для добавления на нашего игрока: «Rigidbody 2D». Это поможет физическому движку правильно задействовать объект в игровом пространстве. Более того, это позволит вам использовать столкновения в скрипте.

  1. Выберите объект Player в «Hierarchy».
  2. Добавьте компонент «Rigidbody 2D».

Теперь, нажмите кнопку «играть» и смотрите, что у нас вышло:

Корабль падает! И как падает! Передвайте привет нашей любимой силе тяжести. По мере того, как сменяются кадры с заранее заданной гравитацией и rigidbodies прибавляет объекту массы, корабль притягивается к нижней части экрана.

По-умолчанию, ускорние свободного падения в Unity равно 9.81 , т.е. мы имеем дело с земной гравитацией.

Гравитация может быть использована в любой игре, но нам она не нужна. К счастью, гравитацию на Rigidbody можн легко отключить. Просто установите «гравитационный масштаб» равным нулю. Вот и все, корабль снова летит. Не забудьте поставить галочку в окошке «Fixed Angles», чтобы предотвратить вращение корабля, обусловленное такой физикой.

Перемещение игрока

Настало время написать скриптик (вы ведь не думали, что все будет двигаться само)? Создайте в Unity C#-скрипт в папке «Scripts» и назовите это «PlayerScript». Откройте ваш любимый редактор или используйте подменю «Sync» (нажмите на «Assets» в строке меню, затем на «Sync MonoDevelop Project») для правки созданного Unity скрипта.

«Sync MonoDevelop Project» : Это подменю немного странное.Во-первых, невозможно изменить имя, даже если сменить редактора.
Мы также рекомендуем использовать это меню при создании первого скрипта, так как Unity создаст решения и привяжет их к библиотекам Unity (для Visual Studio, Xamarin Studio или MonoDevelop).
Если вместо этого вы просто откроете скрипт, компилятор вашего IDE, скорее всего, зарегистрирует определенные ошибки, не Unity. Это не имеет значения, потому что вам не придется использовать его напрямую, но функция автоматического завершения объектов Unity не помешает.

По умолчанию в скрипте уже прописаны методы Start и Update . Вот краткий список наиболее часто используемых функций:

  • Awake() вызывается один раз, когда объект создается. По сути аналог обычной функции-конструктора.
  • Start() выполняется после Awake() . Отличается тем, что метод Start() не вызывается, если скрипт не включен (remember the checkbox on a component in the «Inspector»).
  • Update() выполняется для каждого кадра in the main game loop.
  • FixedUpdate() вызывается каждый раз через определеннок число кадров. Вы можете вызывать этот метод вместо Update() когда имеете дело с физикой («RigidBody» и др.).
  • Destroy() вызывается, когда объект уничтожается. Это ваш последний шанс, чтобы очистить или выполнить код.

У вас также есть некоторые функции для обработки столкновений:

  • OnCollisionEnter2D(CollisionInfo2D info) выполняется, когда коллайдер объекта соприкасается с другим коллайдером.
  • OnCollisionExit2D(CollisionInfo2D info) выполняется, когда коллайдер объекта не соприкасается ни с одним другим коллайдером.
  • OnTriggerEnter2D(Collider2D otherCollider) выполняется, когда коллайдер объекта соприкасается с другим коллайдером с пометкой «Trigger».
  • OnTriggerExit2D(Collider2D otherCollider) выполняется, когда коллайдер объекта перестает соприкасаться с коллайдером, помеченным как «Trigger».
Мастер Йода рекомендует:  Подходы и инструменты для разработки пользовательского интерфейса

Итак, с теорией покончено, пора в бой. Или нет, погодите еще немного: обратите внимание, что почти все, о чем мы говорили с вами имеет, суффикс «2D». Box Collider 2D , a Rigidbody 2D , OnCollisionEnter2D , OnTriggerEnter2D и т.д. Эти новые компоненты или методы появились с Unity 4.3. Используя их, вы работаете с физическим движком, встроенным в Unity 4.3, для 2D-игр (на основе Box2D) вместо движка для 3D-игр (PhysX). Два движка имеют аналогичные концепции и объекты, но они не работают точно так же. Если вы начинаете работать с одним (например, Box2D для 2D-игр), придерживаqntcm его. Именно поэтому мы используем все объекты или методы с суффиксом «2D».

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

Using UnityEngine; /// /// Контроллер и поведение игрока /// public ); // 4 — движение в каждом направлении movement = new Vector2(speed.x * inputX, speed.y * inputY); > vo >

Поясню цифры в комментариях к коду:

  1. Сначала определим публичную переменную, которая будет отображаться в окне «Инспектор». Это скорость, используемая для корабля.
  2. Сохраним движение для каждого кадра.
  3. Используем дефолтную ось, которую можно отредактировать в «Edit» -> «Project Settings» -> «Input» . При этом мы получим целые значения между [-1, 1] , где 0 будет означать, что корабль неподвижен, 1 — движение вправо, -1 — влево.
  4. Умножим направление на скорость.
  5. Изменим скорость rigidbody. Это даст движку команду к перемещению объекта. Сделаем это в FixedUpdate() , предназначенном для всего, что связано с физикой.

Заметка о соглашениях C# : Посмотрите на видимость speed члена класса – он обозначен как публичный. В C# переменная члена класса должна быть приватной для соответствующего сохранения его внутренней репрезентации.
Но смена типа переменной на публичный позволяет редактировать ее в Unity через панель «Inspector», даже в процессе игры. Это одна из самых мощных возможностей Unity, позволяющая изменять геймплей без использования кода.
Помните, что в данном случае мы создаем скрипты, а это не то же самое, что классическое программирование на C#. Это предполагает некоторых правил и соглашений.

Теперь добавим скрипт к игровому объекту. Для этого перетащите скрипт из окна «Проект» (Project) на игровой объект в «Иерархии» (Hierarchy). Вы также можете нажать на «Add Component» и добвить его вручную.

Нажмите кнопку «Play» в верхней части окна редактора. Корабль движется! Congratulations, Вы только что сделали эквивалент «Hello, World!» для игры:)

Попробуйте настроить скорость: нажмите на игрока, измените значения скорости в «Инспекторе», и посмотрите что из этого получится.

Будьте осторожны: изменения параметров, сделанные во время, игры теряются, когда вы ее остановите! Инспекторе — это отличный инструмент для настройки геймплея, но запомните или запишите, что вы делали, если хотите сохранить изменения. Этот же трюк подходит, если вы хотете проверить что-то новое, но не хотите вносить изменения в реальный проект.

Первый враг

Теперь добавим неприятелей, стремящихся уничтожить наш корабль. Пусть им будет зловещий спрут, названный «Poulpi»:

Создадим новый спрайт. Для этого:

  1. Скопируйте картинку в папку «Textures».
  2. Создайте новый спрайт, используя это изображение.
  3. Измените свойство «Масштаб» (Scale) в разделе Трансформирование (Transform) на (0.4, 0.4, 1) .
  4. Добавьте «Box Collider 2D» размером (4, 4) .
  5. Add a «Rigidbody 2D» with a «Gravity Scale» of 0 and «Fixed Angles» ticked.

Сохраните префаб и. вуаля!

Скрипт

Теперь напишем простенький скрипт, отвечающий за движение осьминога в определенном направлении. Для этого создайте новый скрипт, назвав его «MoveScript».

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

Скопируем некоторые части кода, который мы написали в «PlayerScript» для движения персонажа. We will add another designer (a public member you can alter in the «Inspector») variable for the direction:

Прикрепите скрипт к осьминогу. Нажмите «Play» и убедитесь, что спрут движется так, как показано на рисунке ниже:

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

Вы узнали, как добавить игрока, движущегося с помощью клавиатуры. Также, мы создали врага с зачаточным AI. Теперь мы хотим иметь возможность уничтожить его! А для этого, нам нужны боеприпасы, которые мы создадим в следующем уроке .

Введение:

1. Шаг

2. Шаг

Сначала создайте землю для нашей игры. Импортируйте largeGround из загруженного архива ( ссылка снова, если ещё не скачали. Распакуйте архив.zip после его загрузки).

Перетащите largeGround в сцену. Переименуйте созданный игровой объект как Ground . Проверьте, что Z-позиция равна нулю (измените её на , если отличается). Добавьте к нему Box Collider 2D.

3. Шаг

Теперь мы можем сделать игрока. Для этого у меня есть лист спрайтов с крысой. Импортируйте ratIdle (из скаченного архива) в окно Assets . Нам надо разделить спрайты. Выберите ratIdle и переключите Sprite Mode на Multiple . Нажмите Apply .

Нажмите на Sprite Editor и новое окно будет открыто. Нажмите Slice . Измените Type на Grid By Cell Count . Установите Column на 4 и Row на 5 . Нажмите на кнопку Slice . Нажмите на Apply . Закройте это окно.

Раскройте спрайт. В нем должно быть теперь 20 кадров. Перетащите первый кадр в сцену. Будет создан новый игрвой объект. Выделите этот объект и назовите его Rat . Посмотрите на его Inspector . Измените Tag на Player . Убедитесь, что его Z-позиция 0. Добавьте к нему Capsule Collider 2D . Измените Direction на Horizontal . Нажмите на кнопку Edit и настройте размер коллайдера (тяните за зеленые точки). Теперь добавьте Rigidbody 2D . Установите Interpolate на Interpolate . Разверните Constraints и включите Freeze Rotation Z .

4. Шаг

public float speed;

Выберите крысу в иерархии и добавьте к ней скрипт PlayerMove . Измените переменную Speed (около 3). Вы можете запустить игру и проверить сцену. Крыса должна двигаться влево и вправо (использовать левую/правую стрелку или A/D).

5. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class PlayerMove: MonoBehaviour <

public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;

void Start () <
//делаем ссылку на Rigidbody2D
rb = GetComponent ();
>

//переключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
>
>

void FixedUpdate () <
//изменяем переменную, зависящую от результата Physics2D.OverlapPoint

//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis («Horizontal» );
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f );
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
>
>

Выберите Rat в иерархии, щелкните по нему правой кнопкой мыши и выберите Create Empty . Выберите этот созданный объект и переименуйте его в GroundCheck .

Выберите GroundCheck и включите иконку для лучшей видимости (смотрите скриншот). Включите moving tool и передвиньте GroundCheck под крысу, но не в сам коллайдер крысы. Убедитесь, что его Z-Position равна 0.

Выберите Ground в иерархии и смените Layer на Ground (добавьте новый Layer с этим названием, если в списке нет такого).

Выделите Rat в иерархии. В компоненте PlayerMove есть теперь новые поля. Включите Ground в whatIsGround . Поместите GroundCheck в поле GroundCheck . Измените JumpForce на 5.

Проверьте игру. Крыса должна теперь двигаться налево/направо и прыгать.

6. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove: MonoBehaviour <

//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//переменная контроля направления крысы
public bool isLookingLeft;

void Start () <
//делаем ссылку на Rigidbody2D
rb = GetComponent ();
>

//я буду использовать Update() для более точного определения прыжка
void Update () <
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input .GetButtonDown («Jump» ) && isGrounded) <
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2 .up * jumpForce, ForceMode2D .Impulse);
//sпереключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
>
>

void FixedUpdate () <
//изменяем переменную, зависит от результата Physics2D.OverlapPoint
isGrounded = Physics2D .OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis («Horizontal» );
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f );
//изменить скорость игрока на вычисленный вектор
rb.velocity = move;

//функция поворота крысы
void TurnTheRat ()
<
//смена переменной показывающей направление взгляда на обратное значение
isLookingLeft = !isLookingLeft;
//поворот крысы через инвертацию размера по оси х
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>

Выберите крысу. В скрипте PlayerMove появилась новая переменная для обозначения направления взгляда. Включите её, так как крыса смотрит налево.

Крыса может теперь бежать влево и вправо и менять направление взгляда. Вы можете проверить сцену.

7. Step

Теперь можем начать анимировать крысу. Выберите Rat в иерархии и добавьте Animator к ней.

Создайте Animator Controller в Assets . Назовите его RatAnimator .

Выберите Rat и добавьте RatController в поле Controller .

Нам понадобится окно Animation . Включите его в меню Window м поместите его там, где вам удобно (я поместил над Assets ).

Выберите Rat в иерархии. Создайте новую анимацию (нажмите на кнопку Create ). Назовите эту новую анимацию IdleRatAnimation .

Теперь можем добавить спрайтовый лист. Выделите Rat в иерархии. Разверните ratIdle спрайт. Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key Animation

Включите окошко Animator в меню Window .

Анимация должна быть зацикленна. Убедитесь в этом на всякий случай. Перейдите к окну Animator и сделайте двойной клик на IdleRatAnimation Проверьте Loop Time .

У крысы есть теперь анимация покоя. Запустите сцену и проверьте.

8. Шаг

Теперь создадим анимацию бега. Импортируйте спрайт ratRun в Assets . Смените Sprite Mode на Multiple . Перейдите в Sprite Editor и переключите на Grid By Cell Count и установите Column 4 , Row 5 (смотрите 3. Шаг ). Выделите Rat в иерархии. Перейдите в окно Animations и нажмите на IdleRatAnimation потом нажмите на Create New Clip . Назовите новую анимацию RunRatAnimations .

Раскройте спрайт ratRun и выделите все 20 кадров (нажмите первый кадр, держите кнопку шифт и нажмите последний кадр). Перетащите все кадры в окошко Animations . Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).

Откройте окно Animator (включите его в меню Window , если не видите его).

IdleRatAnimation стандартная анимация. Нам нужны transition (переходы) к другим анимациям и параметры контроля этих transition. Нажмите на закладку Parameters . Добавьте новый float speed параметр. Сделайте правый клик на IdleRatAnimation и сделайте transition из IdleRatAnimation в RunRatAnimation . Потом правый клик на RunRatAnimation и добавьте transition на IdleRatAnimation .

Выберите transition от IdleRatAnimation к RunRatAnimation . Отключите Has Exit Time speed greater 0.01 .

Выберите transition от RunRatAnimation к IdleRatAnimation . Отключите Has Exit Time . Добавьте новое condition (условие). Измените его на speed less 0.01 .

Анимация бега сейчас слишком медленная. Выберите RunRatAnimation в Animator и измените скорость на 2.5 (можете потом настроить по желанию).

9. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

void Update () <
//меняем параметр speed в Animator. Используем значение скорости по оси х

Добавьте этот скрипт к крысе Rat .

Запустите сцену. У крысы должна появиться анимация бега

10. Шаг

Теперь сделаем анимацию прыжка. Выберите Rat в иерархии. Добавьте новую анимацию (в окошке Animation ) и назовите её JumpRatAnimation .

Я не сделал анимацию прыжка, просто используем замедленную анимацию бега. Выделите Rat в иерархии. Проверьте в окошке Animation , что JumpRatAnimation выбранна. Разверните спрайт ratRun . Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key и выделите последний кадр. Все 20 кадров должны выбраться. Перетащите все кадры в окошко Animation . Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).

11. Шаг

Переключитесь на Animator . Нам нужно условие для анимации прыжка. Добавьте новую Bool и назовите её isJumping . Сделайте теперь transition (переход) (правый клик) из Any State к JumpRatAnimation . Добавьте transition от JumpRatAnimation к IdleRatAnimation .

Выделите transition от Any State к JumpRatAnimation . Отключите Has Exit Time . Разверните Settings и отключите Can Transition To (чтобы избежать перезапуска анимации, пока isJumping true). Добавьте condition (условие) isJumping true .

Выберите transition от JumpRatAnimation к IdleRatAnimation . Отключите Has Exit Time . Добавьте condition isJumping false .

Выделите JumpRatAnimation и измените Speed на 0.5. Замедленная анимация бега должна заменить анимацию прыжка.

12. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAnim: MonoBehaviour <

//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
//ссылочная переменная для PlayerMove
PlayerMove pm;

void Update () <
//проверка, находится ли крыса на земле
if (pm.isGrounded) <
//меняем параметр isJumping на false
anim.SetBool («isJumping» , false );
//меняем параметр speed. Используем абсолютное значение вектора скорости по х
anim.SetFloat («speed» , Mathf .Abs (rb.velocity.x));
// если крыса не на земле
> else <
//меняем параметр speed на 0
anim.SetFloat («speed» , 0 );
//меняем параметр isJumping на true
anim.SetBool («isJumping» , true );
>
>

Можете проверить сцену.

13. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//ссылочная переменная для звукового файла
public AudioClip footsteps;

Выберите Rat в иерархии и добавьте этот скрипт к крысе. Импортируйте аудио-файл ratStep . И добавьте ratStep в Footsteps поле компонента PlayerSound .

Выделите Rat в иерархии и перейдите в Animation . Смените анимацию на RunRatAnimation . Выберите кадр, когда хотите воспроизвести звук (кликните на полоску времени). Нажмите на Add Event (смотрите скриншот). Выберите добавленный Animations Event и установите Function на FootStepsAudio() .

14. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerSound: MonoBehaviour <

//ссылочная переменная для аудио-файла
public AudioClip footsteps;

//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () <
//воспроизвести заданный звук на позиции крысы
AudioSource .PlayClipAtPoint (footsteps, transform.position);
>

//запустится если было касание другого Collider2D
void OnCollisionEnter2D (Collision2D coll) <
//проверка тэга на тэг «Ground»
if (coll.gameObject.tag == «Ground» ) <
//воспроизвести заданный звук на позиции крысы
AudioSource .PlayClipAtPoint (footsteps, transform.position);
>
>

Выберите Ground в иерархии. Добавьте новый тэг Ground и измените тэг объекта Ground на тэг Ground .

15. Шаг

Выберите Ground в иерархии. Создайте prefab Ground (перетащите объект в Assets ). Поместите prefab Ground в сцену, как следующую платформу.

Выберите Main Camera и сделайте её дочерним объектом Rat (перетащите Main Camera на Rat ). Камера будет следовать за крысой.

Можете изменить X-position камеры на 0, чтобы убрать рывки при повороте.
Я думаю, этого достаточно для первой части. Надеюсь, что вторая часть будет готова в мае-июне (у меня сейчас мало времени).

Пишем арканоид на Unity. Настройка проекта

We recommend upgrading to the latest Google Chrome or Firefox.

Permalink

  • © 2020 GitHub , Inc.
  • Terms
  • Privacy
  • Security
  • Status
  • Help

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Скрипт на движение 2d персонажа в unity3d. Пишем арканоид на Unity. Механика мяча и платформы

Public GameObject player;
public int speed = 5;

Теперь укажем в методе старта, что это объект, на котором висит скрипт.

Void Start () <
player = (GameObject)this.gameObject;
>

Теперь сделаем само передвижение игрока вперёд при нажатии на «W» или стрелку вверх. Это делаем в методе void Update()! Для этого мы будем прибавлять позицию. Например вперёд.

If (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
>

Мы прибавили позицию вперёд (forward) и умножили на скорость, а точнее её переменную. И обязательно надо умножить на кадры в секунду (deltaTime).
Таким же образом сделаем движение назад. Только будем отнимать позицию.

If (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>

Таким же образом можем сделать и вправо и влево (right, left), но я сделаю просто поворот игрока, при нажатии на «A» или «D».
Я буду использовать «Rotate()». Чтобы поворачивать по оси «Y», я буду использовать «up» и «down». Кстати, для этого ещё надо объявить переменную «public int speedRotation = 3». И пишем в условиях.

If (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>

Ну. Сейчас пришло время анимировать. Я записываю анимацию в самой юнити. Это можно открыть в «Window» => «Animation». В этом окне мы можем анимировать куб. Итак. Пропустим момент создания анимации. Давайте теперь создадим переменную анимации.

Public AnimationClip anima;

Теперь в старте добавим клип.

Теперь мы будем его воспроизводить через «CrossFade». Воспроизводить буду в условиях ходьбы вперёд и назад. Чтобы воспроизвести, нужно написать.

Итак. У нас получился хороший код. Сейчас мы сделаем прыжок. Всё так же просто. Опять мы будем прибавлять позицию. Только вверх (up).
И так же с новой переменной анимации «public AnimationClip anima2;»? так же добавим и переменной «public int jumpSpeed = 50;». И мы получаем условие.

If (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

Всё. Наш код готов.

using UnityEngine;
using System.Collections;
public class Move: MonoBehaviour <
public GameObject player;
public int speedRotation = 3;
public int speed = 5;
public AnimationClip anima;
public int jumpSpeed = 50;

Vo courier new font-size: text-align: justify> player = (GameObject)this.gameObject;
animation.AddClip(anima, «animCube»);
>
void Update() <
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
player.transform.position += player.transform.forward * speed * Time.deltaTime;
animation.CrossFade(«animCube»);
>
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>
if (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

В второй главе о разработке игры на Unity мы добавим игрока и его врагов в сцену

Создание игрока в Unity

Создание объекта, контролируемого игроком, требует наличия определенных элементов: спрайт, способ управления им и способ его взаимодействия с игровым миром. Рассмотрим этот процесс шаг за шагом и начнем, пожалуй, со спрайта. Вот изображение, которое мы будем использовать:

  1. Скорируйте картинку в папку «Textures»
  2. Создайте новый спрайт и назовите его «Player»
  3. Настройте спрайт так, чтобы он отображался в свойстве «Sprite» компонента «Sprite Renderer»

Если у вас возникли проблемы, обратитесь к предыдущему уроку. Мы проделали точно такие же действия для фона и «реквизита».

  1. Поместите игрока в слой «2 — Foreground»
  2. Измените масштаб на (0.2, 0.2, 1)

Теперь несколько слов о компонентах. Мы только что говорили о компоненте «Sprite Renderer». Если вы еще не заметил, объект игры состоит из нескольких компонентов, видимых в панели «Инспектор».

По умолчанию пустой объект игры выглядит так:

Этот объект имеет только один компонент: Transform . Этот компонент является обязательным и не может быть отключен или удален. Вы можете добавить к объекту столько компонентов, сколько захотите. Например, скрипты добавляются в качестве компонента. Большинство компонентов может быть включено или отключено пока существует объект.

(Вы можете нажать на галочку чекбокса, чтобы отключить его. Вы можете щелкнуть правой кнопкой мыши на компоненте, чтобы вернуть прежнее свойство, удалить его и т.д.

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

Sprite Renderer является компонентом, который способен отображать спрайт-текстуру. Теперь, когда мы узнали о концепции компонента, давайте добавим один к игроку!

Добавляем бокс-коллайдер (Box Collider)

Нажмите на кнопку «Добавить компонент» объекта игрока. Выберите «Box Collider 2D». Вы можете увидеть коллайдер в редакторе «Сцена» зрения и настройки его размера в «Инспекторе» в поле «Размер» (Size).

Существует еще один способ редактирования бокс-коллайдера. Выберите игровой объект с помощью бокс-коллайдера и зажмите клавишу shift на клавиатуре. Вы увидите, что на бокс-коллайдере (зеленый прямоугольник ) появились четыре маленьких рычажка. Перетащите один из них, чтобы изменить форму бокс-коллайдера. Будьте осторожны, синий прямоугольник представляет собой компонент Transform вашего игрового объекта, а не коллайдер.

Мы будем устанавливать размер коллайдера равным (10, 10) .

Это слишком много для настоящего шмапа, но все же меньше, чем спрайт:

В настоящее время, этого вполне достаточно.

Совет : Если вы планируете создать шмап , вам придется уделить много времени настройке хитбоксов – они должны точно соответствовать маленькому элементу внутри игрового спрайта. Вы также можете изменить такой параметр коллайдера, как shape – например, с помощью «Circle Collider 2D». Благодаря Unity, его поведение при этом не меняется, но это позволяет немного улучить геймплей.

Сохраним объект игрок как префаб. Теперь у вас есть базовую сущность игрока!

2D полигональный коллайдер

Если вы хотите супер точный и произвольный формы хитбокс, воспользуйтесь компонентом Unity «Полигоннальный коллайдер 2D» (Polygon Collider 2D). Эффект от этого будет незначительный, но зато вы получите такую форму, какую вы хотите.

«Polygon Collider 2D» похож на остальные коллайдеры: вы можете изменять форму с помощью мышки в режиме «Scene». Для удаления точки зажмите cmd или ctrl , а чтобы отрегулировать положение точки или добавить ее в форму коллайдера, используйте shift

Магия Rigidbody

Последний компонент, необходимый для добавления на нашего игрока: «Rigidbody 2D». Это поможет физическому движку правильно задействовать объект в игровом пространстве. Более того, это позволит вам использовать столкновения в скрипте.

  1. Выберите объект Player в «Hierarchy».
  2. Добавьте компонент «Rigidbody 2D».

Теперь, нажмите кнопку «играть» и смотрите, что у нас вышло:

Корабль падает! И как падает! Передвайте привет нашей любимой силе тяжести. По мере того, как сменяются кадры с заранее заданной гравитацией и rigidbodies прибавляет объекту массы, корабль притягивается к нижней части экрана.

По-умолчанию, ускорние свободного падения в Unity равно 9.81 , т.е. мы имеем дело с земной гравитацией.

Гравитация может быть использована в любой игре, но нам она не нужна. К счастью, гравитацию на Rigidbody можн легко отключить. Просто установите «гравитационный масштаб» равным нулю. Вот и все, корабль снова летит. Не забудьте поставить галочку в окошке «Fixed Angles», чтобы предотвратить вращение корабля, обусловленное такой физикой.

Перемещение игрока

Настало время написать скриптик (вы ведь не думали, что все будет двигаться само)? Создайте в Unity C#-скрипт в папке «Scripts» и назовите это «PlayerScript». Откройте ваш любимый редактор или используйте подменю «Sync» (нажмите на «Assets» в строке меню, затем на «Sync MonoDevelop Project») для правки созданного Unity скрипта.

«Sync MonoDevelop Project» : Это подменю немного странное.Во-первых, невозможно изменить имя, даже если сменить редактора.
Мы также рекомендуем использовать это меню при создании первого скрипта, так как Unity создаст решения и привяжет их к библиотекам Unity (для Visual Studio, Xamarin Studio или MonoDevelop).
Если вместо этого вы просто откроете скрипт, компилятор вашего IDE, скорее всего, зарегистрирует определенные ошибки, не Unity. Это не имеет значения, потому что вам не придется использовать его напрямую, но функция автоматического завершения объектов Unity не помешает.

По умолчанию в скрипте уже прописаны методы Start и Update . Вот краткий список наиболее часто используемых функций:

  • Awake() вызывается один раз, когда объект создается. По сути аналог обычной функции-конструктора.
  • Start() выполняется после Awake() . Отличается тем, что метод Start() не вызывается, если скрипт не включен (remember the checkbox on a component in the «Inspector»).
  • Update() выполняется для каждого кадра in the main game loop.
  • FixedUpdate() вызывается каждый раз через определеннок число кадров. Вы можете вызывать этот метод вместо Update() когда имеете дело с физикой («RigidBody» и др.).
  • Destroy() вызывается, когда объект уничтожается. Это ваш последний шанс, чтобы очистить или выполнить код.

У вас также есть некоторые функции для обработки столкновений:

  • OnCollisionEnter2D(CollisionInfo2D info) выполняется, когда коллайдер объекта соприкасается с другим коллайдером.
  • OnCollisionExit2D(CollisionInfo2D info) выполняется, когда коллайдер объекта не соприкасается ни с одним другим коллайдером.
  • OnTriggerEnter2D(Collider2D otherCollider) выполняется, когда коллайдер объекта соприкасается с другим коллайдером с пометкой «Trigger».
  • OnTriggerExit2D(Collider2D otherCollider) выполняется, когда коллайдер объекта перестает соприкасаться с коллайдером, помеченным как «Trigger».

Итак, с теорией покончено, пора в бой. Или нет, погодите еще немного: обратите внимание, что почти все, о чем мы говорили с вами имеет, суффикс «2D». Box Collider 2D , a Rigidbody 2D , OnCollisionEnter2D , OnTriggerEnter2D и т.д. Эти новые компоненты или методы появились с Unity 4.3. Используя их, вы работаете с физическим движком, встроенным в Unity 4.3, для 2D-игр (на основе Box2D) вместо движка для 3D-игр (PhysX). Два движка имеют аналогичные концепции и объекты, но они не работают точно так же. Если вы начинаете работать с одним (например, Box2D для 2D-игр), придерживаqntcm его. Именно поэтому мы используем все объекты или методы с суффиксом «2D».

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

Using UnityEngine; /// /// Контроллер и поведение игрока /// public ); // 4 — движение в каждом направлении movement = new Vector2(speed.x * inputX, speed.y * inputY); > vo >

Поясню цифры в комментариях к коду:

  1. Сначала определим публичную переменную, которая будет отображаться в окне «Инспектор». Это скорость, используемая для корабля.
  2. Сохраним движение для каждого кадра.
  3. Используем дефолтную ось, которую можно отредактировать в «Edit» -> «Project Settings» -> «Input» . При этом мы получим целые значения между [-1, 1] , где 0 будет означать, что корабль неподвижен, 1 — движение вправо, -1 — влево.
  4. Умножим направление на скорость.
  5. Изменим скорость rigidbody. Это даст движку команду к перемещению объекта. Сделаем это в FixedUpdate() , предназначенном для всего, что связано с физикой.

Заметка о соглашениях C# : Посмотрите на видимость speed члена класса – он обозначен как публичный. В C# переменная члена класса должна быть приватной для соответствующего сохранения его внутренней репрезентации.
Но смена типа переменной на публичный позволяет редактировать ее в Unity через панель «Inspector», даже в процессе игры. Это одна из самых мощных возможностей Unity, позволяющая изменять геймплей без использования кода.
Помните, что в данном случае мы создаем скрипты, а это не то же самое, что классическое программирование на C#. Это предполагает некоторых правил и соглашений.

Теперь добавим скрипт к игровому объекту. Для этого перетащите скрипт из окна «Проект» (Project) на игровой объект в «Иерархии» (Hierarchy). Вы также можете нажать на «Add Component» и добвить его вручную.

Нажмите кнопку «Play» в верхней части окна редактора. Корабль движется! Congratulations, Вы только что сделали эквивалент «Hello, World!» для игры:)

Попробуйте настроить скорость: нажмите на игрока, измените значения скорости в «Инспекторе», и посмотрите что из этого получится.

Будьте осторожны: изменения параметров, сделанные во время, игры теряются, когда вы ее остановите! Инспекторе — это отличный инструмент для настройки геймплея, но запомните или запишите, что вы делали, если хотите сохранить изменения. Этот же трюк подходит, если вы хотете проверить что-то новое, но не хотите вносить изменения в реальный проект.

Первый враг

Теперь добавим неприятелей, стремящихся уничтожить наш корабль. Пусть им будет зловещий спрут, названный «Poulpi»:

Создадим новый спрайт. Для этого:

  1. Скопируйте картинку в папку «Textures».
  2. Создайте новый спрайт, используя это изображение.
  3. Измените свойство «Масштаб» (Scale) в разделе Трансформирование (Transform) на (0.4, 0.4, 1) .
  4. Добавьте «Box Collider 2D» размером (4, 4) .
  5. Add a «Rigidbody 2D» with a «Gravity Scale» of 0 and «Fixed Angles» ticked.

Сохраните префаб и. вуаля!

Скрипт

Теперь напишем простенький скрипт, отвечающий за движение осьминога в определенном направлении. Для этого создайте новый скрипт, назвав его «MoveScript».

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

Скопируем некоторые части кода, который мы написали в «PlayerScript» для движения персонажа. We will add another designer (a public member you can alter in the «Inspector») variable for the direction:

Прикрепите скрипт к осьминогу. Нажмите «Play» и убедитесь, что спрут движется так, как показано на рисунке ниже:

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

Вы узнали, как добавить игрока, движущегося с помощью клавиатуры. Также, мы создали врага с зачаточным AI. Теперь мы хотим иметь возможность уничтожить его! А для этого, нам нужны боеприпасы, которые мы создадим в следующем уроке .

Введение:

1. Шаг

2. Шаг

Сначала создайте землю для нашей игры. Импортируйте largeGround из загруженного архива ( ссылка снова, если ещё не скачали. Распакуйте архив.zip после его загрузки).

Перетащите largeGround в сцену. Переименуйте созданный игровой объект как Ground . Проверьте, что Z-позиция равна нулю (измените её на , если отличается). Добавьте к нему Box Collider 2D.

3. Шаг

Теперь мы можем сделать игрока. Для этого у меня есть лист спрайтов с крысой. Импортируйте ratIdle (из скаченного архива) в окно Assets . Нам надо разделить спрайты. Выберите ratIdle и переключите Sprite Mode на Multiple . Нажмите Apply .

Нажмите на Sprite Editor и новое окно будет открыто. Нажмите Slice . Измените Type на Grid By Cell Count . Установите Column на 4 и Row на 5 . Нажмите на кнопку Slice . Нажмите на Apply . Закройте это окно.

Раскройте спрайт. В нем должно быть теперь 20 кадров. Перетащите первый кадр в сцену. Будет создан новый игрвой объект. Выделите этот объект и назовите его Rat . Посмотрите на его Inspector . Измените Tag на Player . Убедитесь, что его Z-позиция 0. Добавьте к нему Capsule Collider 2D . Измените Direction на Horizontal . Нажмите на кнопку Edit и настройте размер коллайдера (тяните за зеленые точки). Теперь добавьте Rigidbody 2D . Установите Interpolate на Interpolate . Разверните Constraints и включите Freeze Rotation Z .

4. Шаг

public float speed;

Выберите крысу в иерархии и добавьте к ней скрипт PlayerMove . Измените переменную Speed (около 3). Вы можете запустить игру и проверить сцену. Крыса должна двигаться влево и вправо (использовать левую/правую стрелку или A/D).

5. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove: MonoBehaviour <

public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;

void Start () <
//делаем ссылку на Rigidbody2D
rb = GetComponent ();
>

//переключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
>
>

void FixedUpdate () <
//изменяем переменную, зависящую от результата Physics2D.OverlapPoint

//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis («Horizontal» );
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//y: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f );
//Изменить скорость игрока на вычисленный вектор
rb.velocity = move;
>
>

Выберите Rat в иерархии, щелкните по нему правой кнопкой мыши и выберите Create Empty . Выберите этот созданный объект и переименуйте его в GroundCheck .

Выберите GroundCheck и включите иконку для лучшей видимости (смотрите скриншот). Включите moving tool и передвиньте GroundCheck под крысу, но не в сам коллайдер крысы. Убедитесь, что его Z-Position равна 0.

Выберите Ground в иерархии и смените Layer на Ground (добавьте новый Layer с этим названием, если в списке нет такого).

Выделите Rat в иерархии. В компоненте PlayerMove есть теперь новые поля. Включите Ground в whatIsGround . Поместите GroundCheck в поле GroundCheck . Измените JumpForce на 5.

Проверьте игру. Крыса должна теперь двигаться налево/направо и прыгать.

6. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove: MonoBehaviour <

//в инспекторе мы можем выбрать, какие слои будут землёй
public LayerMask whatIsGround;
//позиция для проверки касания земли
public Transform groundCheck;
//переменная, которая будет true, если крыса находится на земле
public bool isGrounded;
//значение величины силы
public float jumpForce;
//переменная для скорости движения
public float speed;
//ссылочная переменная для компонента Rigidbody2D
Rigidbody2D rb;
//переменная контроля направления крысы
public bool isLookingLeft;

void Start () <
//делаем ссылку на Rigidbody2D
rb = GetComponent ();
>

//я буду использовать Update() для более точного определения прыжка
void Update () <
//проверка, нажат-ли прыжок и находится-ли крыса на земле
if (Input .GetButtonDown («Jump» ) && isGrounded) <
//применяем силу на Rigidbody2D вдоль оси Y для прыжка
rb.AddForce (Vector2 .up * jumpForce, ForceMode2D .Impulse);
//sпереключаем переменную, чтобы предотвратить следующий прыжок, или мы могли бы снова прыгнуть (до того, как isGrounded будет переключена в FixedUpdate ())
isGrounded = false;
>
>

void FixedUpdate () <
//изменяем переменную, зависит от результата Physics2D.OverlapPoint
isGrounded = Physics2D .OverlapPoint (groundCheck.position, whatIsGround);
//декларация переменной с её инициализацией значением полученным с горизонтальной оси (значение лежит в области между -1 и 1)
float x = Input.GetAxis («Horizontal» );
//декларация локального вектора и инициализация посчитанным значением
//x: значение от InputManager * speed
//: принять текущее значение, мы не будем его менять, из-за использования силы тяжести
//z: должно быть равно нулю, нам не нужно движение по оси Z
Vector3 move = new Vector3 (x * speed, rb.velocity.y, 0f );
//изменить скорость игрока на вычисленный вектор
rb.velocity = move;

//функция поворота крысы
void TurnTheRat ()
<
//смена переменной показывающей направление взгляда на обратное значение
isLookingLeft = !isLookingLeft;
//поворот крысы через инвертацию размера по оси х
transform.localScale = new Vector3 (transform.localScale.x * -1 , transform.localScale.y, transform.localScale.z);
>

Выберите крысу. В скрипте PlayerMove появилась новая переменная для обозначения направления взгляда. Включите её, так как крыса смотрит налево.

Крыса может теперь бежать влево и вправо и менять направление взгляда. Вы можете проверить сцену.

7. Step

Теперь можем начать анимировать крысу. Выберите Rat в иерархии и добавьте Animator к ней.

Создайте Animator Controller в Assets . Назовите его RatAnimator .

Выберите Rat и добавьте RatController в поле Controller .

Нам понадобится окно Animation . Включите его в меню Window м поместите его там, где вам удобно (я поместил над Assets ).

Выберите Rat в иерархии. Создайте новую анимацию (нажмите на кнопку Create ). Назовите эту новую анимацию IdleRatAnimation .

Теперь можем добавить спрайтовый лист. Выделите Rat в иерархии. Разверните ratIdle спрайт. Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key Animation

Включите окошко Animator в меню Window .

Анимация должна быть зацикленна. Убедитесь в этом на всякий случай. Перейдите к окну Animator и сделайте двойной клик на IdleRatAnimation Проверьте Loop Time .

У крысы есть теперь анимация покоя. Запустите сцену и проверьте.

8. Шаг

Теперь создадим анимацию бега. Импортируйте спрайт ratRun в Assets . Смените Sprite Mode на Multiple . Перейдите в Sprite Editor и переключите на Grid By Cell Count и установите Column 4 , Row 5 (смотрите 3. Шаг ). Выделите Rat в иерархии. Перейдите в окно Animations и нажмите на IdleRatAnimation потом нажмите на Create New Clip . Назовите новую анимацию RunRatAnimations .

Раскройте спрайт ratRun и выделите все 20 кадров (нажмите первый кадр, держите кнопку шифт и нажмите последний кадр). Перетащите все кадры в окошко Animations . Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).

Откройте окно Animator (включите его в меню Window , если не видите его).

IdleRatAnimation стандартная анимация. Нам нужны transition (переходы) к другим анимациям и параметры контроля этих transition. Нажмите на закладку Parameters . Добавьте новый float speed параметр. Сделайте правый клик на IdleRatAnimation и сделайте transition из IdleRatAnimation в RunRatAnimation . Потом правый клик на RunRatAnimation и добавьте transition на IdleRatAnimation .

Выберите transition от IdleRatAnimation к RunRatAnimation . Отключите Has Exit Time speed greater 0.01 .

Выберите transition от RunRatAnimation к IdleRatAnimation . Отключите Has Exit Time . Добавьте новое condition (условие). Измените его на speed less 0.01 .

Анимация бега сейчас слишком медленная. Выберите RunRatAnimation в Animator и измените скорость на 2.5 (можете потом настроить по желанию).

9. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

void Update () <
//меняем параметр speed в Animator. Используем значение скорости по оси х

Добавьте этот скрипт к крысе Rat .

Запустите сцену. У крысы должна появиться анимация бега

10. Шаг

Теперь сделаем анимацию прыжка. Выберите Rat в иерархии. Добавьте новую анимацию (в окошке Animation ) и назовите её JumpRatAnimation .

Я не сделал анимацию прыжка, просто используем замедленную анимацию бега. Выделите Rat в иерархии. Проверьте в окошке Animation , что JumpRatAnimation выбранна. Разверните спрайт ratRun . Надо выделить все кадры. Выберите первый кадр, зажмитеShift-Key и выделите последний кадр. Все 20 кадров должны выбраться. Перетащите все кадры в окошко Animation . Установите samples на 20. Сделайте двойной клик на первом кадре, чтобы сделать правильную длину анимации (возможно баг моей версии).

11. Шаг

Переключитесь на Animator . Нам нужно условие для анимации прыжка. Добавьте новую Bool и назовите её isJumping . Сделайте теперь transition (переход) (правый клик) из Any State к JumpRatAnimation . Добавьте transition от JumpRatAnimation к IdleRatAnimation .

Выделите transition от Any State к JumpRatAnimation . Отключите Has Exit Time . Разверните Settings и отключите Can Transition To (чтобы избежать перезапуска анимации, пока isJumping true). Добавьте condition (условие) isJumping true .

Выберите transition от JumpRatAnimation к IdleRatAnimation . Отключите Has Exit Time . Добавьте condition isJumping false .

Выделите JumpRatAnimation и измените Speed на 0.5. Замедленная анимация бега должна заменить анимацию прыжка.

12. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAnim: MonoBehaviour <

//ссылочная переменная для аниматора
Animator anim;
//ссылочная переменная для rigidbody2D
Rigidbody2D rb;
//ссылочная переменная для PlayerMove
PlayerMove pm;

void Update () <
//проверка, находится ли крыса на земле
if (pm.isGrounded) <
//меняем параметр isJumping на false
anim.SetBool («isJumping» , false );
//меняем параметр speed. Используем абсолютное значение вектора скорости по х
anim.SetFloat («speed» , Mathf .Abs (rb.velocity.x));
// если крыса не на земле
> else <
//меняем параметр speed на 0
anim.SetFloat («speed» , 0 );
//меняем параметр isJumping на true
anim.SetBool («isJumping» , true );
>
>

Можете проверить сцену.

13. Step

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//ссылочная переменная для звукового файла
public AudioClip footsteps;

Выберите Rat в иерархии и добавьте этот скрипт к крысе. Импортируйте аудио-файл ratStep . И добавьте ratStep в Footsteps поле компонента PlayerSound .

Выделите Rat в иерархии и перейдите в Animation . Смените анимацию на RunRatAnimation . Выберите кадр, когда хотите воспроизвести звук (кликните на полоску времени). Нажмите на Add Event (смотрите скриншот). Выберите добавленный Animations Event и установите Function на FootStepsAudio() .

14. Шаг

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerSound: MonoBehaviour <

//ссылочная переменная для аудио-файла
public AudioClip footsteps;

//публичная функция, получим доступ к ней из аниматора
public void FootStepsAudio () <
//воспроизвести заданный звук на позиции крысы
AudioSource .PlayClipAtPoint (footsteps, transform.position);
>

//запустится если было касание другого Collider2D
void OnCollisionEnter2D (Collision2D coll) <
//проверка тэга на тэг «Ground»
if (coll.gameObject.tag == «Ground» ) <
//воспроизвести заданный звук на позиции крысы
AudioSource .PlayClipAtPoint (footsteps, transform.position);
>
>

Выберите Ground в иерархии. Добавьте новый тэг Ground и измените тэг объекта Ground на тэг Ground .

15. Шаг

Выберите Ground в иерархии. Создайте prefab Ground (перетащите объект в Assets ). Поместите prefab Ground в сцену, как следующую платформу.

Выберите Main Camera и сделайте её дочерним объектом Rat (перетащите Main Camera на Rat ). Камера будет следовать за крысой.

Можете изменить X-position камеры на 0, чтобы убрать рывки при повороте.
Я думаю, этого достаточно для первой части. Надеюсь, что вторая часть будет готова в мае-июне (у меня сейчас мало времени).

Скачать готовый проект

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

Вот список всех статей:

Где мы остановились?

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

Превью результата

Движение платформы

Сама платформа у нас уже есть — мы ее создали еще в прошлом уроке. Осталось научить ее двигаться, причем исключительно влево или вправо, т.е. по оси X. Для этого нам потребуется написать сценарий (Script ).

Сценарии представляют собой фрагменты программного кода, которые ответственны за какую-то конкретную задачу. Unity может работать со скриптами, написанными на трех языках программирования: Boo, JavaScript и C#. Мы будем использовать последний, но вы можете попробовать свои силы и с другими языками.

Итак, для создания скрипта перейдем на вкладку Project , найдем там одноименную папку Scripts и кликнем на нее правой кнопкой мыши. Выберем Create -> C# Script . Появится новый файл с названием NewBehaviourScript . Переименуйте его в PlayerScript для удобства. На вкладке Inspector вы можете видеть содержимое скрипта.

Двойным кликом откройте скрипт. Запуститься среда разработки MonoDevelop, которую вы впоследствии можете изменить на любой удобный для вас редактор. Вот то, что вы увидите:

Using UnityEngine; using System.Collections; public class NewBehaviourScript: MonoBehaviour < // используйте этот метод для инициализации void Start () < >// Update вызывается при отрисовке каждого кадра игры void Update () < >>

Все сценарии на Unity имеют по умолчанию два метода:

  • Start() : используется для инициализации переменных или параметров, необходимых нам в коде.
  • Update() : вызывается каждый кадр игры, необходим для обновления состояния игры.

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

Таким образом, необходимо создать две переменные для сохранения этой информации:

public float playerVelocity;
private Vector3 playerPosition;


Обратите внимание, что одна переменная объявлена публично, а вторая — приватно. Для чего это делается? Дело в том, что Unity позволяет редактировать значения публичных переменных не переходя в редактор MonoDevelop, без необходимости изменения кода. Эта возможность очень полезна в тех случаях. когда необходимо «на лету» корректировать какое-то значение. Скорость платформы — одно из таких значений, и именно поэтому мы объявили его публично.

Сохраните сценарий в редакторе MonoDevelop и перейдите в редактор Unity. Теперь у нас есть сценарий и нам нужно присвоить его какому то объекту, в нашем случае — платформе. Выберите нашу платформу во вкладке Hierarchy и в окне Inspector добавьте компонент, кликнув на кнопку Add Component .

Добавление нашего скрипта в компонент можно сделать и по-другому. Перетащите наш сценарий в область кнопки Add Component . Во вкладке Inspector вы должны увидеть что-то подобное:

Обратите внимание, что в компоненте скрипта появилось поле Player Velocity , которое можно тут же изменить. Это получилось возможным благодаря публичному объявлению переменной. Установите параметр в значение 0.3 и перейдите в редактор MonoDevelop.

Теперь нам надо узнать позицию платформы: playerPosition . Для того, чтобы инициализировать переменную, следует обратиться к объекту сценария в методе Start() :

// используйте этот метод для инициализации vo >

Отлично, мы определили начальную позицию платформы, и теперь можно ее двигать. Так как нам надо, чтобы платформа перемещалась только по оси X, то мы сможем использовать метод GetAxis класса Input . Этой функции мы передадим строку Horizontal , и она вернет нам 1, если была нажата клавиша «вправо», и -1 — «влево». Умножив полученное число на скорость и прибавив эту величину к текущей позиции игрока, мы и получим движение.

Также добавим проверку на выход из приложения по нажатию на клавишу Esc .

Вот то, что у нас должно получиться в итоге:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; > >

Сохраните скрипт и вернитесь в редактор Unity. Нажмите кнопку Play и попробуйте передвинуть платформу при помощи кнопок «влево» и «вправо».

Определение игровой области

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

Давайте добавим в наш существующий скрипт еще одну публичную переменную и назовем его boundary .

Эта переменная будет хранить максимальную координату платформы по оси X. Так как мы собираемся строить уровни в симметричной форме вокруг точки с координатами (0, 0, 0), то абсолютное значение переменной boundary будет одинаковым и для положительной части оси X, и для отрицательной.

А теперь добавим пару условий. Поступим достаточно просто: если вычисленная нами позиция будет больше boundary или меньше -boundary , то мы просто зададим новую позицию по оси X, равную значению переменной boundary . Таким образом, мы гарантируем, что платформа не уедет за пределы наших границ и никогда не покинет игровую зону. Вот код:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; // проверка выхода за границы if (playerPosition.x boundary) < transform.position = new Vector3(boundary, playerPosition.y, playerPosition.z); >> >

Теперь вернитесь в редактор и, переключаясь в игру, найдите оптимальное значение переменной boundary . В нашем случае подошло число 5.46. Откройте Inspector и сбросьте позицию платформы по оси X на 0, а параметр Boundary выставьте согласно найденному вами значению.

Нажмите кнопку Play и убедитесь в том, что вы все сделали правильно. Платформа должна двигаться только в пределах игрового поля.

Включение физики

Чтобы столкновения были более реалистичные — воспользуемся симуляцией физики. В этой статье мы добавим физические свойства мячику, платформе и границам поля. Так как мы пишем 2D игру, то будем использовать 2D коллайдеры. Коллайдер — это отдельный тип компонентов, который позволяет объекту реагировать на коллайдеры других объектов.

В окне Hierarchy выберем нашу платформу, перейдем в Inspector и нажмем на кнопку Add Component . В появившемся окошке наберем collider . Как вы можете увидеть — вариантов достаточно много. Каждый коллайдер имеет специфические свойства, соответствующие связанным объектам — прямоугольникам, кругам и т.д.

Так как наша платформа имеет прямоугольную форму, мы будем использовать Box Collider 2D . Выберите именно его, и компонент автоматически определит размеры платформы: вам не нужно будет задавать их вручную, Unity сделает это за вас.

Сделайте то же самое и для 3 границ (Hierarchy -> Inspector -> Add Component -> Box Collider 2D ).

С мячиком чуть-чуть по другому: он имеет круглую форму. Выберем мяч и добавим для нее компонент Circle Collider 2D .

На самом деле коллайдер окружности и прямоугольника очень похожи, за исключением того, что вместо параметра Size , определяющим ширину и длину, в окружности используется Radius . Объяснения здесь, думаем, излишни.

Упругое столкновение

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

Откройте окно Project и внутри папки Asset создайте новую папку под названием Physics . Кликните по только что созданной папке правой кнопкой мыши и выберите Create -> Physics2D Material . Задайте название BallPhysicsMaterial .

Каждая поверхность в Unity имеет два параметра: трение (friction) и упругость (bounciness) . Более подробно вы можете прочитать про физический движок и ряд физических параметров . Если вам требуется абсолютно упругое тело, то следует выставить трение на 0, а упругость на 1.

Сейчас у нас есть готовый материал, но он пока никак не связан с мячом. Выберите объект мяча во вкладке Hierarchy и в окне Inspector вы увидите поле Material компонента Circle Collider 2D . Перетащите сюда недавно созданный материал.

Добавление компонента Rigid Body

Для того, чтобы наш мячик двигался под контролем физики, мы должны добавить ему еще один компонент: Rigid Body 2D . Выберите объект мяча в окне Hierarchy и добавьте вышеупомянутый компонент — хоть он и имеет несколько параметров, нас интересует только один: Gravity Scale . Так как наш шарик будет двигаться только за счет отскоков, то мы зададим этому параметру 0 — таким образом мы гарантируем, что гравитация не будет реагировать на объект. Все остальное можно не менять.

Поведения шарика

Давайте создадим для шарика отдельный скрипт (снова воспользуемся C# в качестве языка программирования) и назовем его BallScript . Свяжите созданный скрипт с объект (Hierarchy -> Inspector -> Add Component ).

Перед тем, как начать писать скрипт, давайте определим поведение шарика:

  1. Шар имеет два состояния: неактивное (когда он в начале игры находится на платформе) и активное (когда находится в движении).
  2. Шар будет становиться активным только один раз.
  3. Когда шар становится активным, мы применяем к нему силу для того, что он начал движение.
  4. Если шар вышел за пределы игрового поля, он переводится в неактивное состояние и помещается на платформу.

Основываясь на этой информации, давайте создадим глобальные переменные ballIsActive , ballPosition и ballInitialForce:

private bool ballIsActive;
private Vector3 ballPosition;
private Vector2 ballInitialForce;

Теперь, когда у нас есть набор переменных, мы должны подготовить объект. В методе Start() мы должны:

  • создать силу, которая будет применена к шару;
  • перевести шар в неактивное состояние;
  • запомнить позицию шара.

Вот, как это можно сделать:

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

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

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

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

В методе Update мы должны проверять состояние шарика, и в случае если оно неактивное, нам надо задать позицию мячика по оси X таким же, какое оно у платформы.

Решение достаточно простое, но как нам получить координату совсем другого объекта? Элементарно — мы создадим переменную типа GameObject и сохраним ссылку на объект платформы:

public GameObject playerObject;

Вернемся к методу Update() :

Сохраните скрипт и вернитесь в редактор Unity. Вы наверняка заметили, что переменная playerObject объявлена, используется, но нигде не инициализирована. Да, так и есть. Чтобы ее проинициализировать, перейдите во вкладку Hierarchy , найдите шар и в окне Inspector найдите компонент Ball Script . У данного компонента есть параметр Player Object , в настоящее время пустующий:

Найдите во вкладке Hierarchy нашу платформу и перетащите ее на поле Player Object . Запустите игру, нажав кнопку Play , и убедитесь, что все работает.

Сброс игры

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

Это состояние отловить очень просто: шар будет активен, а его положение по оси Y отрицательно. Если это так, то мы переводим шар в неактивное состояние и ставим его на платформу:

If (ballIsActive && transform.position.y

А вот теперь точно все. Запустите игру и проверьте, все ли работает как положено.

В следующей части

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

Движение 2d персонажа в unity3d. Пишем арканоид на Unity

В второй главе о разработке игры на Unity мы добавим игрока и его врагов в сцену

Создание игрока в Unity

Создание объекта, контролируемого игроком, требует наличия определенных элементов: спрайт, способ управления им и способ его взаимодействия с игровым миром. Рассмотрим этот процесс шаг за шагом и начнем, пожалуй, со спрайта. Вот изображение, которое мы будем использовать:

  1. Скорируйте картинку в папку «Textures»
  2. Создайте новый спрайт и назовите его «Player»
  3. Настройте спрайт так, чтобы он отображался в свойстве «Sprite» компонента «Sprite Renderer»

Если у вас возникли проблемы, обратитесь к предыдущему уроку. Мы проделали точно такие же действия для фона и «реквизита».

  1. Поместите игрока в слой «2 — Foreground»
  2. Измените масштаб на (0.2, 0.2, 1)

Теперь несколько слов о компонентах. Мы только что говорили о компоненте «Sprite Renderer». Если вы еще не заметил, объект игры состоит из нескольких компонентов, видимых в панели «Инспектор».

По умолчанию пустой объект игры выглядит так:

Этот объект имеет только один компонент: Transform . Этот компонент является обязательным и не может быть отключен или удален. Вы можете добавить к объекту столько компонентов, сколько захотите. Например, скрипты добавляются в качестве компонента. Большинство компонентов может быть включено или отключено пока существует объект.

(Вы можете нажать на галочку чекбокса, чтобы отключить его. Вы можете щелкнуть правой кнопкой мыши на компоненте, чтобы вернуть прежнее свойство, удалить его и т.д.

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

Sprite Renderer является компонентом, который способен отображать спрайт-текстуру. Теперь, когда мы узнали о концепции компонента, давайте добавим один к игроку!

Добавляем бокс-коллайдер (Box Collider)

Нажмите на кнопку «Добавить компонент» объекта игрока. Выберите «Box Collider 2D». Вы можете увидеть коллайдер в редакторе «Сцена» зрения и настройки его размера в «Инспекторе» в поле «Размер» (Size).

Существует еще один способ редактирования бокс-коллайдера. Выберите игровой объект с помощью бокс-коллайдера и зажмите клавишу shift на клавиатуре. Вы увидите, что на бокс-коллайдере (зеленый прямоугольник ) появились четыре маленьких рычажка. Перетащите один из них, чтобы изменить форму бокс-коллайдера. Будьте осторожны, синий прямоугольник представляет собой компонент Transform вашего игрового объекта, а не коллайдер.

Мы будем устанавливать размер коллайдера равным (10, 10) .

Это слишком много для настоящего шмапа, но все же меньше, чем спрайт:

В настоящее время, этого вполне достаточно.

Совет : Если вы планируете создать шмап , вам придется уделить много времени настройке хитбоксов – они должны точно соответствовать маленькому элементу внутри игрового спрайта. Вы также можете изменить такой параметр коллайдера, как shape – например, с помощью «Circle Collider 2D». Благодаря Unity, его поведение при этом не меняется, но это позволяет немного улучить геймплей.

Сохраним объект игрок как префаб. Теперь у вас есть базовую сущность игрока!

2D полигональный коллайдер

Если вы хотите супер точный и произвольный формы хитбокс, воспользуйтесь компонентом Unity «Полигоннальный коллайдер 2D» (Polygon Collider 2D). Эффект от этого будет незначительный, но зато вы получите такую форму, какую вы хотите.

«Polygon Collider 2D» похож на остальные коллайдеры: вы можете изменять форму с помощью мышки в режиме «Scene». Для удаления точки зажмите cmd или ctrl , а чтобы отрегулировать положение точки или добавить ее в форму коллайдера, используйте shift

Магия Rigidbody

Последний компонент, необходимый для добавления на нашего игрока: «Rigidbody 2D». Это поможет физическому движку правильно задействовать объект в игровом пространстве. Более того, это позволит вам использовать столкновения в скрипте.

  1. Выберите объект Player в «Hierarchy».
  2. Добавьте компонент «Rigidbody 2D».

Теперь, нажмите кнопку «играть» и смотрите, что у нас вышло:

Корабль падает! И как падает! Передвайте привет нашей любимой силе тяжести. По мере того, как сменяются кадры с заранее заданной гравитацией и rigidbodies прибавляет объекту массы, корабль притягивается к нижней части экрана.

По-умолчанию, ускорние свободного падения в Unity равно 9.81 , т.е. мы имеем дело с земной гравитацией.

Гравитация может быть использована в любой игре, но нам она не нужна. К счастью, гравитацию на Rigidbody можн легко отключить. Просто установите «гравитационный масштаб» равным нулю. Вот и все, корабль снова летит. Не забудьте поставить галочку в окошке «Fixed Angles», чтобы предотвратить вращение корабля, обусловленное такой физикой.

Перемещение игрока

Настало время написать скриптик (вы ведь не думали, что все будет двигаться само)? Создайте в Unity C#-скрипт в папке «Scripts» и назовите это «PlayerScript». Откройте ваш любимый редактор или используйте подменю «Sync» (нажмите на «Assets» в строке меню, затем на «Sync MonoDevelop Project») для правки созданного Unity скрипта.

«Sync MonoDevelop Project» : Это подменю немного странное.Во-первых, невозможно изменить имя, даже если сменить редактора.
Мы также рекомендуем использовать это меню при создании первого скрипта, так как Unity создаст решения и привяжет их к библиотекам Unity (для Visual Studio, Xamarin Studio или MonoDevelop).
Если вместо этого вы просто откроете скрипт, компилятор вашего IDE, скорее всего, зарегистрирует определенные ошибки, не Unity. Это не имеет значения, потому что вам не придется использовать его напрямую, но функция автоматического завершения объектов Unity не помешает.

По умолчанию в скрипте уже прописаны методы Start и Update . Вот краткий список наиболее часто используемых функций:

  • Awake() вызывается один раз, когда объект создается. По сути аналог обычной функции-конструктора.
  • Start() выполняется после Awake() . Отличается тем, что метод Start() не вызывается, если скрипт не включен (remember the checkbox on a component in the «Inspector»).
  • Update() выполняется для каждого кадра in the main game loop.
  • FixedUpdate() вызывается каждый раз через определеннок число кадров. Вы можете вызывать этот метод вместо Update() когда имеете дело с физикой («RigidBody» и др.).
  • Destroy() вызывается, когда объект уничтожается. Это ваш последний шанс, чтобы очистить или выполнить код.

У вас также есть некоторые функции для обработки столкновений:

  • OnCollisionEnter2D(CollisionInfo2D info) выполняется, когда коллайдер объекта соприкасается с другим коллайдером.
  • OnCollisionExit2D(CollisionInfo2D info) выполняется, когда коллайдер объекта не соприкасается ни с одним другим коллайдером.
  • OnTriggerEnter2D(Collider2D otherCollider) выполняется, когда коллайдер объекта соприкасается с другим коллайдером с пометкой «Trigger».
  • OnTriggerExit2D(Collider2D otherCollider) выполняется, когда коллайдер объекта перестает соприкасаться с коллайдером, помеченным как «Trigger».

Итак, с теорией покончено, пора в бой. Или нет, погодите еще немного: обратите внимание, что почти все, о чем мы говорили с вами имеет, суффикс «2D». Box Collider 2D , a Rigidbody 2D , OnCollisionEnter2D , OnTriggerEnter2D и т.д. Эти новые компоненты или методы появились с Unity 4.3. Используя их, вы работаете с физическим движком, встроенным в Unity 4.3, для 2D-игр (на основе Box2D) вместо движка для 3D-игр (PhysX). Два движка имеют аналогичные концепции и объекты, но они не работают точно так же. Если вы начинаете работать с одним (например, Box2D для 2D-игр), придерживаqntcm его. Именно поэтому мы используем все объекты или методы с суффиксом «2D».

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

Using UnityEngine; /// /// Контроллер и поведение игрока /// public ); // 4 — движение в каждом направлении movement = new Vector2(speed.x * inputX, speed.y * inputY); > vo >

Поясню цифры в комментариях к коду:

  1. Сначала определим публичную переменную, которая будет отображаться в окне «Инспектор». Это скорость, используемая для корабля.
  2. Сохраним движение для каждого кадра.
  3. Используем дефолтную ось, которую можно отредактировать в «Edit» -> «Project Settings» -> «Input» . При этом мы получим целые значения между [-1, 1] , где 0 будет означать, что корабль неподвижен, 1 — движение вправо, -1 — влево.
  4. Умножим направление на скорость.
  5. Изменим скорость rigidbody. Это даст движку команду к перемещению объекта. Сделаем это в FixedUpdate() , предназначенном для всего, что связано с физикой.

Заметка о соглашениях C# : Посмотрите на видимость speed члена класса – он обозначен как публичный. В C# переменная члена класса должна быть приватной для соответствующего сохранения его внутренней репрезентации.
Но смена типа переменной на публичный позволяет редактировать ее в Unity через панель «Inspector», даже в процессе игры. Это одна из самых мощных возможностей Unity, позволяющая изменять геймплей без использования кода.
Помните, что в данном случае мы создаем скрипты, а это не то же самое, что классическое программирование на C#. Это предполагает некоторых правил и соглашений.

Теперь добавим скрипт к игровому объекту. Для этого перетащите скрипт из окна «Проект» (Project) на игровой объект в «Иерархии» (Hierarchy). Вы также можете нажать на «Add Component» и добвить его вручную.

Нажмите кнопку «Play» в верхней части окна редактора. Корабль движется! Congratulations, Вы только что сделали эквивалент «Hello, World!» для игры:)

Попробуйте настроить скорость: нажмите на игрока, измените значения скорости в «Инспекторе», и посмотрите что из этого получится.

Будьте осторожны: изменения параметров, сделанные во время, игры теряются, когда вы ее остановите! Инспекторе — это отличный инструмент для настройки геймплея, но запомните или запишите, что вы делали, если хотите сохранить изменения. Этот же трюк подходит, если вы хотете проверить что-то новое, но не хотите вносить изменения в реальный проект.

Первый враг

Теперь добавим неприятелей, стремящихся уничтожить наш корабль. Пусть им будет зловещий спрут, названный «Poulpi»:

Создадим новый спрайт. Для этого:

  1. Скопируйте картинку в папку «Textures».
  2. Создайте новый спрайт, используя это изображение.
  3. Измените свойство «Масштаб» (Scale) в разделе Трансформирование (Transform) на (0.4, 0.4, 1) .
  4. Добавьте «Box Collider 2D» размером (4, 4) .
  5. Add a «Rigidbody 2D» with a «Gravity Scale» of 0 and «Fixed Angles» ticked.

Сохраните префаб и. вуаля!

Скрипт

Теперь напишем простенький скрипт, отвечающий за движение осьминога в определенном направлении. Для этого создайте новый скрипт, назвав его «MoveScript».

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

Скопируем некоторые части кода, который мы написали в «PlayerScript» для движения персонажа. We will add another designer (a public member you can alter in the «Inspector») variable for the direction:

Прикрепите скрипт к осьминогу. Нажмите «Play» и убедитесь, что спрут движется так, как показано на рисунке ниже:

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

Вы узнали, как добавить игрока, движущегося с помощью клавиатуры. Также, мы создали врага с зачаточным AI. Теперь мы хотим иметь возможность уничтожить его! А для этого, нам нужны боеприпасы, которые мы создадим в следующем уроке .

Итак. Всем привет. И сегодня я расскажу, как сделать простое движение персонажа. Сейчас только от третьего лица. Приступим.
Начнём, пожалуй, с создания персоажа. У меня это будет куб. Кто не знает, как создавать кубы или круги, поясняю — «GameObject» => «CreateOther» => «Cube». Создаём таким же образом камеру и привязываем к кубу (то бишь просто в иерархии перетаскиваем камеру на куб).
Так. Теперь создадим поверхность, по которой персонаж будет ходить. Пусть это будет просто «Plane». Ах, да. В конце урока будет ссылка с исходником по туториалу для тех, кто не понял.
Итак. Теперь создадим скрипт «Move». Добавим переменную игрока и переменную скорости.

Public GameObject player;
public int speed = 5;

Теперь укажем в методе старта, что это объект, на котором висит скрипт.

Void Start () <
player = (GameObject)this.gameObject;
>

Теперь сделаем само передвижение игрока вперёд при нажатии на «W» или стрелку вверх. Это делаем в методе void Update()! Для этого мы будем прибавлять позицию. Например вперёд.

If (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
>

Мы прибавили позицию вперёд (forward) и умножили на скорость, а точнее её переменную. И обязательно надо умножить на кадры в секунду (deltaTime).
Таким же образом сделаем движение назад. Только будем отнимать позицию.

If (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>

Таким же образом можем сделать и вправо и влево (right, left), но я сделаю просто поворот игрока, при нажатии на «A» или «D».
Я буду использовать «Rotate()». Чтобы поворачивать по оси «Y», я буду использовать «up» и «down». Кстати, для этого ещё надо объявить переменную «public int speedRotation = 3». И пишем в условиях.

If (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>

Ну. Сейчас пришло время анимировать. Я записываю анимацию в самой юнити. Это можно открыть в «Window» => «Animation». В этом окне мы можем анимировать куб. Итак. Пропустим момент создания анимации. Давайте теперь создадим переменную анимации.

Public AnimationClip anima;

Теперь в старте добавим клип.

Теперь мы будем его воспроизводить через «CrossFade». Воспроизводить буду в условиях ходьбы вперёд и назад. Чтобы воспроизвести, нужно написать.

Итак. У нас получился хороший код. Сейчас мы сделаем прыжок. Всё так же просто. Опять мы будем прибавлять позицию. Только вверх (up).
И так же с новой переменной анимации «public AnimationClip anima2;»? так же добавим и переменной «public int jumpSpeed = 50;». И мы получаем условие.

If (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

Всё. Наш код готов.

using UnityEngine;
using System.Collections;
public class Move: MonoBehaviour <
public GameObject player;
public int speedRotation = 3;
public int speed = 5;
public AnimationClip anima;
public int jumpSpeed = 50;

Vo courier new font-size: text-align: justify> player = (GameObject)this.gameObject;
animation.AddClip(anima, «animCube»);
>
void Update() <
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
<
player.transform.position += player.transform.forward * speed * Time.deltaTime;
animation.CrossFade(«animCube»);
>
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
<
player.transform.position -= player.transform.forward * speed * Time.deltaTime;
>
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
<
player.transform.Rotate(Vector3.down * speedRotation);
>
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
<
player.transform.Rotate(Vector3.up * speedRotation);
>
if (Input.GetKeyDown(KeyCode.Space))
<
player.transform.position += player.transform.up * jumpSpeed * Time.deltaTime;
>

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

Вот список всех статей:

Где мы остановились?

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

Превью результата

Движение платформы

Сама платформа у нас уже есть — мы ее создали еще в прошлом уроке. Осталось научить ее двигаться, причем исключительно влево или вправо, т.е. по оси X. Для этого нам потребуется написать сценарий (Script ).

Сценарии представляют собой фрагменты программного кода, которые ответственны за какую-то конкретную задачу. Unity может работать со скриптами, написанными на трех языках программирования: Boo, JavaScript и C#. Мы будем использовать последний, но вы можете попробовать свои силы и с другими языками.

Итак, для создания скрипта перейдем на вкладку Project , найдем там одноименную папку Scripts и кликнем на нее правой кнопкой мыши. Выберем Create -> C# Script . Появится новый файл с названием NewBehaviourScript . Переименуйте его в PlayerScript для удобства. На вкладке Inspector вы можете видеть содержимое скрипта.

Двойным кликом откройте скрипт. Запуститься среда разработки MonoDevelop, которую вы впоследствии можете изменить на любой удобный для вас редактор. Вот то, что вы увидите:

Using UnityEngine; using System.Collections; public class NewBehaviourScript: MonoBehaviour < // используйте этот метод для инициализации void Start () < >// Update вызывается при отрисовке каждого кадра игры void Update () < >>

Все сценарии на Unity имеют по умолчанию два метода:

  • Start() : используется для инициализации переменных или параметров, необходимых нам в коде.
  • Update() : вызывается каждый кадр игры, необходим для обновления состояния игры.

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

Таким образом, необходимо создать две переменные для сохранения этой информации:

public float playerVelocity;
private Vector3 playerPosition;

Обратите внимание, что одна переменная объявлена публично, а вторая — приватно. Для чего это делается? Дело в том, что Unity позволяет редактировать значения публичных переменных не переходя в редактор MonoDevelop, без необходимости изменения кода. Эта возможность очень полезна в тех случаях. когда необходимо «на лету» корректировать какое-то значение. Скорость платформы — одно из таких значений, и именно поэтому мы объявили его публично.

Сохраните сценарий в редакторе MonoDevelop и перейдите в редактор Unity. Теперь у нас есть сценарий и нам нужно присвоить его какому то объекту, в нашем случае — платформе. Выберите нашу платформу во вкладке Hierarchy и в окне Inspector добавьте компонент, кликнув на кнопку Add Component .

Добавление нашего скрипта в компонент можно сделать и по-другому. Перетащите наш сценарий в область кнопки Add Component . Во вкладке Inspector вы должны увидеть что-то подобное:

Обратите внимание, что в компоненте скрипта появилось поле Player Velocity , которое можно тут же изменить. Это получилось возможным благодаря публичному объявлению переменной. Установите параметр в значение 0.3 и перейдите в редактор MonoDevelop.

Теперь нам надо узнать позицию платформы: playerPosition . Для того, чтобы инициализировать переменную, следует обратиться к объекту сценария в методе Start() :

// используйте этот метод для инициализации vo >

Отлично, мы определили начальную позицию платформы, и теперь можно ее двигать. Так как нам надо, чтобы платформа перемещалась только по оси X, то мы сможем использовать метод GetAxis класса Input . Этой функции мы передадим строку Horizontal , и она вернет нам 1, если была нажата клавиша «вправо», и -1 — «влево». Умножив полученное число на скорость и прибавив эту величину к текущей позиции игрока, мы и получим движение.

Также добавим проверку на выход из приложения по нажатию на клавишу Esc .

Вот то, что у нас должно получиться в итоге:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; > >

Сохраните скрипт и вернитесь в редактор Unity. Нажмите кнопку Play и попробуйте передвинуть платформу при помощи кнопок «влево» и «вправо».

Определение игровой области

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

Давайте добавим в наш существующий скрипт еще одну публичную переменную и назовем его boundary .

Эта переменная будет хранить максимальную координату платформы по оси X. Так как мы собираемся строить уровни в симметричной форме вокруг точки с координатами (0, 0, 0), то абсолютное значение переменной boundary будет одинаковым и для положительной части оси X, и для отрицательной.

А теперь добавим пару условий. Поступим достаточно просто: если вычисленная нами позиция будет больше boundary или меньше -boundary , то мы просто зададим новую позицию по оси X, равную значению переменной boundary . Таким образом, мы гарантируем, что платформа не уедет за пределы наших границ и никогда не покинет игровую зону. Вот код:

Using UnityEngine; using System.Collections; public ) * playerVelocity; // выход из игры if (Input.GetKeyDown(KeyCode.Escape)) < Application.Quit(); >// обновим позицию платформы transform.position = playerPosition; // проверка выхода за границы if (playerPosition.x boundary) < transform.position = new Vector3(boundary, playerPosition.y, playerPosition.z); >> >

Теперь вернитесь в редактор и, переключаясь в игру, найдите оптимальное значение переменной boundary . В нашем случае подошло число 5.46. Откройте Inspector и сбросьте позицию платформы по оси X на 0, а параметр Boundary выставьте согласно найденному вами значению.

Нажмите кнопку Play и убедитесь в том, что вы все сделали правильно. Платформа должна двигаться только в пределах игрового поля.

Включение физики

Чтобы столкновения были более реалистичные — воспользуемся симуляцией физики. В этой статье мы добавим физические свойства мячику, платформе и границам поля. Так как мы пишем 2D игру, то будем использовать 2D коллайдеры. Коллайдер — это отдельный тип компонентов, который позволяет объекту реагировать на коллайдеры других объектов.

В окне Hierarchy выберем нашу платформу, перейдем в Inspector и нажмем на кнопку Add Component . В появившемся окошке наберем collider . Как вы можете увидеть — вариантов достаточно много. Каждый коллайдер имеет специфические свойства, соответствующие связанным объектам — прямоугольникам, кругам и т.д.

Так как наша платформа имеет прямоугольную форму, мы будем использовать Box Collider 2D . Выберите именно его, и компонент автоматически определит размеры платформы: вам не нужно будет задавать их вручную, Unity сделает это за вас.

Сделайте то же самое и для 3 границ (Hierarchy -> Inspector -> Add Component -> Box Collider 2D ).

С мячиком чуть-чуть по другому: он имеет круглую форму. Выберем мяч и добавим для нее компонент Circle Collider 2D .

На самом деле коллайдер окружности и прямоугольника очень похожи, за исключением того, что вместо параметра Size , определяющим ширину и длину, в окружности используется Radius . Объяснения здесь, думаем, излишни.

Упругое столкновение

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

Откройте окно Project и внутри папки Asset создайте новую папку под названием Physics . Кликните по только что созданной папке правой кнопкой мыши и выберите Create -> Physics2D Material . Задайте название BallPhysicsMaterial .

Каждая поверхность в Unity имеет два параметра: трение (friction) и упругость (bounciness) . Более подробно вы можете прочитать про физический движок и ряд физических параметров . Если вам требуется абсолютно упругое тело, то следует выставить трение на 0, а упругость на 1.

Сейчас у нас есть готовый материал, но он пока никак не связан с мячом. Выберите объект мяча во вкладке Hierarchy и в окне Inspector вы увидите поле Material компонента Circle Collider 2D . Перетащите сюда недавно созданный материал.

Добавление компонента Rigid Body

Для того, чтобы наш мячик двигался под контролем физики, мы должны добавить ему еще один компонент: Rigid Body 2D . Выберите объект мяча в окне Hierarchy и добавьте вышеупомянутый компонент — хоть он и имеет несколько параметров, нас интересует только один: Gravity Scale . Так как наш шарик будет двигаться только за счет отскоков, то мы зададим этому параметру 0 — таким образом мы гарантируем, что гравитация не будет реагировать на объект. Все остальное можно не менять.

Поведения шарика

Давайте создадим для шарика отдельный скрипт (снова воспользуемся C# в качестве языка программирования) и назовем его BallScript . Свяжите созданный скрипт с объект (Hierarchy -> Inspector -> Add Component ).

Перед тем, как начать писать скрипт, давайте определим поведение шарика:

  1. Шар имеет два состояния: неактивное (когда он в начале игры находится на платформе) и активное (когда находится в движении).
  2. Шар будет становиться активным только один раз.
  3. Когда шар становится активным, мы применяем к нему силу для того, что он начал движение.
  4. Если шар вышел за пределы игрового поля, он переводится в неактивное состояние и помещается на платформу.

Основываясь на этой информации, давайте создадим глобальные переменные ballIsActive , ballPosition и ballInitialForce:

private bool ballIsActive;
private Vector3 ballPosition;
private Vector2 ballInitialForce;

Теперь, когда у нас есть набор переменных, мы должны подготовить объект. В методе Start() мы должны:

  • создать силу, которая будет применена к шару;
  • перевести шар в неактивное состояние;
  • запомнить позицию шара.

Вот, как это можно сделать:

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

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

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

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

В методе Update мы должны проверять состояние шарика, и в случае если оно неактивное, нам надо задать позицию мячика по оси X таким же, какое оно у платформы.

Решение достаточно простое, но как нам получить координату совсем другого объекта? Элементарно — мы создадим переменную типа GameObject и сохраним ссылку на объект платформы:

public GameObject playerObject;

Вернемся к методу Update() :

Сохраните скрипт и вернитесь в редактор Unity. Вы наверняка заметили, что переменная playerObject объявлена, используется, но нигде не инициализирована. Да, так и есть. Чтобы ее проинициализировать, перейдите во вкладку Hierarchy , найдите шар и в окне Inspector найдите компонент Ball Script . У данного компонента есть параметр Player Object , в настоящее время пустующий:

Найдите во вкладке Hierarchy нашу платформу и перетащите ее на поле Player Object . Запустите игру, нажав кнопку Play , и убедитесь, что все работает.

Сброс игры

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

Это состояние отловить очень просто: шар будет активен, а его положение по оси Y отрицательно. Если это так, то мы переводим шар в неактивное состояние и ставим его на платформу:

If (ballIsActive && transform.position.y

А вот теперь точно все. Запустите игру и проверьте, все ли работает как положено.

В следующей части

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

Всем привет. Продолжаем дело, начатое в первой части. Сейчас у нас есть платформа и стоящий на ней персонаж с анимацией покоя. Настало время научить нашего персонажа бегать вправо-влево по платформе.

Загрузим сцену из первой части. Напомню, что в прошлый раз мы импортировали несколько спрайтов в папку AssetsSprites . На всякий случай, внизу поста еще раз приведу ссылку на спрайты. Среди них должен быть спрайт под названием Run . Мы будем использовать его для создания анимации бега. Для этого нам надо проделать те же действия по превращению одиночного спрайта в коллекцию, как и при создании анимации покоя. Вкратце напомню: выделяем спрайт, в окне Inspector устанавливаем свойство Sprite Mode как Multiple , нажимаем ниже Sprite Editor , нарезаем изображение в режиме Grid или Automatic .

Теперь в окне Hierarchy выбираем Character и переходим в окно Animation . Нажимаем на поле с анимацией Idle и выбираем Create New Clip , чтобы создать анимацию бега. Сохраним файл анимации в папке AssetsAnimations под именем Run .

Новая созданная анимация Run стала текущей в окне Animation . Разворачиваем спрайт Run в окне Project , выделяем все фалы Run_0… Run_9 и перетаскиваем в окно Animation . Установим пока значение Sample равное 24.

Все это мы уже делали в первой части, а теперь будет нечто новое. Перейдем в окно Animator . Сейчас там отображены три анимации: Any State , Idle и Run . Нам предстоит задать условия перехода из анимации Idle в анимацию Run , то есть из состояния покоя в состояние бега. В нижнем левом углу есть поле Parameters . Нажимаем на плюсик, выбираем Float и называем новый параметр как Speed . Тем самым мы создали параметр типа число с плавающей запятой, обозначающий скорость перемещения персонажа. Именно в зависимости от значения этого параметра будет происходить переключение из анимации покоя в анимацию бега. Теперь нажимаем правой кнопкой мыши на анимацию Idle , выбираем Make Transition и нажимаем левой кнопкой мыши на анимацию Run . Между анимациями появится линия со стрелкой. Передвиньте мышкой прямоугольники анимации, если плохо видно. Кликнем по линии со стрелкой. В окне Inspector отобразятся свойства перехода между анимациями. Обратим внимание на низ окна, в раздел Conditions . Кликнем на параметр Exit Time и поменяем его на Speed . Второе поле Greater оставим без изменений, а в третьем введем значение 0.01 . Мы создали условие перехода из анимации покоя в анимацию бега — оно происходит, когда значение параметра скорости становится немногим больше нуля.

Теперь нужно сделать обратный переход — из Run в Idle . Делаем все с точностью наоборот: Make Transition от Run к Idle , выделяем переход, в Conditions устанавливаем SpeedLess0.01 .

Теперь у нас есть две анимации и условия перехода между ними. Но пока ничего работать не будет, потому что все что мы сделали нужно «оживить» при помощи скрипта. Давайте перейдем в окно Project и создадим в папке Assets подпапку Scripts . Добавим в нее новый C# Script , назовем его CharacterControllerScript и откроем на редактирование.

Я приведу полный листинг скрипта с подробными комментариями, а ниже еще поясню, что в нем происходит.
using UnityEngine; using System.Collections; public > /// Начальная инициализация /// private vo > /// Выполняем действия в методе FixedUpdate, т. к. в компоненте Animator персонажа /// выставлено значение Animate Physics = true и анимация синхронизируется с расчетами физики /// private vo , Mathf.Abs(move)); //обращаемся к компоненту персонажа Rig > 0 && !isFacingRight) //отражаем персонажа вправо Flip(); //обратная ситуация. отражаем персонажа влево else if (move /// Метод для смены направления движения персонажа и его зеркального отражения /// private vo >

Итак, мы завели несколько переменных: для задания максимальной скорости перемещения, для определения направления (вправо/влево) и для работы с компонентом Animator . Почти все действия происходят в методе FixedUpdate . В нем мы получаем значение оси Х , которое меняется при нажатии на клавиатуре клавиш влево-вправо или A-D (если не меняли соответствующие настройки проекта!). Затем устанавливаем это значение параметру Speed компонента Animator . Обратите внимание, что мы берем модуль этого значения при помощи метода Mathf.Abs , так как при создании условий перехода между анимациями покоя и бега мы сравниваем значение параметра с положительным числом 0.01 . Нам здесь не важно, в какую сторону бежит персонаж. Важно лишь величина значения. Далее задаем скорость перемещения по оси Х в соответствии со значением максимальной скорости. И, наконец, проверяем, в какую сторону бежит персонаж, и в какую сторону он в этот момент повернут. Если он бежит вправо, а повернут влево — разворачиваем его вправо путем инвертирования его размера по оси Х . И наоборот. Этим нехитрым способом мы избавились от необходимости делать две анимации вместо одной: для бега вправо и для бега влево.

Сохраняем скрипт. В Unity перетаскиваем его на нашего Character в окне Hierarchy . Запускаем игру, нажимаем влево-вправо или A-D.

Капитан Коготь теперь умеет бегать! Скорость анимации получилась быстроватой. Ее можно снизить путем уменьшения значения Sample в окне Animation для анимации Run (значение 12 будет нормально). Если одновременно с игрой у вас видно окно Animator , то вы увидите, что во время покоя работает анимация Idle (бегает синий прогрессбар), а во время бега происходит переход на анимацию Run , и, соответственно, работает она.

На этом пока все. Нам осталось разобраться с прыжками… и узнать при этом еще несколько новых вещей!

Пример создания простой 2D игры для Android с использованием игрового движка Unity

Прежде всего, хочу сразу отметить, что я не являюсь профессиональным разработчиком. В этой статье я постараюсь изложить свой опыт создания игры «Feel Speed Racing». Данный материал, скорее всего не будет интересен тем, кто уже имеет большой опыт в разработке игр, но начинающим разработчикам, которые хоть немного работали с Unity думаю, будет интересно.

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

Игра состоит из 2-х сцен: главное меню и сама игровая сцена:

Где «menu» это главное меню а «1» это игровая сцена.

Главное меню

Для создания столь незамысловатого меню нам потребуется элемент управления GUI, который является стандартным в Unity.

В качестве фона я использовал спрайт с именем «background» заполненный серым цветом. Вы же можете выбрать что угодно.

Далее создаем скрипт «menu.cs»(Щелкаем правой кнопкой->выбираем Create-> C# Script) и вешаем его на background.

В результате должно получиться примерно вот так:

Шрифт, цвет и размер GUI элементов вы можете изменить с помощью MyStyle.

Создание игровой сцены

Основными на этой сцене элементами является дорога, автомобиль и шкала топлива.

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

Кидаем спрайт с дорогой на игровую сцену и подгоняем по размерам камеры.

Затем добавляем как дочерние объекты внутрь дороги 4 блока с препятствиями, топливный бак и не забываем добавить к ним Box Collider 2D.Еще надо отметить Is Triger для пересечения с автомобилем.

Теперь создаем скрипт moveroad.cs и вешаем его на нашу дорогу.

Добавляем в него следующий код:

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

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

Должно получиться вот так.

Кидаем спрайт автомобиля на сцену и устанавливаем его в любое место на дороге. Затем создаем скрипт carcontroller.cs и вешаем его на автомобиль.

Теперь автомобиль может перемещаться.

Для создания шкалы потребовалось 2 спрайта одинаковых размеров, но разных цветов (красный, зеленый). И сделать один из них дочерним (зеленый).

Далее создаем скрипт fuelscript.cs, вешаем его на fuel и добавляем в него код:

Дорога у меня это road183 и ее дубликат road183(1). В ее дочерний объект fueltrack нужно добавить скрипт для обнаружения пересечения с автомобилем и восполнения топлива.

Создаем скрипт triger.cs и вешаем его на fueltrack в обеих дорогах и отмечаем как Is Triger. Код:

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

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

Разработка 2D игры на Unity (5/5) «Сборка проекта»

Привет, пикабу! Спасибо, что проявляете интерес к моему далеко не профессиональному творчеству =) И спасибо знатокам — за замечания строго по делу. Этот пост будет крайним в этой серии, но если вам будет интересно узнать, как портировать проект на мобильные устройства — я напишу ещё один, бонусный пост по этой игре.

А так же ссылка на исходники, расположенные на гуглодиске. По прежнему без кода.

Начать хотелось бы с того, что я вспомнил об одной ошибке. Я забыл добавить в пост проверку нажатия клавиши пробел. Как следствие — игра бы не запускалась =) Но это даже хорошо. Будет возможность сразу столкнуться с ежедневной рутинной задачей программиста — поиском багов. Будем считать, что эта ложка дёгтя для того, чтобы не очаровываться.

Но, всё равно прошу у вас прощения за допущенную оплошность.

В этом посте я расскажу, как делается сборка проекта под ОС Windows. Задача эта неимоверно проста, поэтому букв тут будет не так много. Для начала, открываем меню File, выбираем пункт Build Settings, и в открывшемся окошке (в самом низу) ищем кнопочку Player

Settings. Нажимаем её, и нам откроется вот такой чудесный вид:

Сегодня всё, что нам понадобится — поместилось на одном скрине. Но, обо всём по порядку.

Окно Build Settings содержит в себе минимальные настройки, необходимые для сборки проекта. Первое, что необходимо сделать — добавить в проект нашу сцену. Делается это одним из двух способов, либо нажимаем кнопочку Ad Current, либо перетаскиваем файл сцены из окна проекта и бросаем его в поле Scenes In Build.

Обратите внимание на цифру ноль, справа от названия файла сцены. Это её порядковый номер. Если сцен в вашем проекте несколько — помните. Та сцена, что должна будет грузиться первой — должна получить идентификатор ноль. Иначе — случится ужасное. Unity автоматически подгрузит вместо вашего чудесного вступительного ролика — сцену, что случайно получила главный идентификатор.

Далее — нам необходимо выбрать, под какую платформу мы будем делать сборку. Тут сразу оговорюсь, что для сборки под Android, вам необходимо будет установить дополнительное ПО. Самое важное — Android SDK. Без него Unity откажется производить сборку. А без остального софта — откажется вставать сама SDK. Поэтому закатываем губу и выбираем пункт PC, Mac & Linux Standalone. Справа — выбираем платформу Windows и поддерживаемую архитектуру. Фактически — готово. Чтобы показать игру маме и бабушке — нам достаточно того, что мы уже сделали и можно смело нажимать кнопочку Build And Run.

Ну а для тех, кто всё таки хочет учиться — расскажу ещё о нескольких настройках, необходимых для того, чтобы сборка выглядела прилично. Обратите внимание на инспектор. Если там ничего нет, ещё раз нажмите кнопочку Player Settings в окне сборки.

Здесь нам понадобится всего несколько пунктов:

Поля Company Name и Product Name — позволят указать название игры и разработчика.

Default Icon — это иконка нашей игры. Можете нарисовать что нибудь более красивое, я просто поставил один из спрайтов нашего волка.

В окне Resolution & Presentation в пункте Resolution снимаем галочку с Default Is Full Screen. Во первых потому, что графика игры — не торт. А во вторых, чтобы избежать конфуза с выдёргиванием компьютера из розетки, ибо мы с вами не предусмотрели кнопку выхода.

В той же вкладке, но в пункте Stanalone Player Options, необходимо выбрать Disabled в пункте Display Resolution Dialog. Этот пункт позволяет отключить окошко, выводящее настройки управления в игре, перед запуском приложения.

Ну вот и всё. Теперь можно нажать Build And Run в окне сборки и наслаждаться игрой. Напомню, что моя цель — не научить вас, как НАДО делать игры. А помочь сделать первые шаги в сторону игровой индустрии. Поэтому, у вас остался простор для доработки игры. Сделайте увеличение скорости игры, по мере её прохождения. Выводите экран победы или поражения. Экспериментируйте, друзья! Это интересно!

Спасибо, что дочитали серею до конца. Огромное спасибо всем, кто на меня подписался. Очень надеюсь, что вам было интересно. Пожалуйста, напишите в комментариях, будет ли вам интересна серия постов по созданию трёхмерной игры? Это будет шутер от третьего лица, наподобие игры Alien Shooter. А главным героем станет — Марио =)

Не забывайте ставить плюсы, чтобы поблагодарить автора. Это лучшая мотивация, чтобы сидеть ночью и писать. А так же подписывайтесь, чтобы не пропустить новые посты! 😉

Мастер Йода рекомендует:  Таргетинг экономим время и деньги
Добавить комментарий
Type Name Latest commit message Commit time
..
Failed to load latest commit information.