발사하기
Coddy의 Roblox 게임: 타워 디펜스 코스 레슨. 18개 중 8번째.
적을 마주 보는 것은 임무의 절반입니다. shoot는 Humanoid:TakeDamage로 대상에게 피해를 주고, 머리에서 대상까지 짧은 빛의 섬광을 그립니다. 이 섬광은 얇은 네온 파트이며, 10분의 1초 후 Debris가 제거합니다.
Debris:AddItem(ray, 0.1) -- 0.1초 후 제거됨발사한 후 타워는 다시 쏠 수 있을 때까지 Cooldown만큼 기다립니다. 이 때문에 궁수는 빠르고 대포는 느립니다.
Humanoid의 체력이 0이 되면 Died 이벤트가 발생합니다. 쓰러진 적은 즉시 게임에서 사라져야 하므로, spawnEnemy는 Died를 적을 제거하는 동작에 연결합니다. 그러면 walkPath가 적이 사라진 것을 확인하고 멈춥니다.
챌린지
중급Debris서비스를 가져옵니다.beam(from, to)를 작성합니다. 고정된 네온 파트를 만들고, 크기는 0.2 × 0.2이며 거리를 길이로 설정한 다음,CFrame.lookAt((from + to) / 2, to)로 방향을 맞추고 Debris를 사용해 0.1초 후 제거합니다.shoot(tower, target, info)를 작성합니다. 대상의 Humanoid에TakeDamage(info.Damage)를 적용한 다음, 머리에서 대상까지 빔을 만듭니다.runTower에서 방향을 돌린 다음 발사하고, 0.1초 대신info.Cooldown만큼 기다립니다(대상이 없을 때는 0.1초를 유지합니다).spawnEnemy에서 Humanoid가 죽으면 적을 제거합니다.
Play를 누른 다음 Check를 누르세요.
직접 해보기
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local enemies = workspace.Enemies
local towers = workspace.Towers
print("The base can take " .. Settings.BaseHealth .. " hits")
-- 순서대로 정렬된 경유 지점들(이름은 1, 2, 3...)
local waypoints = workspace.Path.Waypoints:GetChildren()
table.sort(waypoints, function(a, b)
return tonumber(a.Name) < tonumber(b.Name)
end)
-- workspace의 속성으로 저장된 기지의 체력: 모든 클라이언트가 읽을 수 있습니다
workspace:SetAttribute("BaseHealth", Settings.BaseHealth)
-- 모든 플레이어는 리더보드에서 Money를 받습니다
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local money = Instance.new("IntValue")
money.Name = "Money"
money.Value = Settings.StartMoney
money.Parent = leaderstats
end)
-- 적이 기지에 도달했습니다
local function damageBase(amount)
local health = math.max(0, workspace:GetAttribute("BaseHealth") - amount)
workspace:SetAttribute("BaseHealth", health)
end
-- 적을 경로를 따라 이동시킵니다. MoveTo는 8초 후 이동을 포기하고 이를 알립니다
-- (MoveToFinished가 false를 반환), 따라서 느린 적은 도착할 때까지 다시 이동 명령을 받습니다.
local function walkPath(enemy)
local humanoid = enemy.Humanoid
for i = 2, #waypoints do
repeat
humanoid:MoveTo(waypoints[i].Position)
until humanoid.MoveToFinished:Wait() or not enemy.Parent
if not enemy.Parent then
return
end
end
-- 기지에 도달했습니다
damageBase(Settings.Enemies[enemy.Name].Damage)
enemy:Destroy()
end
-- 입구에서 생성되어 경로를 따라 이동하는 새로운 적
local function spawnEnemy(kind)
local enemy = ServerStorage.Enemies[kind]:Clone()
-- 첫 번째 경유 지점 바로 위에 배치됩니다
enemy:PivotTo(waypoints[1].CFrame + Vector3.new(0, 5, 0))
local info = Settings.Enemies[kind]
enemy.Humanoid.MaxHealth = info.Health
enemy.Humanoid.Health = info.Health
enemy.Humanoid.WalkSpeed = info.Speed
enemy.Parent = enemies
task.spawn(walkPath, enemy)
return enemy
end
-- 한 지점에서 사거리 내에 있는 가장 가까운 살아 있는 적, 없으면 nil
local function nearestEnemy(position, range)
local best, bestDistance = nil, range
for _, enemy in enemies:GetChildren() do
local root = enemy:FindFirstChild("HumanoidRootPart")
if root and enemy.Humanoid.Health > 0 then
local distance = (root.Position - position).Magnitude
if distance <= bestDistance then
best, bestDistance = enemy, distance
end
end
end
return best
end
-- 타워의 동작: 사거리 내 가장 가까운 적을 조준합니다
local function runTower(tower)
local info = Settings.Towers[tower.Name]
while tower.Parent do
local target = nearestEnemy(tower.Head.Position, info.Range)
if target then
tower.Head.CFrame = CFrame.lookAt(tower.Head.Position, target.HumanoidRootPart.Position)
task.wait(0.1)
else
task.wait(0.1)
end
end
end
-- 패드 위에 타워를 건설합니다
local function placeTower(pad, kind)
local tower = ServerStorage.Towers[kind]:Clone()
tower:PivotTo(pad.CFrame + Vector3.new(0, pad.Size.Y / 2 + 1, 0))
tower.Parent = towers
task.spawn(runTower, tower)
end
-- 클라이언트가 패드에 타워를 배치해 달라고 요청한다
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
placeTower(pad, kind)
end)
-- 한 웨이브: 적을 하나씩 생성한 다음, 모두 사라질 때까지 기다린다
local function runWave(list)
for _, kind in list do
spawnEnemy(kind)
task.wait(Settings.SpawnGap)
end
while #enemies:GetChildren() > 0 do
task.wait(0.2)
end
end
-- 각 웨이브는 휴식 시간이 지난 뒤 시작된다
for i, list in Settings.Waves do
task.wait(Settings.WaveBreak)
runWave(list)
end
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.