← Все уроки
Урок 4

Создай свой первый tower defense

Враги идут по дороге к твоей базе, а башня стреляет в ближайшего из них.

Бесплатно60 минут · Для новичков · Roblox Studio
1
Шаг 1 / 8

Подготовь место

  1. Открой Roblox Studio, нажми New Experience и выбери шаблон Baseplate.
  2. В Explorer наведи курсор на Workspace, нажми + и добавь Folder. Назови её Path.
  3. Добавь в Workspace вторую Folder и назови её Enemies. Оставь её пустой. Враги будут появляться в ней во время игры.

Подробнее

  • Шаблон Baseplate есть в списке шаблонов на стартовом экране.
  • Когда ты щёлкаешь +, введи слово Folder, чтобы быстро его найти. Папку переименовывают через F2.
  • Названия должны быть точно Path и Enemies, с заглавной буквы. Скрипты ищут именно эти названия.
  • На Mac каждый раз, когда в уроке написано Ctrl, нажимай клавишу Cmd.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

2
Шаг 2 / 8

Построй дорогу

  1. Добавь Part. Задай Size равным 6, 1, 6, включи Anchored и перетащи его в папку Path. Назови его 1.
  2. Сделай копию через Ctrl+D и отодвинь её примерно на 30 studs. Назови её 2.
  3. Повторяй, пока не получится 5 деталей с именами 1, 2, 3, 4 и 5. Расставь их так, чтобы на пути было несколько поворотов.
  4. Враги пойдут от 1 к 2, потом к 3 и так далее, по прямой между каждой парой.

Подробнее

  • Чтобы положить деталь в папку, потяни её название в Explorer на название Path.
  • Копия, сделанная через Ctrl+D, уже лежит в папке Path. Тебе остаётся только передвинуть её и переименовать.
  • Названия являются просто числами: 1, 2, 3, 4, 5. Без букв и без пробелов.
  • Оставь детали лежать на полу. Враги парят на 2 studs над ними.
Частая ошибка. Пропустить номер. Если детали 3 нет, враги остановятся на детали 2, а скрипт покажет ошибку.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

3
Шаг 3 / 8

Создай врага

  1. Добавь Part. Задай Shape равным Ball, Size равным 3, 3, 3 и сделай его красным. Включи Anchored, выключи CanCollide и назови его Enemy.
  2. Наведи курсор на Enemy, нажми + и добавь IntValue. Назови его Health и задай Value равным 3.
  3. Перетащи Enemy в ServerStorage. Теперь это шаблон. Игра будет делать с него копии.

Подробнее

  • Shape является списком в Properties. Щёлкни его и выбери Ball.
  • CanCollide является флажком в Properties. Без галочки игроки и другие детали проходят сквозь врага.
  • Когда ты щёлкаешь +, введи IntValue, чтобы его найти. Щёлкни новый IntValue, а потом в Properties измени Name на Health, а Value на 3.
  • Когда ты перетащишь Enemy в ServerStorage, он исчезнет из Viewport. Это правильно.
Совет. Враг Anchored, потому что его двигает скрипт. Детали с Anchored не поддаются гравитации и толчкам.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

4
Шаг 4 / 8

Построй базу

  1. Добавь большой Part в конце дороги, рядом с деталью 5. Включи Anchored и назови его Base.
  2. Наведи курсор на Base, нажми + и добавь IntValue. Назови его Health и задай Value равным 10.
  3. Добавь в Base объект BillboardGui с Size {0, 200}, {0, 50} и StudsOffset 0, 8, 0. Добавь в него TextLabel с Size {1, 0}, {1, 0} и включённым TextScaled.
  4. Добавь в Base Script и вставь этот код.
Base > Script
local base = script.Parent
local health = base.Health
local label = base.BillboardGui.TextLabel

local function update()
	if health.Value > 0 then
		label.Text = "Base: " .. health.Value
	else
		label.Text = "Game over"
	end
