2D платформер, стрельба

Стрельба для двухмерной игры, платформера. Пример, прежде всего будет интересен начинающим игроделам, впрочем, не только, так как вариант уже готовый, бери и используй. Код достаточно простой, легко отредактировать если что. Стрельба реализована не через луч, а объектами. То есть, как в обычном платформере, чтобы пули были видимы. Подойдет для игры наподобие, как Contra или для управления какой-нибудь турелью. Реализовано вращение указанного объекта по оси Z, допустим, автомата. И предусмотрено ограничение на вращения. Настраиваются такие параметры как, скорость пули и скорострельность.

2D платформер, стрельба

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

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


Далее, на родителя модельки нашего оружия вешаем скрипт FireScript2D:

using UnityEngine;
using System.Collections;

public class FireScript2D : MonoBehaviour {

	public float speed = 10; // скорость пули
	public Rigidbody2D bullet; // префаб нашей пули
	public Transform gunPoint; // точка рождения
	public float fireRate = 1; // скорострельность

	public Transform zRotate; // объект для вращения по оси Z

	// ограничение вращения
	public float minAngle = -40;
	public float maxAngle = 40;

	private float curTimeout;
	
	void Start()
	{
	}

	void SetRotation()
	{
		Vector3 mousePosMain = Input.mousePosition;
		mousePosMain.z = Camera.main.transform.position.z; 
		Vector3 lookPos = Camera.main.ScreenToWorldPoint(mousePosMain);
		lookPos = lookPos - transform.position;
		float angle  = Mathf.Atan2(lookPos.y, lookPos.x) * Mathf.Rad2Deg;
		angle = Mathf.Clamp(angle, minAngle, maxAngle);
		zRotate.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
	}
	
	void Update()
	{
		if(Input.GetMouseButton(0))
		{
			Fire();
		}
		else
		{
			curTimeout = 100;
		}

		if(zRotate) SetRotation();
	}

	void Fire()
	{
		curTimeout += Time.deltaTime;
		if(curTimeout > fireRate)
		{
			curTimeout = 0;
			Rigidbody2D clone = Instantiate(bullet, gunPoint.position, Quaternion.identity) as Rigidbody2D;
			clone.velocity = transform.TransformDirection(gunPoint.right * speed);
			clone.transform.right = gunPoint.right;
		}
	}
}

Создадим модельку пули. Там дело на пару кликов. На спрайт пули вешаем компонент Rigidbody 2D и параметр Gravity Scale ставим на ноль, чтобы выключить гравитацию. Добавляем коллайдер и ставим галочку Is Trigger. И перетаскиваем объект в папку с префабами.


В завершении, цепляем на префаб скрипт Bullet2D:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody2D))]

public class Bullet2D : MonoBehaviour {

	void Start()
	{
		// уничтожить объект по истечению указанного времени (секунд), если пуля никуда не попала
		Destroy(gameObject, 20);
	}
	
	void OnTriggerEnter2D(Collider2D coll)
	{
		if(!coll.isTrigger) // чтобы пуля не реагировала на триггер
		{
			switch(coll.tag)
			{
			case "Enemy_1":
				// что-то...
				break;
			case "Enemy_2":
				// что-то еще...
				break;
			}

			Destroy(gameObject);
		}
	}
}

Указываем префаб в переменной скрипта стрельбы и можно тестировать.

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

Скачать демо сцену:

Внимание! Посетители, находящиеся в группе Гости, не могут скачивать файлы.

Комментариев 57

