이전 튜토리얼에서는 사라지는 플랫폼과 치명적인 용암 등 다양한 경험 기능을 만들었습니다. 이번 튜토리얼에서는 사용자가 생존하는 동안 누가 가장 오래 버티는지를 확인할 수 있는 플레이 가능한 경험으로 이 모든 것을 연결합니다. 사용자가 생존하는 매 초마다 점수가 추가됩니다.
설정하기
먼저 경험을 위한 장면을 설정해야 합니다. 이전 튜토리얼에서 만든 사라지는 플랫폼을 복제하여 사용자가 가능한 한 오랜 시간 동안 플랫폼 보드에 머물도록 경합하게 하세요.
또한 치명적인 용암을 사용하여 사용자가 플랫폼에서 떨어질 때 죽게 하거나, 그냥 그들이 멸망하는 대로 두어도 됩니다. 사용자가 플랫폼에 점프하여 플레이를 시작할 수 있도록 SpawnLocation을 적당한 곳에 배치하세요.

플레이어 점수
Roblox에는 사용자 통계를 표시하기 위한 기본 제공 리더보드가 있습니다. 리더보드를 통해 플레이어 점수를 설정하면, 해당 점수가 경험의 오른쪽 화면에 표시됩니다.

향후 튜토리얼에서 더 많은 사용자 정의 가능 정보를 표시하는 방법을 배우겠지만, 리더보드는 Roblox에서 시각적인 점수 시스템을 만드는 가장 간단한 방법입니다.
경험의 상태를 설정하는 스크립트는 ServerScriptService에 배치하는 것이 좋습니다. 이렇게 하면 경험이 시작될 때 자동으로 실행됩니다. ServerScriptService에 SetupPoints라는 스크립트를 만듭니다.