end

health.Changed:Connect(update)
update()

Что делает каждая часть

  • Changed срабатывает каждый раз, когда значение Health меняется.
  • Функция update записывает новое число на надпись над базой.
  • Когда Health доходит до 0, надпись показывает Game over, а скрипт Waves перестаёт посылать врагов.

Подробнее

  • Размер 10, 10, 10 хорошо подходит для базы. Любой цвет подойдёт.
  • Health базы является другим объектом, чем Health врага. Каждый лежит в своей детали.
  • Для Size и StudsOffset введи числа точно так, как показано, со скобками и запятыми, и нажми Enter.
  • Чтобы проверить: нажми F5. Надпись над базой показывает Base: 10.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

5
Шаг 5 / 8

Пошли волны

  1. Наведи курсор на ServerScriptService, нажми + и добавь Script. Назови его Waves.
  2. Удали строку, которая там уже есть, и вставь этот код.
  3. Нажми Play. Каждые 3 секунды у детали 1 появляется красный шар и идёт по дороге. Когда он доходит до конца, база теряет 1 здоровья.
ServerScriptService > Waves
local TweenService = game:GetService("TweenService")
local ServerStorage = game:GetService("ServerStorage")

local path = workspace:WaitForChild("Path")
local enemies = workspace:WaitForChild("Enemies")
local base = workspace:WaitForChild("Base")
local SPEED = 8

local function walk(enemy)
	for i = 2, #path:GetChildren() do
		local target = path[tostring(i)].Position + Vector3.new(0, 2, 0)
		local distance = (target - enemy.Position).Magnitude
		local info = TweenInfo.new(distance / SPEED, Enum.EasingStyle.Linear)
		local tween = TweenService:Create(enemy, info, {Position = target})
		tween:Play()
		tween.Completed:Wait()
		if not enemy.Parent then return end
	end

	base.Health.Value = math.max(0, base.Health.Value - 1)
	enemy:Destroy()
end

while base.Health.Value > 0 do
	task.wait(3)

	local enemy = ServerStorage.Enemy:Clone()
	enemy.Position = path["1"].Position + Vector3.new(0, 2, 0)
	enemy.Parent = enemies
	task.spawn(walk, enemy)
end

Что делает каждая часть

  • Clone делает копию шаблона Enemy из ServerStorage.
  • Функция walk двигает врага к каждой детали дороги по порядку. distance / SPEED держит скорость одинаковой на длинных и коротких участках.
  • task.spawn позволяет каждому врагу идти сам по себе, поэтому цикл может продолжать посылать новых.

Подробнее

  • Скрипт открывается в новой вкладке. Щёлкни внутри кода, нажми Ctrl+A, а потом Ctrl+V, чтобы заменить всё.
  • Пока игра идёт, враги появляются в папке Enemies. Ты можешь следить за ними в Explorer.
  • Пока башни нет, каждый враг доходит до базы. После 10 врагов надпись показывает Game over, и новые враги больше не приходят.
  • Красный текст про отсутствующее название в Output означает, что у детали дороги или у папки неправильное название.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

6
Шаг 6 / 8

Построй башню

  1. Добавь Part возле поворота дороги. Задай Size равным 4, 8, 4, включи Anchored и назови его Tower.
  2. Добавь в Tower Script и вставь этот код.
  3. Нажми Play. Раз в секунду башня бьёт ближайшего врага в зоне досягаемости. Враг вспыхивает белым, а после 3 попаданий исчезает.
Tower > Script
local tower = script.Parent
local enemies = workspace:WaitForChild("Enemies")
local RANGE = 25
local DAMAGE = 1

