승리 기록 저장하기
Coddy의 Roblox 게임: 재난 생존 코스 레슨. 18개 중 17번째.
현재 플레이어가 떠나면 승리 횟수가 사라집니다. DataStore는 방문 사이에 Roblox 서버에 데이터를 보관합니다. 각 값은 키 아래에 저장되며, 플레이어의 UserId는 보통 키로 사용됩니다. 이 값은 절대 바뀌지 않기 때문입니다.
local winsStore = DataStoreService:GetDataStore("Wins")
winsStore:SetAsync(player.UserId, 12)
print(winsStore:GetAsync(player.UserId)) --> 12DataStore 호출은 네트워크를 통해 이루어지므로 실패할 수 있고, 오류가 게임을 중단시켜서는 안 됩니다. 따라서 각 호출은 함수 실행 결과를 오류를 발생시키는 대신 성공 여부로 알려주는 pcall로 감쌉니다.
local ok, saved = pcall(function()
return winsStore:GetAsync(player.UserId)
end)플레이어가 떠날 때(PlayerRemoving) 저장하고, 서버가 종료될 때 실행되는 game:BindToClose에서도 저장하세요. 플레이어가 들어올 때 데이터를 불러오세요. Roblox Studio에서는 플레이스가 게시되고 Enable Studio Access to API Services가 켜져 있으면 DataStore를 사용할 수 있습니다.
챌린지
어려움Wins를 저장해 유지하세요:
- 상단 부분에
DataStoreService를 가져오고Wins라는 이름의 DataStore를 만드세요. - PlayerAdded에서 leaderstats를 만든 다음, pcall 안에서
GetAsync(player.UserId)를 사용해 저장된 Wins를 불러오고, 호출이 성공하고 값이 있으면 그 값을 사용하세요. - pcall 안에서
SetAsync를 사용해 Wins를 저장하는saveWins(player)를 작성하고,PlayerRemoving이 발생할 때와game:BindToClose에서 각 플레이어에 대해 호출하세요.
Play를 눌러 라운드에서 승리한 다음, Stop을 누르고 다시 Play를 누르세요. Wins가 복원됩니다. 그런 다음 Check를 누르세요.
직접 해보기
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")
local Settings = require(game.ReplicatedStorage.Settings)
local lobbySpawn = workspace.LobbySpawn
print("Rounds last " .. Settings.RoundLength .. " seconds")
-- 모든 플레이어의 리더보드에 Wins와 Streak가 표시됩니다
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local wins = Instance.new("IntValue")
wins.Name = "Wins"
wins.Parent = leaderstats
local streak = Instance.new("IntValue")
streak.Name = "Streak"
streak.Parent = leaderstats
end)
-- 로비에 있는 상태 표시판
local gui = Instance.new("SurfaceGui")
gui.Parent = workspace.StatusBoard
local status = Instance.new("TextLabel")
status.Name = "Status"
status.Size = UDim2.fromScale(1, 1)
status.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
status.TextColor3 = Color3.fromRGB(255, 255, 255)
status.TextScaled = true
status.Text = "Welcome to Disaster Survival!"
status.Parent = gui
local function setStatus(text)
status.Text = text
end
local function teleport(player, target)
local character = player.Character
if character then
character:PivotTo(target.CFrame + Vector3.new(0, 4, 0))
end
end
local function defeat(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
humanoid.Health = 0
end
end
-- 플레이어의 머리 위에 떠 있는 "Survivor" 태그
local function tagSurvivor(character)
local tag = Instance.new("BillboardGui")
tag.Name = "SurvivorTag"
tag.Size = UDim2.fromOffset(120, 30)
tag.StudsOffset = Vector3.new(0, 2.5, 0)
tag.Parent = character.Head
local label = Instance.new("TextLabel")
label.Size = UDim2.fromScale(1, 1)
label.BackgroundTransparency = 1
label.Text = "Survivor"
label.TextColor3 = Color3.fromRGB(80, 255, 120)
label.TextScaled = true
label.Parent = tag
end
-- 이름별 재난
local Disasters = {}
function Disasters.Flood(map)
local base = map.Base
local water = Instance.new("Part")
water.Name = "Water"
water.Anchored = true
water.CanCollide = false
water.Transparency = 0.3
water.Color = Color3.fromRGB(40, 120, 255)
water.Size = Vector3.new(base.Size.X + 10, 1, base.Size.Z + 10)
water.Position = base.Position - Vector3.new(0, 2, 0)
water.Parent = map
water.Touched:Connect(defeat)
local rise = TweenInfo.new(Settings.RoundLength * 0.8, Enum.EasingStyle.Linear)
TweenService:Create(water, rise, { Position = water.Position + Vector3.new(0, 8, 0) }):Play()
end
function Disasters.Meteors(map)
local base = map.Base
task.spawn(function()
while map.Parent do
local meteor = Instance.new("Part")
meteor.Name = "Meteor"
meteor.Shape = Enum.PartType.Ball
meteor.Size = Vector3.new(3, 3, 3)
meteor.Color = Color3.fromRGB(255, 120, 30)
meteor.Material = Enum.Material.Neon
local x = base.Position.X + math.random(-15, 15)
local z = base.Position.Z + math.random(-15, 15)
meteor.Position = Vector3.new(x, 40, z)
meteor.Parent = map
meteor.Touched:Connect(defeat)
Debris:AddItem(meteor, 4)
task.wait(0.5)
end
end)
end
function Disasters.Shrink(map)
local base = map.Base
local shrink = TweenInfo.new(Settings.RoundLength * 0.7, Enum.EasingStyle.Linear)
TweenService:Create(base, shrink, { Size = Vector3.new(6, base.Size.Y, 6) }):Play()
end
local function pickDisaster()
if Settings.Disaster then
return Settings.Disaster
end
local names = {}
for name in Disasters do
table.insert(names, name)
end
table.sort(names)
return names[math.random(1, #names)]
end
local function pickMap()
local maps = ServerStorage.Maps
if Settings.Map then
return maps:FindFirstChild(Settings.Map)
end
local all = maps:GetChildren()
return all[math.random(1, #all)]
end
-- 라운드 반복문
while true do
for seconds = Settings.Intermission, 1, -1 do
setStatus("Intermission: " .. seconds)
task.wait(1)
end
local template = pickMap()
local map = template:Clone()
map.Name = "Map"
map.Parent = workspace
setStatus("Map: " .. template.Name)
local survivors = {}
for _, player in Players:GetPlayers() do
local character = player.Character
if character and character.Humanoid.Health > 0 then
teleport(player, map.Spawn)
tagSurvivor(character)
survivors[player] = true
character.Humanoid.Died:Connect(function()
survivors[player] = nil
player.leaderstats.Streak.Value = 0
end)
end
end
task.wait(2)
local disaster = pickDisaster()
Disasters[disaster](map)
for seconds = Settings.RoundLength, 1, -1 do
setStatus(disaster .. "! Time left: " .. seconds)
task.wait(1)
end
local names = {}
for player in survivors do
player.leaderstats.Wins.Value += 1
player.leaderstats.Streak.Value += 1
local tag = player.Character and player.Character.Head:FindFirstChild("SurvivorTag")
if tag then
tag:Destroy()
end
teleport(player, lobbySpawn)
table.insert(names, player.Name)
end
map:Destroy()
if #names > 0 then
setStatus("Winners: " .. table.concat(names, ", "))
else
setStatus("Nobody survived!")
end
task.wait(3)
end
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.