К карте
ОСТРОВ КУЗНИ · GODOT · КВЕСТ 9
Затонувший храм
0
Прогресс0 / 5
СДЕЛАЙ ПЕРВЫЙ ХОД

Нажми — и увидишь, что делает команда

Жми кнопки по очереди — это три настоящие команды.
ПЕРЕД СТАРТОМ
⏱ Сколько займёт
30–50 минут, 5 шагов. Каждый шаг заканчивается результатом на экране.
💻 Что нужно
Компьютер с Windows или macOS. Понадобится Godot — бесплатный, поставим на первом шаге. С телефона этот квест не проходится.
⏸ Если прервёшься
Ничего не потеряется: прогресс сохраняется на этом устройстве. Вернёшься — продолжишь с того же шага.
🎓 Чему научишься
оружие и пули в 3D · направление объекта · свой игровой режим
ШАГ 1 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 9

Гарпуномёт в кадре

ЧТО ПРОИСХОДИТ
ЭПИЗОД 9Затонувший храм

Под водой, в двадцати метрах, стоят колонны. Между ними шевелится что-то большое.

Тео стучит по шлему: «Слушай внимательно, повторять не буду. В храме ты один. Гарпун стреляет туда, куда ты смотришь. В колчане их двадцать — промахнулся, значит одним меньше».

Дальше — твои правила. Сколько жизней, сколько врагов, чем всё кончится — решаешь ты.

мастер Тео · кузнец Острова Кузни
ЧТО ПОЛУЧИТСЯ
ЗАПИСЬ ГОТОВОЙ ИГРЫ
Настоящее 3D: колонны, туман, фонарь ныряльщика и гарпун, который летит туда, куда смотришь. Это финал экспедиции — твой первый шутер.

Это записано в самом Godot — движок посчитал физику и нарисовал каждый кадр. К концу квеста такая же игра будет запускаться у тебя.

СНАЧАЛА — ПОСМОТРИ
ЖИВАЯ ЗАПИСЬ ДВИЖКА
Гарпуномёт в руках, гарпун летит из дула. Финал экспедиции — и самая узнаваемая механика в играх. Счётчик патронов на экран в ролике не выведен — это твоё дело, Label по образцу третьего квеста.
Мастер Тео
Читать текстом
Оружейник, вот и финал. В храме ты один, гарпун летит туда, куда ты смотришь, и половину этой работы ты уже делал в плоском мире. Секрет объёма вот в чём: «вперёд» — это минус Z. Так устроена математика и в Godot, и в Unity, и в Blender. Скопируешь гарпуну поворот дула — он полетит точно в прицел. Сделаешь оружие, мишени и свой тир на скорость.

Половину этого ты уже делал в 2D. Посмотрим, что изменилось.

ЗАДАНИЕ 1 · СБОРКА
Player · CharacterBody3D
  └─ Head · Node3D
       ├─ Camera3D · глаза
       └─ Gun · Node3D — гарпуномёт
            ├─ GunMesh · модель оружия
            └─ Muzzle · Marker3D — точка вылета гарпуна

Гарпуномёт — ребёнок головы, значит смотрит туда же, куда камера. Muzzle — просто пустая точка на конце ствола: гарпуны будут рождаться именно там, а не в центре героя.

Модель оружия бесплатно возьми в наборе Kenney Blaster Kit на kenney.nl.

ШАГ 2 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 9

Выстрел

ЗАДАНИЕ 2 · КОД ГАРПУНОМЁТА
gun.gdGDSCRIPT
extends Node3D
# gun.gd — гарпуномёт: выстрел, патроны, создание пуль

const BULLET := preload("res://prefabs/harpoon3d.tscn")

@export var ammo: int = 10

@onready var muzzle := $Muzzle   # дуло

func _physics_process(_delta: float) -> void:
	if Input.is_action_just_pressed("shoot") and ammo > 0:
		shoot()

func shoot() -> void:
	ammo -= 1
	var b = BULLET.instantiate()
	b.global_transform = muzzle.global_transform   # сначала поворот и место
	get_tree().current_scene.add_child(b)   # и только потом — в мир