while true do
	task.wait(1)

	local target = nil
	local closest = RANGE
	for _, enemy in ipairs(enemies:GetChildren()) do
		local distance = (enemy.Position - tower.Position).Magnitude
		if distance < closest then
			target = enemy
			closest = distance
		end
	end

	if target then
		target.Health.Value -= DAMAGE
		if target.Health.Value <= 0 then
			target:Destroy()
		else
			target.Color = Color3.new(1, 1, 1)
			task.wait(0.1)
			target.Color = Color3.fromRGB(255, 60, 60)
		end
	end
end

Что делает каждая часть

  • Цикл измеряет расстояние от башни до каждого врага и запоминает ближайшего.
  • RANGE это то, как далеко достаёт башня. DAMAGE это сколько здоровья снимает один удар.
  • Когда Health доходит до 0, Destroy убирает врага.

Подробнее

  • Поставь башню в 8-12 studs от дороги. Радиус действия составляет 25 studs во все стороны.
  • Одна башня тратит 3 секунды на одного врага, а новый враг приходит каждые 3 секунды. Поэтому одна башня может удержать дорогу, только если враги остаются в зоне действия достаточно долго.
  • Белая вспышка длится десятую долю секунды. Приглядись, чтобы её увидеть.
  • Для второй башни выбери Tower и нажми Ctrl+D, а потом передвинь копию. Скрипт идёт вместе с ней.
Совет. Башня работает лучше всего рядом с поворотом, потому что там враги дольше остаются в зоне досягаемости.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

7
Шаг 7 / 8

Проверь и настрой баланс

  1. Нажми F5 и посмотри несколько волн.
  2. Если ни один враг не доходит до базы, игра слишком лёгкая. Если база быстро теряет всё здоровье, игра слишком трудная.
  3. Баланс настраивается тремя числами: временем ожидания в Waves, значением Health у врага и DAMAGE у башни.
  4. Нажми Shift+F5, чтобы остановить игру. Если что-то не работает, открой окно Output в меню Window и прочитай красный текст.

Подробнее

  • Меняй только одно число за раз, а потом играй снова. Иначе ты не узнаешь, какое изменение помогло.
  • Время ожидания является числом в task.wait(3) ближе к концу скрипта Waves. Меньшее число посылает врагов быстрее.
  • Health врага лежит в ServerStorage, внутри Enemy. DAMAGE башни стоит вверху скрипта Tower.
  • Хорошая первая цель: база должна продержаться две минуты с двумя башнями.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

8
Шаг 8 / 8

Опубликуй игру

  1. Выбери File → Publish to Roblox. Придумай игре название и короткое описание.
  2. На сайте Creator Hub открой свою игру и ответь на вопросы анкеты Maturity.
  3. Поставь игре статус Public и отправь ссылку другу.

Подробнее

  • Когда ты публикуешь впервые, Studio просит название и описание. Нажми Create.
  • Creator Hub является сайтом create.roblox.com. Войди с тем же аккаунтом и щёлкни свою игру в списке.
  • Прежде чем игру можно сделать публичной, Roblox может попросить что-то ещё, например проверку возраста на аккаунте. Страница подскажет, чего не хватает.
  • Если тебе ещё нет 18, выполняй этот шаг вместе с кем-то из родителей.
Совет. Покажи игру другу и задай один вопрос: было слишком легко или слишком трудно? Потом измени одно число и проверь снова.
У меня не получается этот шаг

Сначала проверь эти три вещи

  • Название каждой детали и каждого скрипта точно такое же, как в уроке, с теми же заглавными буквами.
  • Скрипт лежит в нужном объекте. Посмотри на подпись над блоком с кодом.
  • Открой окно Output через меню Window. Красный текст показывает скрипт и строку, в которой есть проблема.

Всё ещё не получается? Напиши нам →

Теперь измени сам

  • Добавь вторую башню с короткой дальностью и DAMAGE 2.
  • Сделай так, чтобы волны со временем ускорялись. Подсказка: храни время ожидания в переменной и после каждого врага делай его чуть меньше.
  • Дай базе 20 здоровья и сделай так, чтобы каждый враг отнимал 2.