プレイヤーは現在コインを集め、死ぬとコインを失いますが、コインは何の役にも立たず、ほとんどの3Dワールドには非常に高くジャンプする能力がなければアクセスできません。このチュートリアルのセクションでは、コインを使ってジャンプ力を増加させる画面上のボタンを追加することで、ゲームのロジックを完成させる方法を教えます。
アップグレードボタンを作成する
Robloxの2Dインターフェースは通常、GUIコンテナ内のGUIコンポーネントのコレクションで構成されています。この場合、TextButtonコンポーネントを1つ作成し、「Upgrade Jump (5 Coins)」と表示させ、ScreenGuiコンテナ内に配置します。
ReplicatedStorageに「Instances」という名前のフォルダーを作成します。
Instancesフォルダー内に、ResetOnSpawnを無効にした「JumpPurchaseGui」という名前のScreenGuiを作成します。
JumpPurchaseGui内に、以下のプロパティを持つ「JumpButton」という名前のTextButtonを作成します:
- Text: "Upgrade Jump (5 Coins)"
- TextSize: 25
- AnchorPoint: 1, 1
- Position: {1, 0}, {1, 0}
また、Instancesフォルダー内に「IncreaseJumpPowerFunction」という名前のRemoteFunctionを作成します。
最後に、StarterPlayerサービスでCharacterUseJumpPowerプロパティを有効にします。ジャンプ力データを定義する
現在、各プレイヤーのコイン数のみがPlayerDataモジュールスクリプトに保存されています。ジャンプ力も同様に保存して更新する必要があります。PlayerData内の関数は変更されるデータに特化していないため、プレイヤーのジャンプ力を保存するために必要なのは、Jumpキーを追加し、defaultPlayerData()内でその初期値を初期化することだけです。
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は応答を受け取るまで待機するため、双方向の通信が可能です。
このチュートリアルでは、クライアントがサーバーがプレイヤーのジャンプ力を正常にアップグレードしたかどうかを知る必要があるため、リモート関数を使用するべきです。
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()はプレイヤーのジャンプ力とリーダーボードを更新し、視覚的なフィードバックを提供します。この関数は、Create player hazardsでプレイヤーにダメージを与えるコードに似ています。CharacterモデルとHumanoidがアップグレードされるプレイヤーに存在する場合、この関数はPlayerDataによって保存された新しい値にJumpPowerプロパティを更新し、30増加させます。ゲームを少し長く続けたい場合は、この数値を減らすことができます。
サーバーリクエストの検証 - onPurchaseJumpIncrease()は、プレイヤーがアップグレードを購入するために必要なコインの数を実際に持っているかどうかを最初に確認します。クライアントからサーバーへのすべてのリクエストは、悪意のある行為者が虚偽のリクエストを提出してゲームを悪用するのを防ぐために検証されるべきです。
プレイヤーGUIにボタンを追加する
ScreenGuiオブジェクトは、プレイヤーのPlayerGuiオブジェクトに親子関係がある場合にのみ画面に表示されます。デフォルトでは、これにはチャットウィンドウなどのシステムGUIが含まれています。次に、ReplicatedStorage内にスクリプトを作成して、アップグレードボタンを各プレイヤーのGUIにコピーし、ボタンが押されたときの動作を実装する必要があります。
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)
-- プレイヤーのGuiにJumpPurchaseGuiを追加する
jumpPurchaseGui.Parent = playerGui
```以下のセクションでは、コードをより詳細に説明します。
- GUIとサーバー関数への参照を取得する - 変数IncreaseJumpPowerFunction、jumpPurchaseGui、およびjumpButtonは、後で必要となる関数とGUIへの参照を含んでいます。
- イベントハンドラーを定義する - onButtonClicked()は、ユーザーがアップグレードボタンをクリックしたときのロジックを定義します。pcall()(保護された呼び出し)を使用してRemoteFunctionを呼び出します。このようなクライアント-サーバー通信には、エラーや接続の問題を処理するためにpcall()が必要です。
- ハンドラーをボタンに接続する - Activatedイベントは、マウス、タッチスクリーン、またはゲームパッドのコンテキストを含むすべてのプラットフォームで互換性があります。クリック、タッチ、またはゲームパッドボタンが放されるとトリガーされます。
プレイテスト
ドロップダウンからTestを選択し、Playをクリックします。Upgrade Jumpボタンが右下隅に表示されます。
コインを集める前にボタンをクリックして、追加のジャンプ力が付与されないことを確認し、その後コインを集めて再度クリックしたときにアップグレードが機能するかどうかを確認してください。
コードが完成したら、難易度を調整してみてください:ペースが遅く感じる場合はコインを追加し、アップグレードが簡単すぎる場合はコインをいくつか取り除いて、より難しい場所に隠してください。