0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PlayerNameUIの作り方

0
Posted at

【Roblox】頭の上にプレイヤー名とデバイスアイコンを表示する「PlayerNameUI」の作り方

プレイヤーの頭上に DisplayName、ユーザーネーム、および利用デバイス(PC / モバイル / タブレット / コンソール等)のアイコンを表示するUIの作成手順です。


1. RemoteEventの作成

  1. ReplicatedStorage 内に RemoteEvent を追加します。
  2. 名前を 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(出力) ウィンドウに赤文字のエラーが出ていないか確認してください。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?