10 December 2014

Про создание платформера на Unity. Часть 4.1, злодейская

Microsoft corporate blogGame developmentUnity3D
Tutorial
Привет, Хабр!

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



Осторожно, под катом по-прежнему много гифок!



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

Итак, поехали. Я выделил четыре основных типа объектов, которые могут так или иначе помешать герою вашей игры достигнуть цели:

1) Статичные (вращающиеся пилы, «смертельные» блоки итд)
image

2) Ходящие по платформам (грибы и черепахи из Super Mario Bros)


3) Летающие (вороны со второго уровня Ghosts and Goblins)
image

4) Стреляющие (Баужя из своего замка того же Марио)


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

1) Статичные препятствия.
Сделаем вращающуюся пилу. Для реализации такого «врага» нужны буквально пара вещей — спрайт пилы и скрипт, который будет ее вращать. Сказано — сделано.

Перетаскиваем спрайт на сцену:
image

Создаем новый скрипт (это, как обычно, очень просто)
image

И добавляем туда код, выглядящий примерно так:
using UnityEngine;
using System.Collections;

public class rotator : MonoBehaviour {
	public float speed = 0.04f;
	
	void Update () {
		 transform.Rotate (new Vector3 (0f, 0f, speed * Time.deltaTime));
	}
}


В публичной переменной speed задается скорость вращения. Важно отметитить, что положительное значение вращает пилу против часовой стрелки, а отрицательное — по часовой.

Теперь, чтобы взаимодействовать с пилой, добавим на нее какой-нибудь коллайдер (подробно это описано в интереснейших предыдущих частях) и изменим тег объекта на какой-нибудь подходящий в данной ситуации.

Теги — хорошая штука. Мы можем назначить игроку тег player, врагам тег enemy, а стенам и полу — level. После этой нехитрой процедуры проверка того, с чем мы, например, столкнулись, будет происходить гораздо проще. А еще можно найти какой-нибудь один (или все, что есть на сцене) объект с определенным тегом. Делается это примерно так:

GameObject someEnemy = GameObject.FindGameObjectWithTag ("Enemy");


Массив всех объектов с заданным тегом можно получить используя метод FindGameObjectsWithTag — проще некуда.

Вернемся к нашим пилам и создадим новый тег для врагов в игре.
image

В скрипт персонажа добавим следующую проверку
	void OnCollisionEnter2D(Collision2D col){
				if (col.gameObject.tag == "Enemy")
						Application.LoadLevel (Application.loadedLevel);
		}


Как видите, все элементарно: проверяем коллизии, проверяем тег того, с чем столкнулись. Если все плохо, перезагружаем уровень. Или отнимаем жизнь. Или что-нибудь в этом духе. Вы ведь играли в платформеры, правда?

Вот как все это выглядит в итоге:
image

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

2) Ходящие, ползающие и другие враги, перемещающиеся по платформам.
Неподготовленному читателю может показаться что этот тип врагов сложнее в реализации чем первый. Спешу успокоить — это совсем не так. Как и в прошлом случае, нам нужны какой-нибудь спрайт, коллайдер на нем, скрипт и платформа, по которой все это будет двигаться. К этому небольшому списку добавится только rigidbody2D, чтобы на врага действовала физика и можно было устанавливать ему скорость.

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

Для его перемещения используем следующий скрипт
using UnityEngine;
using System.Collections;

public class walkingEnemy : MonoBehaviour {
	public float speed = 7f;
	float direction = -1f;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		rigidbody2D.velocity = new Vector2 ( speed * direction, rigidbody2D.velocity.y);
	}

Задаем скорость врага и направление его движения (-1 — влево, 1 — вправо), которое можно менять при столкновении со стенами, к примеру. Дальше просто — устанавливаем горизонтальную скорость, равную произведению значения скорости и направления.

Забавный факт
Забавный факт — если поставить у rigidbody2D галку fixedAngle, то враг будет ползти, а если убрать, то
image

«Но он смотрит вправо, а двигается влево!» — заметит внимательный читатель. Давайте пофиксим это и будем разворачивать спрайт соответственно направлению движения:

using UnityEngine;
using System.Collections;

public class walkingEnemy : MonoBehaviour {
	public float speed = 7f;
	float direction = -1f;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		rigidbody2D.velocity = new Vector2 ( speed * direction, rigidbody2D.velocity.y);
		transform.localScale = new Vector3 (direction, 1, 1);
	}
}


И научим разворачиваться при столкновении со стеной. Для этого сделаем на уровне пару стен с тегом wall и напишем обработку коллизий. Вот такую:

void OnCollisionEnter2D(Collision2D col){
		if (col.gameObject.tag == "Wall")
						direction *= -1f;
	}

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

Подведем промежуточный итог. Мы разобрали как создаются два типа «врагов» в 2D-платформерах: статичные и перемещающиеся по уровню. Как видите, это действительно очень просто и базовая реализация занимает совсем мало времени.

В следующей части я расскажу как создать два остальных вида врагов — летающих и стреляющих.
Stay tuned — будет интересно!

Предыдущие серии:
Часть первая, в которой мы учимся ходить
Часть вторая, в которой мы учимся проигрывать
Часть третья, в которой мы веселимся с физикой

Еще немного полезных ссылок


Изучить курсы виртуальной академии Microsoft по созданию игр и другим технологиям
Введение в программирование игр на Unity
Увлекательное программирование на языке C#

Загрузить Unity
Загрузить бесплатную или пробную Visual Studio
Стать разработчиком универсальных приложений Windows
Попробовать Azure бесплатно на 30 дней!
Tags:unitygame developmentплатформерврагимариосоздание игрgiftutorialникто не читает теги
Hubs: Microsoft corporate blog Game development Unity3D
+21
74.1k 371
Comments 17
Top of the last 24 hours