Офлайн
Stason4ikRU 13 мая 2017
Light,
Спасибо
Офлайн
Camera.main не работает. Пишет: Camera не содержит определения для main
Онлайн
Light 9 июня 2017
Дмитрий Туркин, нужно установить стандартный тег камеры MainCamera.
Офлайн
SleepyAsh 20 июня 2017
У меня проблема, сделал все как описано в комментариях(стрельба в обратную сторону не через мышку) theScale *=1; (т.к. на управлении персонажа стоит такой же разворот и рука просто не поворачивается) И суть проблемы в том, что, пуля всегда летит только в правую сторону. Подскажите пожалуйста люди добрые в чем может быть косяк?
Онлайн
Light 21 июня 2017
SleepyAsh, не совсем понятно, что и куда у тебя поворачивается. Кинь ссылку на проект в ЛС, посмотрим...
Офлайн
TEEAAA 28 сентября 2017
Как сделать перезарядку в этом же скрипте
Помоги пожалуйста если есть время
Онлайн
Light 28 сентября 2017
TEEAAA, планируется обновленная версия этого скрипта, где будут разные режимы, пистолет, автомат и т.п., с возможностью отображения кол. патронов и перезарядки оружия. Следите за новыми публикациями.
Офлайн
TEEAAA 29 сентября 2017
Light,
Спасибо, буду ждать
Офлайн
xKalibrx 2 октября 2017
Light,
Добрый день, пока не выпустили новую версию хотел бы задать вопрос.
При скорости пули около 100 то видимая коллизия происходит до того как пуля долетела до объекта. Я понимаю что всё дело в том что следующий ВИДИМЫЙ для глаза человека шаг при такой скорости пули попал именно уже в объект и удалился, но это выглядит корявенько потому что это срабатывает не всегда) а как повезёт) бывает пуля прям в плотную долетит бывает рядом уничтожится. Чем можно решить этот вопрос?)))
Онлайн
Light 2 октября 2017
xKalibrx, сместить триггер пули за ее спрайт, то есть чтобы вначале спрайт пули влетал в цель, а только потом происходила коллизия.
Офлайн
xKalibrx 2 октября 2017
Light,
Вариант, Спасиб
Офлайн
skywoker 31 марта 2018
а есть такой же скрипт но для врага, чтоб он автоматически стрелял?
Онлайн
Light 31 марта 2018
skywoker, зависит от ИИ врага, как он видит, потом вычисление вектора стрельбы...
Офлайн
Sapecorp 4 апреля 2018
Взял за основу ваш скрипт для своего платформера, у меня персонаж не стреляет, а бросает яблоко, ну не важно. Подскажите такой момент, когда персонаж стоит, при броске яблоко летит с заданной скоростью, при броске во время бега яблоко так же вылетает с заданной скоростью, и скорость яблока почти совпадает со скоростью персонажа получается персонаж бежит перед яблоком. Подскажите пожалуйста, каким образом можно вычислить скорость персонажа во время совершения выстрела/броска, чтобы к скорости яблока прибавилась скорость движения персонажа?
Онлайн
Light 4 апреля 2018
Sapecorp, чтобы получить скорость игрока, у персонажа должен быть компонент Rigidbody2D, потом к переменной скорости тела персонажа, добавляем скорость яблока:
body.velocity.magnitude + скорость яблока
Офлайн
mekkoss 5 мая 2018
Light, А как сделать что бы пуля летела по курсору, куда курсор показывает туда и пуля. Что бы можно было стрелять 360.
Онлайн
Light 5 мая 2018
mekkoss, убрать строку: angle = Mathf.Clamp(angle, minAngle, maxAngle);
Офлайн
mekkoss 6 мая 2018
Light,
https://sun1-2.userapi.com/c834501/u155803513/docs/d14/463d4d50eb10/asdaazz.gif?extra=pJuy1MLOFJJnk7FUJrfZkiVyG-oGtoIJ19Q9Qx_QDADTw2Ey4LGWWHchxiAIWPFejvdMx8M9btRXBZ4LPpI9yQpmrUBoSyl8KaXpyE4pFEJ1ELCVVnbT0pEbXJ1GCf71nLcu95o_E680RHI
Онлайн
Light 6 мая 2018
mekkoss, ссылка не работает.
Офлайн
mekkoss 6 мая 2018
Light,
Офлайн
mekkoss 6 мая 2018
Light, немного решил проблему исправив "Vector3 direction = gunPoint.position - transform.position;" на "Vector3 direction = gunPoint.position;"
Но пули вверх стали боком летать

И там если я отхожу влево то пули опять летят назад как на гифке которую я скинул.
Офлайн
mekkoss 6 мая 2018
Извиняюсь, проблему решил.
Офлайн
Dordoro 16 мая 2018
Как менять спрайт пули, я поменял спрайт у bullet. А клоны всё равно старые.
Офлайн
очень помогло, огромное спасибо. И за комменты с помощью тоже
Офлайн
linar2131 16 января 2019
Новичок в юньке. Снаряд после спавна вылетает немного вверх.
Офлайн
nekita06117 24 июня 2019
Что-то оно не стреляет
Онлайн
Light 24 июня 2019
nekita06117, вроде у всех стреляет...
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика