Лучевая трассировка (Raycasting) — это распространенная техника в разработке игр. «Raycasting» означает построение линии от определенной точки до столкновения с чем либо.
Оглавление
Свойства узла
Добавьте узел RayCast2D и взгляните на инспектор:
Вот основные свойства ноды в Godot, которые вам нужно понять:
- Включено
Выключите, чтобы отключить работу Raycasting.
- Исключить родителя
Это свойство заставляет луч игнорировать столкновения с объектом-родителем. Включено по умолчанию.
- Позиция цели
Это конечная точка луча. Примечание: в локальных координатах.
Также обратите внимание на раздел «Столкновение с» (Collide With). По умолчанию луч будет обнаруживать только тела, поэтому вам нужно будет зайти сюда, если вы хотите обнаруживать также области.
Полезные функции
Вы можете увидеть полный список функций узла в документации API. Вот несколько из наиболее полезных:
- is_colliding() — Булева функция, позволяющая определить, сталкивается ли луч с чем-то.
- get_collision_point() — Если луч сталкивается, эта функция вернет позицию столкновения (в глобальных координатах).
- get_collider() — Если луч сталкивается, эта функция вернет ссылку на объект, с которым произошло столкновение.
- get_collision_normal() — Еще одна полезная информация — это нормаль объекта, с которым произошло столкновение, в точке столкновения.
Примеры использования
Существует много способов использования Raycasting: определение видимости (может ли объект A видеть объект B или есть ли препятствие между ними?), определение близости (находится ли объект близко к стене/земле/препятствию и т. д.). Вот несколько практических примеров использования:
Стрельба
Быстродвижущиеся снаряды часто сталкиваются с проблемой «туннелирования» сквозь препятствия — они движутся слишком быстро, чтобы столкновение можно было обнаружить в одном кадре. В качестве альтернативы вы можете использовать Raycast2D для представления пути (или лазера и т. д.).
Вот пример: спрайт игрока с прикрепленным Raycast2D к концу оружия. Позиция цели установлена как (250, 0).
Когда игрок стреляет, вы проверяете, сталкивается ли луч с чем-то:
func _input(event):
if event.is_action_pressed("shoot"):
if $RayCast2D.is_colliding():
print($RayCast2D.get_collider().name)
Обнаружение вершин
Представьте врага в платформере, который ходит по платформам, но вы не хотите, чтобы он сваливался с краев. Добавьте два луча, направленных вниз, к мобу следующим образом:
В скрипте моба проверьте, когда луч перестает сталкиваться с поверхностью. Это означает, что вы обнаружили край, и должны развернуться:
func _physics_process(delta):
velocity.y += gravity * delta
if not $RayRight.is_colliding():
dir = -1
if not $RayLeft.is_colliding():
dir = 1
velocity.x = dir * speed
$AnimatedSprite.flip_h = velocity.x > 0
velocity = move_and_slide(velocity, Vector2.UP)
Вот как это выглядит в действии: