업그레이드 버튼 스크립트

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.


플레이어는 이제 동전을 수집하고 죽을 때 동전을 잃게 되지만, 동전은 아무런 기능이 없으며, 매우 높이 점프할 수 있는 능력이 없으면 대부분의 3D 세계에 접근할 수 없습니다. 이 튜토리얼의 이 섹션에서는 동전을 사용하여 점프 능력을 증가시키는 화면 버튼을 추가하여 게임의 논리를 완성하는 방법을 배웁니다.

업그레이드 버튼 만들기

Roblox의 2D 인터페이스는 일반적으로 GUI 컨테이너 내부의 GUI 구성 요소 모음으로 구성됩니다. 이 경우, TextButton 구성 요소가 필요하며, 그 안에 "점프 업그레이드 (5 동전)"이라고 적혀 있어야 합니다. 이 구성 요소는 ScreenGui 컨테이너 안에 위치해야 합니다.

업그레이드 GUI 설정
ReplicatedStorage에 Instances라는 이름의 폴더를 만듭니다.
Instances 폴더 안에 ResetOnSpawn이 비활성화된 JumpPurchaseGui라는 이름의 ScreenGui를 만듭니다.
JumpPurchaseGui 안에 JumpButton이라는 이름의 TextButton을 만들고 다음 속성을 설정합니다:
- Text: "점프 업그레이드 (5 동전)"
- TextSize: 25
- AnchorPoint: 1, 1
- Position: {1, 0}, {1, 0}
Instances 폴더 안에 IncreaseJumpPowerFunction이라는 이름의 RemoteFunction을 만듭니다.
마지막으로, StarterPlayer 서비스에서 CharacterUseJumpPower 속성을 활성화합니다.

점프 파워 데이터 정의

현재 PlayerData 모듈 스크립트에는 각 플레이어의 동전 수만 저장됩니다. 점프 파워도 같은 방식으로 저장하고 업데이트해야 합니다. PlayerData의 함수는 변경되는 데이터에 비특정적이므로, 플레이어 점프 파워를 저장하기 위해 Jump 키를 추가하고 defaultPlayerData()에서 초기 값을 설정하기만 하면 됩니다.

점프 파워로 PlayerData 업데이트
ServerStorage에서 기존 PlayerData ModuleScript의 코드를 다음으로 교체합니다:
```lua
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
PlayerData.JUMP_KEY_NAME = "Jump"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number,
["Jump"] = jumpPower: number
}
--]]
}
local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0,
[PlayerData.JUMP_KEY_NAME] = 0,
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
playerData[tostring(player.UserId)] = data
return data
end
function PlayerData.getValue(player, key)
return getData(player)[key]
end
function PlayerData.updateValue(player, key, updateFunction)
local data = getData(player)
local oldValue = data[key]
local newValue = updateFunction(oldValue)
data[key] = newValue
return newValue
end
return PlayerData
```

점프 파워 데이터 업데이트

이제 PlayerData가 점프 파워를 추적할 수 있게 되었으므로, 플레이어의 클라이언트 요청으로부터 점프 파워를 업그레이드하는 서버의 논리를 구현해야 합니다.

서버와 클라이언트는 RemoteEvents 또는 RemoteFunctions를 통해 통신할 수 있습니다. RemoteEvent는 발사될 때 대기하지 않으며 일방향 통신에 사용할 수 있습니다. 반면, RemoteFunction은 응답을 받을 때까지 대기하므로 양방향 통신이 가능합니다.

이 튜토리얼에서는 클라이언트가 서버가 플레이어의 점프 파워를 성공적으로 업그레이드했는지 알아야 하므로, RemoteFunction을 사용해야 합니다.

JumpService 생성
ServerScriptService에서 JumpService라는 이름의 스크립트를 만들고 다음 코드를 추가합니다:
```lua
-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Modules
local Leaderboard = require(ServerStorage.Leaderboard)
local PlayerData = require(ServerStorage.PlayerData)
-- Events
local IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunction
local JUMP_KEY_NAME = PlayerData.JUMP_KEY_NAME
local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
local JUMP_POWER_INCREMENT = 30
local JUMP_COIN_COST = 5
local function updateJumpPower(player, updateFunction)
-- 점프 파워 테이블 업데이트
local newJumpPower = PlayerData.updateValue(player, JUMP_KEY_NAME, updateFunction)
-- 플레이어의 점프 파워 업데이트
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.JumpPower = newJumpPower
-- 점프 리더보드 업데이트
Leaderboard.setStat(player, JUMP_KEY_NAME, newJumpPower)
end
end
local function onPurchaseJumpIncrease(player)
local coinAmount = PlayerData.getValue(player, COIN_KEY_NAME)
if coinAmount < JUMP_COIN_COST then
return false
end
-- 플레이어의 점프 파워 증가
updateJumpPower(player, function(oldJumpPower)
oldJumpPower = oldJumpPower or 0
return oldJumpPower + JUMP_POWER_INCREMENT
end)
-- 동전 테이블 업데이트
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, function(oldCoinAmount)
return oldCoinAmount - JUMP_COIN_COST
end)
-- 동전 리더보드 업데이트
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
return true
end
local function onCharacterAdded(player)
-- 캐릭터가 추가될 때 플레이어의 점프 파워 초기화
updateJumpPower(player, function(_)
return 0
end)
end
-- PlayerAdded 이벤트에 연결하기 전에 추가된 플레이어 초기화
for _, player in Players:GetPlayers() do
onCharacterAdded(player)
end
-- PlayerAdded 이벤트에서 플레이어를 정상적으로 초기화
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function()
onCharacterAdded(player)
end)
end
local function onPlayerRemoved(player)
updateJumpPower(player, function(_)
return nil
end)
end
IncreaseJumpPowerFunction.OnServerInvoke = onPurchaseJumpIncrease
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)
```

다음 섹션에서는 코드를 더 자세히 설명합니다.

  • 점프 파워 데이터 업데이트 - updateJumpPower()는 플레이어의 점프 파워와 리더보드를 업데이트하여 시각적 피드백을 제공합니다. 이 함수는 플레이어 위험 만들기에서 플레이어에게 피해를 주는 코드와 유사합니다. Character 모델과 Humanoid가 업그레이드되는 플레이어에 대해 존재하는 경우, 이 함수는 PlayerData에 저장된 새 값으로 JumpPower 속성을 업데이트하여 30만큼 증가시킵니다. 게임이 조금 더 오래 지속되기를 원한다면 이 숫자를 줄일 수 있습니다.

  • 서버 요청 검증 - onPurchaseJumpIncrease()는 먼저 플레이어가 업그레이드를 구매하는 데 필요한 동전 수를 실제로 가지고 있는지 확인합니다. 클라이언트에서 서버로의 모든 요청은 나쁜 행위자가 잘못된 요청을 제출하고 게임을 악용하는 것을 방지하기 위해 검증되어야 합니다.

플레이어 GUI에 버튼 추가

ScreenGui 객체는 플레이어의 PlayerGui 객체에 부모가 되어야만 화면에 표시됩니다. 기본적으로 여기에는 채팅 창과 같은 시스템 GUI가 포함됩니다. 이제 ReplicatedStorage에 스크립트를 만들어 각 플레이어의 GUI에 업그레이드 버튼을 복사하고 버튼이 눌렸을 때의 동작을 구현해야 합니다.

JumpButtonClickHandler 생성
ReplicatedStorage에 JumpButtonClickHandler라는 이름의 스크립트를 만들고 RunContext를 Client로 설정한 후 다음 코드를 추가합니다:
```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local playerGui = player.PlayerGui
local IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunction
local jumpPurchaseGui = ReplicatedStorage.Instances.JumpPurchaseGui
local jumpButton = jumpPurchaseGui.JumpButton
local function onButtonClicked()
local success, purchased = pcall(IncreaseJumpPowerFunction.InvokeServer, IncreaseJumpPowerFunction)
if not success then
-- purchased는 성공이 false일 경우 오류 메시지가 됩니다
error(purchased)
elseif success and not purchased then
warn("동전이 부족합니다!")
end
end
jumpButton.Activated:Connect(onButtonClicked)
-- JumpPurchaseGui를 플레이어의 Gui에 추가합니다
jumpPurchaseGui.Parent = playerGui
```

다음 섹션에서는 코드를 더 자세히 설명합니다.

  • GUI 및 서버 함수에 대한 참조 얻기 - 변수 IncreaseJumpPowerFunction, jumpPurchaseGui, 및 jumpButton은 나중에 필요할 함수와 GUI에 대한 참조를 포함합니다.
  • 이벤트 핸들러 정의 - onButtonClicked()는 사용자가 업그레이드 버튼을 클릭할 때의 논리를 정의합니다. pcall() (보호된 호출)을 사용하여 RemoteFunction을 호출합니다. 이와 같은 클라이언트-서버 통신은 오류나 연결 문제를 처리하기 위해 pcall()이 필요합니다.
  • 버튼에 핸들러 연결 - Activated 이벤트는 마우스, 터치스크린 또는 게임패드 컨텍스트를 포함한 모든 플랫폼에서 호환됩니다. 클릭, 터치 또는 게임패드 버튼이 해제될 때 트리거됩니다.

플레이테스트

드롭다운에서 Test를 선택하고 Play를 클릭합니다. 점프 업그레이드 버튼이 오른쪽 하단에 나타납니다.

동전을 수집하기 전에 버튼을 클릭하여 추가 점프 파워를 부여하지 않는지 확인한 다음, 동전을 수집하고 다시 클릭할 때 업그레이드가 작동하는지 확인합니다.

코드가 완성되었으므로 난이도를 조정해 보세요: 속도가 느리게 느껴지면 동전을 추가하고, 업그레이드가 너무 쉽게 이루어지면 몇 개를 제거하고 더 어려운 위치에 숨겨 보세요.

©2026 Roblox Corporation. Roblox 및 Roblox 로고, 'Powering Imagination'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.