Как создать 2D-шутер в Unity
2026-02-21 04:03 Diff

#Руководства

  • 24 июл 2019
  • 0

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

 vlada_maestro / shutterstock

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

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

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

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

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

  • управление транспортом;
  • прокачку персонажа;
  • торговлю;
  • исследование мира;
  • крафтинг (создание игровых предметов).

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

Есть два основных способа реализовать стрельбу:

  • Префабы. Добавляет на карту снаряд, которому можно прописать поведение — направление полета, действия при попадании и так далее.
  • Лучи (Raycast). Движок рисует невидимую линию от какой-нибудь точки в заданном направлении и возвращает данные о том, есть ли что-нибудь на пути.

Каждый стоит разобрать более подробно.

В первую очередь нужно подготовить всё, чтобы персонаж мог стрелять. Начать стоит с создания точки, откуда будет лететь снаряд или направляться луч. Для этого добавьте пустой объект с именем FirePoint и поместите его внутрь персонажа, расположив возле дула его оружия:

Затем нужно написать код, который позволит персонажу вращаться вместе с этой точкой. Создайте скрипт Controller.cs и прикрепите его к персонажу:

public class Controller : MonoBehaviour { private Rigidbody2D rb; private float speed = 5f; private bool isRightSide = true; void Start() { rb = GetComponent<Rigidbody2D>(); //Получение компонентов } void Update() { //Движение float moveX = Input.GetAxis("Horizontal"); rb.MovePosition(rb.position + Vector2.right * moveX * speed * Time.deltaTime); if ((moveX > 0f && !isRightSide) || (moveX < 0f && isRightSide)) //Если персонаж начал двигаться в противоположную сторону { Spin(); } } void Spin() { isRightSide = !isRightSide; transform.Rotate(0f, 180f, 0f); //Вращение персонажа по оси X на 180 градусов } }

Теперь персонаж сможет двигаться и вращаться вместе с объектом FirePoint:

После этого можно приступить к скрипту, который позволит стрелять. Назовите его Shooting.cs, добавьте к персонажу и используйте следующий код:

public class Shooting : MonoBehaviour { public GameObject bullet; //Снаряд public Transform firePoint; //Точка, с которой будут отправляться снаряды и лучи public LineRenderer lineRenderer; //Луч void Update() { if (Input.GetKeyDown(KeyCode.RightControl)) //Если игрок нажал на правый Ctrl { //Вызов метода стрельбы снарядами ShootBullet(); //Вызов метода стрельбы лучами StartCoroutine(Shoot()); //Выберите один из них } } }

Теперь можно разобрать оба способа стрельбы.

Для начала нужно создать снаряд. Для этого перетащите на карту спрайт и назовите его Bullet:

Добавьте коллайдер с триггером и создайте скрипт Bullet.cs, в котором будут обрабатываться попадания (он будет рассмотрен чуть позже). Сохраните объект в качестве префаба, а потом перетащите его в компонент Shooting.cs. Туда же перетащите FirePoint:

Теперь нужно написать метод, который будет создавать (инстанцировать) новые снаряды на карте:

void ShootBullet() { Instantiate(bullet, firePoint.position, firePoint.rotation); }

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

Пока снаряд остается на месте. Чтобы это исправить, нужно прописать в Bullet.CS этот код:

public class Bullet : MonoBehaviour { private Rigidbody2D rb; private float speed = 15f; private int damage = 20; private int life = 0; private int lifeMax = 500; void Start() { rb = GetComponent<Rigidbody2D>(); rb.velocity = transform.right * speed; //Изменение скорости } void Update() { life++; if (life >= lifeMax) { Explode(); //Если снаряд пролетел определенное расстояние и ни с чем не столкнулся, его нужно удалить, чтобы он не расходовал ресурсы } } void OnTriggerEnter2D(Collider2D hitInfo) //Метод, который срабатывает при попадании { Explode(); } void Explode() { Destroy(gameObject); //Уничтожение объекта } }

Теперь снаряд будет лететь и уничтожаться при попадании во что-то:

В первую очередь нужно добавить персонажу объект Effect -> Line.

Укажите в X — 1, а в Z — 0, а затем поставьте галочку Use World Space. После этого можно изменить толщину линии, поменять цвет, закруглить края и так далее.

Прикрепите получившуюся линию к скрипту Shooting.cs и добавьте следующий метод:

IEnumerator Shoot() //Выполнение методов этого типа можно остановить на определенный срок { RaycastHit2D hitInfo = Physics2D.Raycast(firePoint.position, firePoint.right); //Создание луча if (hitInfo) //Если луч во что-то попал { lineRenderer.SetPosition(0, firePoint.position); //Задание позиции начала линии lineRenderer.SetPosition(1, hitInfo.point); //Конец линии } else //Если попадания не было { lineRenderer.SetPosition(0, firePoint.position); lineRenderer.SetPosition(1, firePoint.position + firePoint.right * 50); } lineRenderer.enabled = true; //Включение отображения линии yield return 0; //Ждать один кадр lineRenderer.enabled = false; //Отключить отображение линии }

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

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

За очки жизни будет отвечать скрипт Health.cs — его нужно добавить всем объектам, которые должны получать повреждения при попадании.

public class Health : MonoBehaviour { public int hp = 100; public int hpMax = 100; void Update() { if (hp > hpMax) { hp = hpMax; } if (hp <= 0) { Die(); } } public void Hit(int damage) { hp -= damage; } void Die() { Destroy(gameObject); } }

Теперь нужно изменить код попадания внутри класса Bullet.cs:

void OnTriggerEnter2D(Collider2D hitInfo) { Health health = hitInfo.GetComponent<Health>(); if (health) { health.Hit(damage); } Explode(); }

Обновленный метод проверяет, есть ли у объекта, в который попал снаряд, компонент Health. Если он существует, то вызывается метод Hit(), который отнимает здоровье.

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

Чтобы игра не превратилась в стрельбу по неподвижным мишеням, нужно написать скрипт поведения объектов — NPC.cs:

public class NPC : MonoBehaviour { public GameObject bullet; public Transform firePoint; private Rigidbody2D rb; private Animator animator; private float speed = 5f; private bool isRightSide = true; private int timer = 0; private int timerMax = 50; private int action = 0; private int reload = 0; private int reloadMax = 5; void Start() { rb = GetComponent<Rigidbody2D>(); animator = GetComponent<Animator>(); } void Update() { timer++; if (timer >= timerMax) { timer = 0; action++; } float moveX = 0f; switch (action) { case 0: moveX = 1f; break; case 1: moveX = 0f; break; case 2: moveX = -1f; break; case 3: moveX = 0f; break; default: action = 0; break; } rb.MovePosition(rb.position + Vector2.right * moveX * speed * Time.deltaTime); if ((moveX > 0f && !isRightSide) || (moveX < 0f && isRightSide)) { Spin(moveX); } //Shooting if (reload >= 1) { reload--; } RaycastHit2D hitInfo = Physics2D.Raycast(firePoint.position, firePoint.right); if (hitInfo) { if (hitInfo.transform.tag == "Player") //Если объекту присвоен тег Player { Shoot(); } } } void Spin(float moveX) { isRightSide = !isRightSide; transform.Rotate(0f, 180f, 0f); } void Shoot() { if (reload <= 0) { Instantiate(bullet, firePoint.position, firePoint.rotation); reload = reloadMax; } } }

Так создается примитивная логика поведения персонажа. Он может двигаться или стоять на месте, а если заметит героя (это проверяется с помощью Raycast), то начнет стрелять.

Это довольно простой шутер, но полученных знаний должно хватить, чтобы разработать что-то более сложное и интересное. Если вы хотите глубже погрузиться в тему разработки игр на Unity, читайте статьи в нашем блоге и записывайтесь на курс  «Профессия разработчик игр на Unity».

Научитесь: Профессия Разработчик игр на Unity с нуля Узнать больше