Проблема
Вы хотите стрелять снарядами из вашего игрока/моба и т. д.
Решение
Настройка снаряда
Сначала мы настроим объект «снаряд», который мы хотим создавать. Вот узлы в Godot, которые мы будем использовать:
Area2D: Bullet
Sprite2D
CollisionShape2D
Для текстуры Sprite2D вы можете использовать любое изображение на ваш вкус. Вот пример:
Настройте узлы, спрайт и форму столкновения. Если ваша текстура ориентирована вверх, как на приведенном выше примере, убедитесь, что повернули узел Sprite на 90°, чтобы он указывал вправо.
Добавьте скрипт и подключите сигнал body_entered узла Area2D.
extends Area2D
var speed = 750
func _physics_process(delta):
position += transform.x * speed * delta
func _on_Bullet_body_entered(body):
if body.is_in_group("mobs"):
body.queue_free()
queue_free()
В этом примере мы удалим снаряд, если он попадет во что-либо. Мы также удалим все объекты из группы «мобы», в которые он попадет.
Стрельба
Нам нужно настроить место появления снарядов. Добавьте узел Marker2D и разместите его там, где вы хотите, чтобы снаряды появлялись. Вот пример, размещенный у дула оружия. Я назвал его «Muzzle».
Обратите внимание, что при вращении игрока трансформация Muzzle остается ориентированной таким же образом относительно оружия. Это будет очень удобным при создании снарядов, поскольку они могут использовать трансформацию для получения правильной позиции и направления. Мы просто устанавливаем transform нового снаряда равной трансформации дула.
Подсказка! Это будет работать для любого типа персонажа, не только для стиля «вращение и движение», как показанного здесь. Просто прикрепите Marker2D туда, где вы хотите, чтобы появлялись снаряды.
В скрипте персонажа мы добавляем переменную для хранения сцены снаряда для создания экземпляра:
@export var Bullet : PackedScene
И проверяем наше определенное действие ввода:
if Input.is_action_just_pressed("shoot"):
shoot()
Теперь в нашей функции shoot() мы можем создать экземпляр снаряда и добавить его в дерево. Распространенной ошибкой является добавление снаряда в качестве дочернего элемента игрока:
func shoot():
var b = Bullet.instantiate()
add_child(b)
b.transform = $Muzzle.transform
Проблема здесь заключается в том, что, поскольку снаряды являются дочерними элементами игрока, они подвергаются воздействию при перемещении или вращении игрока.
Чтобы исправить это, мы должны убедиться, что снаряды добавляются в мир. В этом случае мы будем использовать owner, который относится к корневому узлу сцены, в которой находится игрок. Обратите внимание, что нам также нужно использовать глобальное преобразование дула, иначе снаряд окажется не там, где мы ожидали.
func shoot():
var b = Bullet.instantiate()
owner.add_child(b)
b.transform = $Muzzle.global_transform
Скачать проект
Скачайте код проекта здесь: https://github.com/godotrecipes/2d_shooting