@onready — «найди этого ребёнка, когда сцена соберётся». Без него узел ещё не существует в момент запуска. global_transform копирует гарпуну положение и поворот дула — он вылетит точно туда, куда смотрит ствол.

Порядок этих двух строк решает всё. В момент add_child у гарпуна срабатывает _ready() — и он тут же считает, куда лететь. Зададим поворот позже — гарпун уже разогнался не туда и полетит в одну и ту же сторону мира, куда бы ты ни целился.

Сначала заведи клавишу: Проект → Настройки проекта → «Карта действий» (Input Map) → добавь действие shoot и назначь ему левую кнопку мыши. Без этого Godot напишет «The InputMap action "shoot" doesn't exist».

Сравни с 2D-выстрелом из пятого квеста: та же схема — preload, instantiate, add_child. Добавилось только одно: гарпуну теперь важен поворот, а не только точка.

Почему гарпун добавляют в get_tree().current_scene, а не в сам гарпуномёт?
Иначе гарпун будет ездить вместе с гарпуномётом, оставаясь у дула
В гарпуномёт нельзя добавлять детей
Так быстрее работает
ШАГ 3 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 9

Куда летит гарпун

ЗАДАНИЕ 3 · КОД ГАРПУНА
bullet.gdGDSCRIPT
extends RigidBody3D
# bullet.gd — гарпун: разгоняется один раз, дальше его несёт физика

@export var speed: float = 30.0
@export var lifetime: float = 3.0   # через сколько секунд исчезнет

func _ready() -> void:
	linear_velocity = -global_transform.basis.z * speed
	await get_tree().create_timer(lifetime).timeout
	queue_free()
Главная строка — первая. «Вперёд» у любого объекта в 3D — это минус Z его собственных осей. Гарпун скопировал поворот дула ещё до того, как попал в сцену, — значит его минус Z смотрит точно в прицел. А await с queue_free() — это уже знакомая уборка из шестого квеста.

Сцена гарпуна — новая сцена, сохрани как res://prefabs/harpoon3d.tscn. Корень Bullet · RigidBody3D, внутри: MeshInstance3D с CylinderMesh, CollisionShape3D и HitZone · Area3D со своей CollisionShape3D. У корня в Инспекторе поставь Gravity Scale = 0 — иначе гарпун полетит по дуге и воткнётся в пол.

Убери queue_free() — и через минуту в сцене будут тысячи пуль. Игра начнёт тормозить, а потом зависнет. Всё, что появляется во время игры, обязано уметь исчезать.

МИНУС Z — ЭТО «ВПЕРЁД»
Странное правило, но его придумали не в Godot: так устроена математика 3D-графики почти везде — в Unity, в Blender, в OpenGL. Камера смотрит вдоль своей оси −Z, и всё остальное подстроили под неё. Просто запомни: вперёд = −Z, вверх = +Y, вправо = +X.
ЭКСКУРС
ПРОФЕССИЯ

Кто придумывает правила игры

Человек, который решает «три жизни или пять», «сколько врагов» и «чем всё кончится», называется геймдизайнер.

Он почти не пишет код и не рисует. Его работа — придумать правило, а потом проверить на живых людях, что играть интересно. Это называется плейтест.

Правило простое: если тестировщик скучает — виноват не тестировщик. Значит, правило нужно менять.

ШАГ 4 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 9

Попадание и мишени

ЗАДАНИЕ 4 · МИШЕНИ
hit_zone.gdGDSCRIPT
extends Area3D
# hit_zone.gd — вешается на ребёнка гарпуна

func _on_body_entered(body: Node3D) -> void:
	if body.is_in_group("targets"):
		body.queue_free()
	get_parent().queue_free()
Один в один как в 2D — поменялась только тройка в названиях узлов. Скрипт вешается на HitZone внутри сцены гарпуна — и там же, во вкладке «Узел», подключи сигнал body_entered, иначе функция никогда не вызовется. Мишеням не забудь добавить группу targets: выдели узел → вкладка Узел → Группы.

Мишень — это обязательно физическое тело: StaticBody3D (стоит намертво) или RigidBody3D (падает и катится), а внутри — MeshInstance3D и CollisionShape3D. Голый меш Area3D просто не заметит.

