타워 배치하기
Coddy의 Roblox 게임: 타워 디펜스 코스 레슨. 22개 중 8번째.
회색 패드 중 하나를 클릭하면 선택한 타워가 그곳에 세워집니다. 클라이언트는 마우스에서 클릭을 읽습니다: me:GetMouse(), 해당 객체의 Button1Down 이벤트, 그리고 포인터 아래에 있는 파트인 Target입니다. 하지만 클라이언트는 직접 아무것도 세울 수 없습니다. 타워는 서버에 있기 때문입니다. 클라이언트는 원격 이벤트 Remotes.Place를 통해 요청합니다:
-- 클라이언트
remotes.Place:FireServer(workspace.Pads.Pad4, "Frost")
-- 서버: Roblox가 player를 첫 번째 인자로 추가합니다
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
end)타워 모델은 ServerStorage.Towers에서 대기합니다. 서버는 모델 하나를 복제해 패드 위에 놓습니다. 타워가 패드 위에 서도록 패드 높이의 절반에 1을 더한 만큼 높여 배치합니다.
챌린지
중급선택한 타워를 클릭한 패드에 설치하세요.
DefenseClient에서remotes(WaitForChild사용)와 LocalPlayer인me를 가져오세요.me:GetMouse().Button1Down에서mouse.Target이workspace.Pads안에 있고selected가 설정되어 있으면remotes.Place:FireServer(target, selected)를 호출하세요.DefenseServer에서remotes.Place.OnServerEvent가placeTower(pad, kind)를 호출하도록 하세요.ServerStorage.Towers[kind]를 복제해 패드 위의workspace.Towers에 배치하세요.
‘플레이’를 누르고 Archer를 선택한 다음 회색 패드를 클릭하세요. Archer가 패드 위에 서게 됩니다. 그런 다음 ‘확인’을 누르세요.
직접 해보기
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local enemies = workspace.Enemies
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)
print("Base: " .. 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
-- 한 웨이브: 적을 하나씩 내보낸 뒤 모두 사라질 때까지 기다림
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
Roblox 게임: 타워 디펜스의 모든 레슨
직접 연습해 보세요: Roblox 플레이그라운드