RobloxStudioでEキーを押してアイテムを拾う方法

Roblox Studioでアイテムを配置したものの、「近づいたらEキーを表示したい」「キーを押したプレイヤーだけにアイテムを渡したい」と悩んでいませんか?

Touchedを使えば、Partへ触れた瞬間に取得させることはできます。
しかし、宝箱を開ける、NPCへ話しかける、落ちているアイテムを拾うといった場面では、プレイヤー自身に操作してもらう方が自然です。

このような「近づいてボタンを押す」操作には、Roblox標準のProximityPromptが適しています。
PCだけでなく、スマートフォンやゲームパッドにも対応しやすいことが特徴です。

目次

この記事で解決できること

この記事では、黄色いアイテムへ近づいてEキーを押すと、そのアイテムを取得できる仕組みを作ります。

  • アイテムへ近づくと「E 拾う」と表示する
  • PC、スマートフォン、ゲームパッドから操作できる
  • 取得数をPlayer内のInventoryへ記録する
  • 同じアイテムの二重取得を防ぐ
  • サーバー側で距離とプレイヤーの状態を確認する

コードはPartの中へ置く通常のScriptだけで動きます。RemoteEventやLocalScriptは使用しません。

完成後の状態

プレイヤーがアイテムから10 studs以内へ近づくと、対象名と「拾う」という操作案内が表示されます。PCではEキー、スマートフォンでは画面上のPrompt、ゲームパッドでは設定したボタンで取得できます。

取得に成功するとアイテムがマップから消え、操作したPlayerの中へ次のデータが作られます。

Player
└─ Inventory(Folder)
   └─ Star(IntValue)= 1

この完成例では、1つのアイテムを最初に拾ったプレイヤーだけが取得します。
全プレイヤーが個別に拾える方式ではなく、サーバー内で共有されるアイテムです。

ProximityPromptとは

ProximityPromptは、3D空間にあるPart、Attachment、またはPrimaryPartを設定したModelの近くへ操作案内を表示するためのオブジェクトです。

プロパティ役割
ActionText「拾う」「開ける」などの操作内容
ObjectText「Star」「宝箱」などの対象名
KeyboardKeyCodePCで操作するキー
GamepadKeyCodeゲームパッドで操作するボタン
HoldDuration長押しが必要な秒数
MaxActivationDistancePromptが表示される最大距離
RequiresLineOfSight対象との間に壁がある場合の表示条件

実装手順

1. アイテムを配置する

Roblox StudioのExplorerでWorkspaceへPartを追加し、名前をPickupItemへ変更します。最終的な構成は次の通りです。

Workspace
└─ PickupItem(Part)
   ├─ ProximityPrompt
   └─ PickupServer(Script)

PickupItemは見つけやすいように、次の設定から始めてください。

プロパティ設定例
Anchoredtrue
CanCollidefalse
Color黄色
MaterialNeon

2. ProximityPromptを追加する

PickupItemの「+」を押し、ProximityPromptを追加します。
Propertiesは次のように設定します。

プロパティ設定値
ActionText拾う
ObjectTextStar
KeyboardKeyCodeE
GamepadKeyCodeButtonX
HoldDuration0
MaxActivationDistance10
RequiresLineOfSightfalse

HoldDuration0なら、キーを押した時点で取得します。
たとえば1へ変更すると、1秒間長押ししたときだけ取得する操作になります。

3. アイテム名をAttributeへ設定する

PickupItemを選択し、PropertiesのAttributesからString型のAttributeを追加します。

名前: ItemName
値: Star

鍵ならKey、宝石ならGemのように値を変えられます。
Attributeが未設定の場合は、Part名のPickupItemがアイテム名として使われます。

4. 完成コードを追加する

PickupItemの中へ通常のScriptを追加し、名前をPickupServerへ変更します。
最初から入っているコードを削除し、以下を貼り付けてください。

local item = script.Parent
local prompt = item:WaitForChild("ProximityPrompt")

local EXTRA_DISTANCE = 3
local collected = false

local function getInventory(player)
	local inventory = player:FindFirstChild("Inventory")

	if not inventory then
		inventory = Instance.new("Folder")
		inventory.Name = "Inventory"
		inventory.Parent = player
	end

	return inventory
end

local function isPlayerCloseEnough(player)
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	local rootPart = character and character:FindFirstChild("HumanoidRootPart")

	if not humanoid or humanoid.Health <= 0 or not rootPart then
		return false
	end

	local distance = (rootPart.Position - item.Position).Magnitude
	return distance <= prompt.MaxActivationDistance + EXTRA_DISTANCE
end

local function getItemName()
	local itemName = item:GetAttribute("ItemName")

	if typeof(itemName) == "string" and itemName ~= "" then
		return itemName
	end

	return item.Name
end

local function addItem(player, itemName)
	local inventory = getInventory(player)
	local itemCount = inventory:FindFirstChild(itemName)

	if itemCount and not itemCount:IsA("IntValue") then
		warn(itemName .. " と同じ名前のIntValue以外が存在します")
		return false
	end

	if not itemCount then
		itemCount = Instance.new("IntValue")
		itemCount.Name = itemName
		itemCount.Value = 0
		itemCount.Parent = inventory
	end

	itemCount.Value += 1
	return true
end