Поставь по миру пять-шесть мишеней: ящики, бочки, летающие шары. Стрельба по неподвижным предметам быстро надоедает — попробуй подвесить парочку и раскачать.

СОБЕРИ ПОРЯДОК
ПОРЯДОК ВНУТРИ ФУНКЦИИ SHOOT()
get_tree().current_scene.add_child(b)
ammo -= 1
b.global_transform = muzzle.global_transform
var b = BULLET.instantiate()
ШАГ 5 ИЗ 5 · ОСТРОВ КУЗНИ · GODOT · КВЕСТ 9

Охота на время

НАСТОЯЩИЙ ЭКРАН GODOT — КУДА НАЖИМАТЬ
ТВОЙ ЭКРАН GODOT — КУДА НАЖИМАТЬнажми на кружок — покажу место
Окно редактора
  • 1Дерево героя — сюда встанет гарпуномётНа кадре у Player есть камера, а оружия нет. Добавь рядом с Camera3D узел Node3D по имени Gun — он ребёнок головы, значит смотрит туда же, куда глаза. Внутрь Gun положи модель и пустой Marker3D по имени Muzzle: это точка на конце ствола, откуда будут вылетать гарпуны.
  • 2Свиток с зелёным плюсом — скрипт оружиюВыдели Gun и жми: res://scripts/gun.gd. Скриптов в квесте три, и живут они на разных узлах: gun.gd на оружии, bullet.gd на корне отдельной сцены гарпуна, hit_zone.gd на его Area3D. Один узел — один скрипт; перепутаешь хозяина — не заработает ничего.
  • 3Компас осей: вперёд — это минус ZСиний шарик Z смотрит на тебя, поэтому «вперёд» у любого объекта — минус его Z. Отсюда и строка linear_velocity = -global_transform.basis.z * speed. Порядок важен: сначала гарпун копирует поворот дула, и только потом получает скорость. Сделаешь наоборот — он будет улетать в одну и ту же сторону мира, куда бы ты ни целился.
  • 4Мишени расставляй по всему мируЯщики, бочки, шары — близко, далеко, высоко и за укрытием, иначе стрелять надоест через минуту. Ставь их прямо на землю, как этот холм. И помни: всё, что появляется во время игры, обязано уметь исчезать — без таймера жизни у гарпуна через минуту в сцене будут тысячи снарядов, и игра начнёт тормозить.
  • 5Группы — в соседней вкладке этого докаВыдели мишень и добавь ей группу targets: вкладка «Группы» живёт в том же правом доке, что и «Сигналы» на кадре, — панель узкая, вкладки прокручиваются стрелками в её правом верхнем углу. Слово в группе и слово в коде должны совпасть буква в букву: is_in_group("targets").
Отмечено:0 из 5

Это настоящий экран Godot, вкладка 3D: слева дерево объёмной сцены, в центре мир с землёй, холмом и героем-ящиком, а на нём — гизмо из трёх стрелок. Нажимай на кружки по порядку: метка покажет место, строка ниже объяснит, зачем оно.

МАСТЕР ТЕО · ГИЛЬДИЯ РАЗРАБОТЧИКОВ
Экспедиция «Глубина острова» закрыта. За три квеста ты собрал 3D-мир, героя от первого лица и оружие. Это скелет любого шутера — дальше идут только детали: враги, звук, меню, уровни.
Мастер Тео
Читать текстом
Экспедиция «Глубина острова» закрыта, и ты Мастер Гильдии. За девять квестов ты собрал платформер и трёхмерный шутер на одном движке. Унеси с собой главное: сигналы, заготовки сцен, таймеры и группы работали и в плоском мире, и в объёмном. Меняется измерение, а ремесло остаётся тем же.

И главное, что стоит унести с собой: ты почти ничего не учил заново. Сигналы, префабы, таймеры, группы — всё это было в платформере. Движок один, приёмы одни, меняется только измерение.

Поднимай флаг.

Экспедиция закрыта!

Гарпун, выстрелы, попадания и своя охота — 3D-шутер работает. Печать МАСТЕР ГИЛЬДИИ.

🏅 Забрать диплом Вернуться на остров Кузни
🔒

Этот остров ещё закрыт

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

⚑ Экспедиционный режим