플레이어 감지하기
Roblox에서 서비스는 다양한 유용한 기능을 수행하는 개체입니다. Players 서비스에는 경험에 참가하는 각 사용자에 대한 점수를 설정하는 데 사용할 수 있는 PlayerAdded라는 이벤트가 있습니다.
GetService 함수를 사용하여 game 개체에서 서비스를 접근할 수 있습니다. game은 경험 안에 있는 모든 것을 포함하는 변수로, 어디서나 접근 가능합니다.
game:GetService("Players")를 사용하여 Players 서비스의 변수를 생성합니다.
들어오는 플레이어에 대한 매개변수를 가진 onPlayerAdded라는 함수를 생성합니다.
onPlayerAdded 함수를 PlayerAdded 이벤트에 연결합니다.
local Players = game:GetService("Players")local function onPlayerAdded(player)endPlayers.PlayerAdded:Connect(onPlayerAdded)
통계 폴더 만들기
사용자의 점수를 리더보드에 표시하려면 사용자의 Player 개체에 "leaderstats"라는 새 Folder를 만들어야 하며, 그 안에 점수를 넣으면 됩니다. 새 개체는 Instance.new() 함수를 통해 스크립트 내에서 생성할 수 있습니다.
Instance.new("Folder")를 사용하여 새 Folder 개체를 만들고, 결과를 leaderstats라는 새 변수에 저장합니다.
local function onPlayerAdded(player)local leaderstats = Instance.new("Folder")endleaderstats의 Name 속성을 "leaderstats"로 설정합니다.
leaderstats를 player에 첨부합니다.
local Players = game:GetService("Players")local function onPlayerAdded(player)local leaderstats = Instance.new("Folder")leaderstats.Name = "leaderstats"leaderstats.Parent = playerendPlayers.PlayerAdded:Connect(onPlayerAdded)
점수 만들기
리더보드 시스템은 leaderstats 폴더의 값들을 읽고 찾은 내용을 표시합니다.
플레이어의 점수를 추적할 통계를 추가하기 위해, leaderstats 폴더에 새 IntValue 개체를 부모로 할 수 있습니다. 값 개체의 이름은 현재 값과 함께 표시됩니다.
- Name을 "Points"로 설정합니다.
- Value를 0으로 설정합니다. 이것이 리더보드에 플레이어를 위해 처음 표시될 값입니다.
- points 개체를 leaderstats 폴더에 첨부합니다.
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
end
Players.PlayerAdded:Connect(onPlayerAdded)경험을 시험해보면 오른쪽 위에 리더보드가 나타나며 사용자 이름과 함께 점수도 나올 것입니다.
시간 계산하기
각 사용자는 생존하는 매 초마다 점수를 얻어야 합니다. while 루프와 task.wait() 함수를 사용하여 매초마다 점수 값을 업데이트할 수 있습니다.
- 스크립트의 끝에 true를 조건으로 사용하는 while 루프를 만듭니다.
- 루프 내에서 task.wait()를 사용하여 1초를 기다립니다.
Players.PlayerAdded:Connect(onPlayerAdded)
while true do
task.wait(1)
end플레이어 목록
경험에 있는 모든 사용자에 대해 코드를 실행하려면 GetPlayers 함수로 반환된 배열을 반복해야 합니다.
배열은 순서대로 저장된 항목 목록입니다. 각 항목은 인덱스 위치를 통해 접근할 수 있으며, 인덱스는 1부터 시작합니다. 배열의 길이를 얻으려면 #로 접두사를 붙이면 됩니다.
- Players:GetPlayers()의 결과를 playerList 변수에 저장합니다.
- 시작값이 1이고 종료값이 #playerList인 for 루프를 생성하여 각 사용자에 대해 한 번의 반복을 수행합니다.
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for currentPlayer = 1, #playerList do
-- Add your logic here for each player in the playerList
end
end점수 부여하기
for 루프에서 각 사용자에게 점수를 부여하려면 배열에서 사용자를 꺼내고 Points 개체에 1을 추가해야 합니다.
배열에 저장된 개체는 대괄호를 사용하여 접근합니다. 예를 들어 playerList 배열의 첫 번째 항목은 playerList[1]로 접근할 수 있습니다. for 루프에서 playerList[currentPlayer]를 쓰면 루프의 매 반복에서 각 사용자에 접근할 수 있습니다.
- playerList[currentPlayer]의 사용자를 player라는 변수에 저장합니다.
- 사용자의 Points 개체를 points라는 변수에 저장합니다.
- Value 속성을 points.Value + 1로 설정합니다.
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for currentPlayer = 1, #playerList do
local player = playerList[currentPlayer]
local points = player.leaderstats.Points
points.Value += 1
end
end경험을 시험해 보세요. 각 초마다 점수가 1씩 누적되는 것을 확인할 수 있을 것입니다.
캐릭터 감지하기
경험의 목표는 누가 가장 오래 생존할 수 있는지를 확인하는 것이므로, 죽은 사용자의 점수를 0으로 재설정해야 합니다.
사용자가 죽었는지 감지하려면 해당 사용자의 Character 모델을 가져와야 합니다. 이 모델은 사용자의 Player 개체가 로드된 후에만 경험에 추가됩니다. CharacterAdded 이벤트를 사용하여 캐릭터가 준비되었을 때를 감지할 수 있습니다. character와 player라는 두 개의 매개변수를 가진 onCharacterAdded라는 함수를 만듭니다.
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")onCharacterAdded 함수의 매개변수에 사용자를 포함했지만, 실제 CharacterAdded 이벤트는 캐릭터만 반환하고 관련 사용자는 포함되지 않습니다. player 개체를 전달하려면 이벤트 연결을 위해 익명 함수를 사용하세요.
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end점수 재설정
사용자가 죽으면 그들의 Humanoid가 자동으로 Died 이벤트를 발생시킵니다. 이 이벤트를 사용하여 점수를 재설정하는 시점을 알 수 있습니다.
Humanoid는 Character 모델 내에 있지만, 해당 모델의 내용은 사용자가 스폰될 때만 조립됩니다. Humanoid 객체가 로드되기를 안전하게 기다리기 위해 WaitForChild() 함수를 사용하실 수 있습니다. 이 함수는 모든 상위 개체에서 호출할 수 있으며, 대기 중인 자식의 문자열 이름을 전달합니다. character:WaitForChild("Humanoid")를 사용하여 Humanoid를 기다릴 변수를 만듭니다.
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
local humanoid = character:WaitForChild("Humanoid")
endDied 이벤트에 연결해야 하는 함수는 매우 짧고 여기서만 필요하므로 익명 함수를 사용할 수 있습니다.
- Humanoid의 Died 이벤트에 새로운 익명 함수를 연결합니다.
- 익명 함수 내에서 사용자의 Points 개체를 위한 변수를 points라고 만듭니다.
- Value 속성을 0으로 설정합니다.
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
end)
end이것을 시험해보면 사용자가 죽을 때 점수가 재설정되는 것을 볼 수 있을 것입니다.
사용자 확인하기
사용자가 죽어도 계속 점수를 얻는다면 경험의 정신에 맞지 않으므로, 코드는 점수를 부여하기 전에 사용자가 생존하고 있는지를 확인할 필요가 있습니다.
이제 onPlayerAdded 함수에 사용자가 생존하고 있는지 확인할 수 있는 속성을 정의합니다. 이때 사용자는 아직 생존하지 않고 스폰되지 않았기 때문에 캐릭터 모델이 추가되어야 합니다.
속성이란 Roblox에서 객체를 사용자 정의할 수 있는 데이터입니다. 속성은 이름과 값으로 구성됩니다. SetAttribute 함수를 사용하여 임의의 객체에 속성을 생성할 수 있습니다. SetAttribute를 player에 호출하여 새 속성인 "IsAlive"를 false로 설정합니다.
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player:SetAttribute("IsAlive", false)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end사용자의 캐릭터 모델이 스폰될 때 값이 IsAlive는 true로 변경되어 사용자가 다시 점수를 얻기 시작할 수 있도록 해야합니다.
- onCharacterAdded에서 player의 IsAlive 속성을 true로 설정합니다.
- onCharacterDied에서 player의 IsAlive 속성을 false로 설정합니다.
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
player:SetAttribute("IsAlive", true)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
player:SetAttribute("IsAlive", false)
end)
end마지막으로 IsAlive를 점수를 부여하기 전에 스크립트 끝의 while 루프에서 확인해야 합니다. GetAttribute 함수는 속성의 이름을 인자로 받아 값을 반환합니다. while 루프 내에서 점수를 부여하는 코드를 if 문으로 감싸고 조건을 player:GetAttribute("IsAlive")로 설정합니다.
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for currentPlayer = 1, #playerList do
local player = playerList[currentPlayer]
if player:GetAttribute("IsAlive") then
local points = player.leaderstats.Points
points.Value += 1
end
end
end이제 경험을 시험해보면 사용자가 생존하는 매 초마다 점수를 얻고, 죽어있는 동안은 0으로 유지되는 것을 확인할 수 있습니다. 친구들과 함께 플레이하여 누가 가장 높은 점수를 얻는지 확인해보세요.
이것은 단지 시작일 뿐입니다. 사용자의 경험을 계속 개선할 수 있습니다. 몇 가지 팁은 다음과 같습니다:
- 모든 플랫폼에 대한 코드를 하나의 스크립트에 배치하여 업데이트를 훨씬 더 쉽게 만드세요.
- 사용자가 경험 영역으로 전송되기를 기다리는 로비 공간을 만드세요. 이를 통해 사용자가 동시에 시작할 수 있습니다.
- 각 라운드의 승자를 발표하세요.
최종 코드
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
player:SetAttribute("IsAlive", true)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
player:SetAttribute("IsAlive", false)
end)
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player:SetAttribute("IsAlive", false)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for i = 1, #playerList do
local player = playerList[i]
if player:GetAttribute("IsAlive") then
local points = player.leaderstats.Points
points.Value += 1
end
end
end