prompt.Triggered:Connect(function(player)
	if collected or not prompt.Enabled then
		return
	end

	if not isPlayerCloseEnough(player) then
		warn(player.Name .. " はアイテムから離れすぎています")
		return
	end

	collected = true
	prompt.Enabled = false

	local itemName = getItemName()
	local added = addItem(player, itemName)

	if not added then
		collected = false
		prompt.Enabled = true
		return
	end

	print(player.Name .. " が " .. itemName .. " を取得しました")
	item:Destroy()
end)

5. Playで動作を確認する

  1. Studio上部のPlayを押します。
  2. 黄色いアイテムへ近づきます。
  3. 「E 拾う」と表示されたらEキーを押します。
  4. アイテムが消えることを確認します。
  5. ExplorerでPlayer内にInventory > Star = 1が作られたことを確認します。

スマートフォン表示はStudioのTestタブにあるDevice Emulatorで確認できます。
画面上に表示されたPromptをタップし、同じように取得できれば成功です。

コードの仕組み

Triggeredで操作したPlayerを受け取る

prompt.Triggered:Connect(function(player)

Triggeredは、指定されたキーやボタンでPromptが操作されたときに発生するイベントです。サーバー側のScriptでは、操作したPlayerを引数として受け取れます。

距離と生存状態をサーバー側でも確認する

local distance = (rootPart.Position - item.Position).Magnitude
return distance <= prompt.MaxActivationDistance + EXTRA_DISTANCE

プレイヤーのHumanoidRootPartとアイテムの座標差から距離を求めています。
また、Humanoidが存在し、Healthが0より大きいことも確認します。

Robloxの公式資料では、Triggeredにはサーバー側の距離確認がある一方、クライアントから開始される操作ではサーバー側でも条件を検証することが推奨されています。アイテムや報酬を渡す直前に、距離やプレイヤーの状態を確認すると、意図しない取得を防ぎやすくなります。

EXTRA_DISTANCE = 3は、通信遅延やキャラクターの大きさを考慮した3 studsの余裕です。
広すぎると遠くから取得できるため、実際のゲームで操作感を確認して調整してください。

Inventoryへ取得数を記録する

Playerの中にInventory Folderを作り、アイテム名と同じIntValueへ取得数を保存します。
同じ名前のIntValueがすでにあれば、Valueへ1を加算します。

ここで作った値は、現在プレイしているサーバー内だけのデータです。
プレイヤーがゲームから退出すると消えるため、次回も所持数を残すにはDataStoreを追加する必要があります。

二重取得を防ぐ

if collected or not prompt.Enabled then
	return
end

collected = true
prompt.Enabled = false

collectedがtrueなら処理を終了します。
取得処理を始めると同時にPromptも無効化するため、2人がほぼ同時に操作した場合の二重取得を防げます。

動かない場合の対処

「E 拾う」が表示されない

  • ProximityPromptPickupItemの中にあるか確認する
  • Enabledがtrueになっているか確認する
  • MaxActivationDistanceが小さすぎないか確認する
  • 壁越しの場合はRequiresLineOfSightを一度falseにして確認する

Eキーを押してもアイテムが消えない

PickupServerがLocalScriptではなく、通常のScriptになっているか確認してください。
Scriptの親はPickupItemです。また、ViewタブからOutputを開き、赤いエラーが表示されていないか確認します。

「ProximityPrompt is not a valid member」と表示される

Explorer上の名前がProximityPromptと完全に一致しているか確認します。
スペルや大文字・小文字が違うと、コードから見つけられません。

取得したのにInventoryが見つからない

Play中のExplorerでPlayersを開き、その中にある自分のPlayerを確認してください。
編集画面のStarterPlayerには作成されません。

壁の向こうから操作できてしまう

RequiresLineOfSightをtrueへ変更します。障害物の判定をさらに厳密にしたい場合は、サーバー側でRaycastを行い、プレイヤーとアイテムの間に壁がないことを確認します。

次に起きる悩みと関連記事

アイテムを拾えるようになると、次は「取得数を画面へ表示したい」「退出後も所持数を残したい」「一定時間後にアイテムを復活させたい」という悩みが出てきます。

  • 画面へ表示する: ScreenGuiとTextLabelを使う
  • 退出後も保存する: DataStoreServiceを使う
  • アイテムを復活させる: 取得後に一定時間待ってCloneを配置する
  • 複数のPromptを管理する: ProximityPromptServiceへ処理をまとめる

まとめ

ProximityPromptを使うと、PC、スマートフォン、ゲームパッドに対応した「近づいて操作する」仕組みを少ないコードで作れます。

重要なのは、Promptの表示だけに任せず、アイテムを渡す直前にサーバー側でも距離、プレイヤーの状態、二重取得を確認することです。まずはStarを1つ配置して動作を確認し、問題なく拾えたら鍵や宝箱へ応用してみてください。

関連記事

参考資料

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

現役のゲーム会社サーバーエンジニア。

HTML・CSS・JavaScript、PHP・MySQL、Robloxを使い、初心者でも実際に動かせるゲーム制作・プログラミング記事を執筆しています。

掲載コードは公開前に動作確認し、完成コードだけでなく「なぜ動くのか」「どこでつまずきやすいか」まで解説します。

Google Cloud Professional Cloud Architect取得。

コメント

コメントする

目次