【Roblox】頭の上にプレイヤー名とデバイスアイコンを表示する「PlayerNameUI」の作り方
プレイヤーの頭上に DisplayName、ユーザーネーム、および利用デバイス(PC / モバイル / タブレット / コンソール等)のアイコンを表示するUIの作成手順です。
1. RemoteEventの作成
-
ReplicatedStorage内にRemoteEventを追加します。 - 名前を
PlatformEventに変更してください。
2. サーバー側スクリプト(Script)の作成
ServerScriptService に新しい Script を作成し、以下のコードを貼り付けます。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local platformEvent = ReplicatedStorage:WaitForChild("PlatformEvent")
-- プレイヤーごとのOS名をサーバー側で保存しておくためのテーブル(辞書)
local playerOSMap = {}
-- 【設定】デバイス名に応じた画像(Asset ID)のテーブル
local DEVICE_ICONS = {
["Windows/Mac/Linux"] = 12684119292, -- 数値(数字のみ)で指定します
["Chromebook/2-in-1 PC"] = 12684119292,
["Smartphone"] = 71335945608045,
["Tablet"] = 132361591008690,
["Console"] = 4728059087,
["Unknown"] = 696413141
}
-- 頭の上にBillboardGuiを作成・設置する関数
local function addBillboardGuiToHead(player, osName)
local character = player.Character
if not character then return end
local head = character:WaitForChild("Head", 5)
if not head then return end
-- 既存の古いGUIがあれば削除
if head:FindFirstChild("PlayerNameGui") then
head.PlayerNameGui:Destroy()
end
-- 1. 土台となるBillboardGuiの作成
local billboardGui = Instance.new("BillboardGui")
billboardGui.Name = "PlayerNameGui"
billboardGui.Size = UDim2.new(0, 300, 0, 50)
billboardGui.StudsOffset = Vector3.new(0, 2, 0)
billboardGui.Parent = head
billboardGui.MaxDistance = 50
-- 2. パーツを横並びにするための「コンテナ用Frame」を作成
local container = Instance.new("Frame")
container.Name = "Container"
container.Size = UDim2.new(1, 0, 1, 0)
container.BackgroundTransparency = 1
container.Parent = billboardGui
-- 3. 自動で「左から右」へ並べるためのUIListLayout
local listLayout = Instance.new("UIListLayout")
listLayout.FillDirection = Enum.FillDirection.Horizontal
listLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
listLayout.VerticalAlignment = Enum.VerticalAlignment.Center
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Padding = UDim.new(0, 8)
listLayout.Parent = container
-- 4. 左側に表示する「画像(ImageLabel)」の作成
local imageLabel = Instance.new("ImageLabel")
imageLabel.Name = "DeviceIcon"
imageLabel.Size = UDim2.new(0, 35, 0, 35)
imageLabel.BackgroundTransparency = 1
imageLabel.LayoutOrder = 1
-- ★【超重要】アセットIDの自動変換システム
local rawId = DEVICE_ICONS[osName] or DEVICE_ICONS["Unknown"]
if rawId then
imageLabel.Image = "rbxthumb://type=Asset&id=" .. tostring(rawId) .. "&w=150&h=150"
end
imageLabel.Parent = container
-- 5. 右側に表示する「文字(TextLabel)」の作成
local textLabel = Instance.new("TextLabel")
textLabel.Name = "PlayerNameLabel"
textLabel.Size = UDim2.new(0, 220, 1, 0)
textLabel.BackgroundTransparency = 1
textLabel.TextXAlignment = Enum.TextXAlignment.Left
textLabel.LayoutOrder = 2
-- テキストを設定
textLabel.Text = player.DisplayName .. " @" .. player.Name .. " (" .. osName .. ")"
textLabel.TextColor3 = Color3.new(1, 1, 1)
textLabel.TextScaled = true
textLabel.Font = Enum.Font.GothamBold
textLabel.Parent = container
-- 文字のフチ取り(UIStroke)
local ServerUi = Instance.new("UIStroke")
ServerUi.Parent = textLabel
ServerUi.Thickness = 3
ServerUi.Color = Color3.new(0, 0, 0)
end
-- クライアントから送られてきた初回OS情報を受け取る
platformEvent.OnServerEvent:Connect(function(player, osName)
-- 1. このプレイヤーのOS情報をテーブルに保存
playerOSMap[player] = osName
-- 2. 現在のキャラクターにGUIを付ける
addBillboardGuiToHead(player, osName)
-- 3. 以降、このプレイヤーがリスポーンするたびに自動で付け直す
player.CharacterAdded:Connect(function(newCharacter)
task.wait(0.1)
local savedOS = playerOSMap[player]
if savedOS then
addBillboardGuiToHead(player, savedOS)
end
end)
end)
-- プレイヤーがゲームを抜けた時は保存データを消去
game:GetService("Players").PlayerRemoving:Connect(function(player)
playerOSMap[player] = nil
end)
3. LocalScript(クライアント側)の作成
StarterPlayer > StarterPlayerScripts 内に新しい LocalScript を作成し、以下のコードを貼り付けます。
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Camera = workspace.CurrentCamera -- 画面サイズ取得用
local platformEvent = ReplicatedStorage:WaitForChild("PlatformEvent")
-- デバイスを推測する関数
local function detectDetailedOS()
-- 1. コンソール(PlayStation / Xbox等)の判定
if GuiService:IsTenFootInterface() then
return "Console"
end
-- 2. モバイル系(タッチ操作のみ)の判定
if UserInputService.TouchEnabled and not UserInputService.MouseEnabled then
-- 画面の「短い方の幅」を取得する
local viewportSize = Camera.ViewportSize
local minDimension = math.min(viewportSize.X, viewportSize.Y)
-- 一般的に、短い方の幅が 600px 以上のデバイスはタブレット(iPad等)に分類されます
if minDimension >= 600 then
return "Tablet"
else
return "Smartphone"
end
end
-- 3. PC系(マウス+キーボード)の判定
if UserInputService.MouseEnabled and UserInputService.KeyboardEnabled then
-- タッチもできるPC = Chromebookや2-in-1ノートPCなど
if UserInputService.TouchEnabled then
return "Chromebook/2-in-1 PC"
end
-- 通常のPC環境
return "Windows/Mac/Linux"
end
-- どのパターンにも当てはまらない場合
return "Unknown"
end
-- 判定を実行してサーバーへ送信
local detectedOS = detectDetailedOS()
platformEvent:FireServer(detectedOS)
動かない場合のチェックリスト
-
RemoteEventの名前-
ReplicatedStorage直下にあり、名前がPlatformEvent(大文字小文字に注意)になっているか確認してください。
-
-
スクリプトの種類
-
ServerScriptService内:通常のScript -
StarterPlayerScripts内:LocalScript
-
-
エラーログ
- Roblox Studio の Output(出力) ウィンドウに赤文字のエラーが出ていないか確認してください。