Логика стрельбы в Unity 2D и 3D ничем не отличается, поэтому данный материал можно использовать в любом проекте, разница будет только в использовании двух- или трехмерных позиций, векторов и объектов.
Рассмотрим реализацию стрельбы в Unity 2D в игре с видом сбоку. Сначала необходимо подготовить объект, который будет выступать в качестве пули. Это может быть какой-то специальный спрайт, который нужно перетащить мышкой на игровую сцену, либо можно просто создать стандартный двумерный объект, например Circle (круг):
Сделаем круг желтым цветом, чтобы его было хорошо видно на сцене, и переименуем его в Bullet:
Чтобы этот мог взаимодействовать с другими объектами, например наносить урон врагам, добавим ему компонент Circle Collider2D. Для коллайдера установим флажок IsTrigger, чтобы пуля не оказывала физического воздействия на нашего персонажа, в частности не отталкивал его назад при генерации.
Добавьте объекту пули скрипт и откройте его. Поскольку пуля не является физическим телом, перемещать ее можно простым изменением позиции в компоненте Transform, например, в этой строке мы изменяем позицию объекта каждый кадр на одну единицу по оси X:
transform.position = transform.position + new Vector3(1, 0, 0);
Добавим возможность настроить скорость пули через публичную переменную и учет времени, прошедшего с предыдущего кадра:
transform.position = transform.position + new Vector3(speed * Time.deltaTime, 0, 0);
Таким образом скрипт пули будет выглядеть следующим образом:
После того, как объект пули создан и настроен, необходимо создать из него префаб, перетаскивая игровой объект из иерархии в заранее созданную папку префабов.
Удалите объект пули с игровой сцены, поскольку он должен появляться только во время стрельбы.
Теперь необходимо реализовать процесс стрельбы в скрипте персонажа. В скрипте на скриншоте ниже уже реализован код для перемещения персонажа. У Вас может быть свой код, который не требуется менять, необходимо просто добавить код, который отвечает за стрельбу.
Для начала заведем публичные переменные, с помощью которых мы определим объект, который будет генерироваться при стрельбе, и позицию, в которой этот объект будет создаваться.
public GameObject Bullet;
public Transform BulletPosition;
Теперь при нажатии клавиши, отвечающей за стрельбу, в Unity по умолчанию – это левый Ctrl, нам необходимо создавать объект Bullet в позиции BulletPosition.
Для этого в Unity существует специальная команда Instantiate, которая позволяет в коде создавать объект на игровой сцене:
if (Input.GetAxis("Fire1") > 0)
{
Instantiate(Bullet, BulletPosition);
}
Измененный скрипт персонажа будет выглядеть следующим образом, на скрине вертикальной оранжевой чертой представлены внесенные изменения:
Переходим в Unity и выбираем в иерархии объект персонажа. В инспекторе в компоненте скрипта, куда мы вносили изменения появятся две новые переменные Bullet и BulletPosition, которые нам необходимо связать с конкретными объектами.
В поле Bullet перенесите мышкой префаб пули, который мы подготовили до этого:
Теперь давайте создадим позицию, в которой эта пуля должна появляться во время стрельбы. Для этого создадим пустой объект (Create Empty), переименуем его в Gun и перенесем в объект персонажа (объект Gun будет являться дочерним для персонажа). Теперь переместите объект Gun в ту позицию, в которой должны появляться пули. Если у Вас персонаж держит оружие в руках, то объект Gun должен находится на конце этого оружия. В моем случае я просто помещаю объект Gun справа от персонажа:
Перенесите мышкой объект Gun из иерархии в поле BulletPosition скрипта персонажа:
Теперь, если запустить игру, мы увидим стрельбу, в которой пули выпускаются подряд целой очередью. Обычно в игре так не делается, а между генерацией пуль должно пройти какое-то время. Для этого в процесс стрельбы необходимо добавить таймер.
Для этого давайте заведем две переменные:
public float Period = 1;
float timerFire;
С помощью публичной переменной Period задается время, которое должно пройти до возможности следующего выстрела. А с помощью переменной timerFireмы будем определять сколько фактически уже прошло с момента последнего выстрела. Как только значение timerFire будет больше или равно значения переменной Period, это означает, что мы можем снова выстрелить.
Таким образом условие стрельбы по клавише Fire1 дополнится еще одним условием таймера, а после генерации пули необходимо обнулить таймер для нового отсчета:
if (Input.GetAxis("Fire1") > 0 && timerFire >= Period)
{
Instantiate(Bullet, BulletPosition);
timerFire = 0;
}
Каждый кадр нам необходимо теперь увеличивать переменную таймера:
timerFire = timerFire + Time.deltaTime;
Скрипт персонажа будет выглядеть следующим образом:
В Unity в инспекторе персонажа в скрипте задайте значение переменной Period, например, равным единице:
Одно дополнение – при такой реализации персонаж при запуске игры начинает стрелять не сразу, а через время, которое задано переменной Period. Если Вас устраивает такое, то хорошо, но если Вы хотите дать персонажу возможность стрелять сразу при запуске игры, то в методе Start необходимо присвоить таймеру timerFire значение переменной Period, таким образом дополнительное условие стрельбы (timerFire >= Period) сработает сразу при запуске игры.
void Start()
{
rb = GetComponent<Rigidbody2D>();
timerFire = Period;
}
Теперь стрельба реализована с таймером и пули вылетают по одной с интервалом равным значению переменной Period.
В 3D проекте логика реализации стрельбы остается точно такой же.