🖋️
【Roblox】TopbarPlusを使ってトグルを作ってみた
前書き
こんにちは!ambrでクライアントエンジニアを務めているAgatsumaです。
今年からRobloxのゲーム開発に携わっており、本記事ではTopbarPlusを使ったトグル実装のポイントを紹介します。
はじめに
この記事のゴール
- TopbarPlusでトップバーにアイコンを追加できる
- クリックでUI(Frame)を開閉できる(同じアイコンを再クリックで閉じる)
- 複数アイコンの排他トグル(どれかを開いたら他は閉じる)を実装できる
前提
- クライアント側(LocalScript)で動かします
- TopbarPlusは
ReplicatedStorageに配置してrequireする想定です - (補足)表示の開閉だけなら
Icon.new()で作ったiconに対してicon:bindToggleItem(guiObject)で短く書けます(selected/deselectedでVisibleを切り替えるのと同等)
本題: TopbarPlusを使ってみた
1. TopbarPlusとは
- Robloxのトップバーに Icon(クリック可能な要素) を追加できるUIライブラリ
- 通知バッジやDropdownにも対応
2. 導入方法
- 公式ドキュメントを参考に、Roblox Studio上にTopbarPlusを配置してください
- Packageの自動更新(Get Latest Package等)は、環境によってはエラーになる場合があります
3. 実際のコード
- 以降のコードは説明のために分割しています。動かす場合は、必要な部分だけを1つのLocalScriptにまとめてください
- Icon の配置場所に合わせて require のパスは読み替えてください
3.1 アイコン(ボタン)の生成
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Icon = require(ReplicatedStorage:WaitForChild("Icon"))
local shopIcon = Icon.new()
shopIcon:setImage("rbxassetid://0") -- TODO: 好きな画像IDに差し替え
shopIcon:align("Right") -- 何も書かない場合は Left(デフォルト)。右上に出したい場合は Right
3.2 アイコン画像のスケール調整
- デフォルトだと画像が小さく見えることがあるので、必要に応じて調整します
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Icon = require(ReplicatedStorage:WaitForChild("Icon"))
local shopIcon = Icon.new()
shopIcon:setImage("rbxassetid://0")
shopIcon:setImageScale(1.0) -- デフォルトは 0.5。小さく見える場合は調整
shopIcon:align("Right")
3.3 クリック時(selected)の処理
-
selectedは「選択状態になった」タイミングで発火します(Roblox標準のイベントではなく、ライブラリ固有) -
bindEventのイベント名は camelCase で指定します(例:selected,deselected) - 利用できるイベント一覧(
selected,deselected,toggledなど)は 公式API にまとまっています
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Icon = require(ReplicatedStorage:WaitForChild("Icon"))
local shopIcon = Icon.new()
shopIcon:setImage("rbxassetid://0")
shopIcon:setImageScale(1.0)
shopIcon:align("Right")
shopIcon:bindEvent("selected", function(_icon)
-- TODO: 画面を開くなど
end)
3.4 解除時(deselected)の処理
- TopbarPlusでは、以下のようなケースで
deselectedが呼ばれます- 同じアイコンをもう一度クリックしたとき
- 他のアイコンをクリックして、選択が外れたとき(
autoDeselect(true)の場合)
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Icon = require(ReplicatedStorage:WaitForChild("Icon"))
local shopIcon = Icon.new()
shopIcon:setImage("rbxassetid://0")
shopIcon:setImageScale(1.0)
shopIcon:align("Right")
shopIcon:bindEvent("selected", function(_icon)
-- TODO: 画面を開くなど
end)
shopIcon:bindEvent("deselected", function(_icon)
-- TODO: 画面を閉じるなど
end)
3.5 トグル(開閉)の作り方

- TopbarPlus の
selected/deselectedで、自前UI(Shop など)の表示を切り替えます -
selectedで開き、deselectedで閉じる構成にすると、同じアイコンの再クリックでも自然にトグルできます -
deselectedは再クリックだけでなく、autoDeselect(true)(デフォルトtrue)で他のautoDeselectがtrueのアイコンが押されたときにも呼ばれます - 排他トグルは標準の
autoDeselectでも実現できますが、×ボタンなどで閉じた場合も状態を揃えるため、アイコン参照を保持して必要に応じて:deselect()します
--!strict
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Icon = require(ReplicatedStorage:WaitForChild("Icon"))
local localPlayer = Players.LocalPlayer
local playerGui = localPlayer:WaitForChild("PlayerGui")
-- 自前UI(例)
local screenGui = playerGui:WaitForChild("ScreenGui")
local shopFrame = screenGui:WaitForChild("ShopFrame") :: Frame
local codeFrame = screenGui:WaitForChild("CodeFrame") :: Frame
-- 初期状態:起動時は閉じておく
shopFrame.Visible = false
codeFrame.Visible = false
local ICON_SCALE = 0.9
local ICON_ASSETS = {
Shop = "rbxassetid://0", -- TODO: 好きな画像IDに差し替え
Code = "rbxassetid://0", -- TODO: 好きな画像IDに差し替え
}
-- Topbarアイコン参照(他を閉じるために保持)
type IconType = typeof(Icon.new())
local shopIconRef: IconType? = nil
local codeIconRef: IconType? = nil
-- 他のウィンドウ(=他アイコン)を閉じる
local function closeAllTopbarWindowsExcept(except: string?): ()
if except ~= "Shop" and shopIconRef ~= nil then
shopIconRef:deselect() -- deselected が走るので、閉じ処理はそちらに寄せられる
end
if except ~= "Code" and codeIconRef ~= nil then
codeIconRef:deselect()
end
end
-- Shop アイコン(トグル)
do
local shopIcon = Icon.new()
shopIcon:setImage(ICON_ASSETS.Shop)
shopIcon:setImageScale(ICON_SCALE)
shopIcon:align("Right")
shopIcon:bindEvent("selected", function(_icon)
closeAllTopbarWindowsExcept("Shop")
shopFrame.Visible = true
end)
shopIcon:bindEvent("deselected", function(_icon)
shopFrame.Visible = false
end)
shopIconRef = shopIcon
end
-- Code アイコン(トグル)
do
local codeIcon = Icon.new()
codeIcon:setImage(ICON_ASSETS.Code)
codeIcon:setImageScale(ICON_SCALE)
codeIcon:align("Right")
codeIcon:bindEvent("selected", function()
closeAllTopbarWindowsExcept("Code")
codeFrame.Visible = true
end)
codeIcon:bindEvent("deselected", function()
codeFrame.Visible = false
end)
codeIconRef = codeIcon
end
まとめ
TopbarPlusを実際に使ってみて、個人的に一番大きな収穫だったのは、「トップバーの導線」をきれいに整理できて、UIの切り替えが想像以上にシンプルになったことです。
特に selected / deselected を軸にトグルを組むことで、「同じアイコンをもう一度押したら閉じる」「別のアイコンを押したら前の画面が閉じる」といった自然な体験を、破綻しにくい形で作れました。
今回の実装を踏まえて、今後はDropdownの活用や、通知バッジ・画面遷移時の状態同期なども含めて、より使いやすいUIに育てていきたいです。
最後まで読んでいただき、ありがとうございました!
Discussion