Menu
CoddyTech

발사하기

Coddy의 Roblox 게임: 타워 디펜스 코스 레슨. 18개 중 8번째.

적을 마주 보는 것은 임무의 절반입니다. shoot는 Humanoid:TakeDamage로 대상에게 피해를 주고, 머리에서 대상까지 짧은 빛의 섬광을 그립니다. 이 섬광은 얇은 네온 파트이며, 10분의 1초 후 Debris가 제거합니다.

Debris:AddItem(ray, 0.1) -- 0.1초 후 제거됨

발사한 후 타워는 다시 쏠 수 있을 때까지 Cooldown만큼 기다립니다. 이 때문에 궁수는 빠르고 대포는 느립니다.

Humanoid의 체력이 0이 되면 Died 이벤트가 발생합니다. 쓰러진 적은 즉시 게임에서 사라져야 하므로, spawnEnemy는 Died를 적을 제거하는 동작에 연결합니다. 그러면 walkPath가 적이 사라진 것을 확인하고 멈춥니다.

challenge icon

챌린지

중급
  1. Debris 서비스를 가져옵니다. beam(from, to)를 작성합니다. 고정된 네온 파트를 만들고, 크기는 0.2 × 0.2이며 거리를 길이로 설정한 다음, CFrame.lookAt((from + to) / 2, to)로 방향을 맞추고 Debris를 사용해 0.1초 후 제거합니다.
  2. shoot(tower, target, info)를 작성합니다. 대상의 Humanoid에 TakeDamage(info.Damage)를 적용한 다음, 머리에서 대상까지 빔을 만듭니다.
  3. runTower에서 방향을 돌린 다음 발사하고, 0.1초 대신 info.Cooldown만큼 기다립니다(대상이 없을 때는 0.1초를 유지합니다).
  4. 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
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Roblox 게임: 타워 디펜스의 모든 레슨