Studio では、カスタムウィジェットを作成し、Studio ツールやエクステンションとして使用することができます。 これらのウィジェットは、Studio のカスタムウィンドウ/パネルとして動作し、インターフェース内にドッキングしたり、別のウィンドウとしてフロートさせたりすることができます。
ウィジェット UI の作成
Studio ウィジェットはすべてDockWidgetPluginGuiオブジェクトとして始まり、テキストラベルやボタンなどのGuiObjectsで埋めることができます。 からのウィジェット GUI を作成するには、CreateDockWidgetPluginGui()関数を呼び出し、ID とDockWidgetPluginGuiInfoオブジェクトをパスします。
DockWidgetPluginGuiInfo.new()コンストラクタは、以下のように特定の順序でパラメータを受け取ることに注意してください:
# | プロパティ | タイプ | 概要 |
---|---|---|---|
1 | Enum.InitialDockState | Enum | Enum.InitialDockState列挙の一つ。 |
2 | InitialEnabled | ブール | ウィジェットGUIの初期有効化(表示)状態。 |
3 | InitialEnabledShouldOverrideRestore | ブール | 正しい場合、初期有効化の値は以前に保存された有効状態を上書きします。 |
4 | FloatingXSize | 整数 | 初期ドック状態がEnum.InitialDockState.Floatに設定されている場合のGUIの初期幅。 |
5 | FloatingYSize | 整数 | 初期ドック状態がEnum.InitialDockState.Floatに設定されている場合のGUIの初期高。 |
6 | MinWidth | 整数 | GUIの最小幅で、プラットフォームによって異なる場合があります。 |
7 | MinHeight | 整数 | GUIの最低高で、プラットフォームによって異なる場合があります。 |
-- Create new "DockWidgetPluginGuiInfo" objectlocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, -- Widget will be initialized in floating paneltrue, -- Widget will be initially enabledfalse, -- Don't override the previous enabled state200, -- Default width of the floating window300, -- Default height of the floating window150, -- Minimum width of the floating window150 -- Minimum height of the floating window)-- Create new widget GUIlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Test Widget" -- Optional widget title
ウィジェット UI のカスタマイズ
ウィジェットを作成すると、有益なTextLabelsや対話型のClass.GuiObject|GuiObjects``Class.ImageButton|ImageButtonsなどでユーザーインターフェースをカスタマイズできます。 例えば、次のコードは GUI ウィンドウに基本的なTextButtonを追加します:
-- Create new widget GUIlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Test Widget" -- Optional widget titlelocal testButton = Instance.new("TextButton")testButton.BorderSizePixel = 0testButton.TextSize = 20testButton.TextColor3 = Color3.new(1,0.2,0.4)testButton.AnchorPoint = Vector2.new(0.5,0.5)testButton.Size = UDim2.new(1,0,1,0)testButton.Position = UDim2.new(0.5,0,0.5,0)testButton.SizeConstraint = Enum.SizeConstraint.RelativeYYtestButton.Text = "Click Me"testButton.Parent = testWidget
Studio のカラーテーマを変更
効果的な Studio ウィジェットは、Studio のテーマ設定にぴったり一致し、テーマが変更されると動的に調整を行います。 例えば、開発者が暗いテーマを使用している場合、ウィジェットの背景色、画像、テキストラベルは Studio の本来のテーマカラーとマッチするように調整されます。
以下のコードの追加は、当初、同期する GUI オブジェクトのテーブルとともに呼び出されるsyncGuiColors()関数を使用します。 関数の内部では、層になったsetColors()関数がオブジェクトをループし、Enum.StudioStyleGuideColorenumsGetColor()でオブジェクトの特定の側面を同期させます。 このsetColors()関数はすぐに実行され、Studio のテーマを同期し、その後ThemeChangedイベントに接続されて将来のテーマ変更を検出します。
testButton.Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in pairs(objects) do
-- Sync background color
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
-- Sync text color
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
end
end
-- Run 'setColors()' function to initially sync colors
setColors()
-- Connect 'ThemeChanged' event to the 'setColors()' function
settings().Studio.ThemeChanged:Connect(setColors)
end
-- Run 'syncGuiColors()' function to sync colors of provided objects
syncGuiColors({testButton})
マウスカーソルのカスタマイズ
ウィジェット要素との期待されるインタラクションをよりよくするために、MouseEnterやMouseLeaveなどの GUI イベントにシステム固有のマウスカーソルを設定できます。 以下のコードは、関数をtestButtonのMouseEnterやMouseLeaveイベントに接続してマウスカーソルを変更する方法を示しています。
local function setCursor(cursorAsset)
plugin:GetMouse().Icon = cursorAsset
end
testButton.MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton.MouseLeave:Connect(function()
setCursor("")
end)
マウスカーソルの一覧とその使用例については、以下の表を参照してください:
マウスカーソルアイコン | アセット | 使用事例 |
---|---|---|
rbxasset://SystemCursors/Arrow | デフォルトのクリックと選択。 | |
rbxasset://SystemCursors/PointingHand | アクティブなリンク/ボタンにカーソルを合わせます。 | |
rbxasset://SystemCursors/OpenHand | ドラッグ可能なアイテムにカーソルを合わせます。 | |
rbxasset://SystemCursors/ClosedHand | アイテムのドラッグ。 | |
rbxasset://SystemCursors/IBeam | テキストフィールドにカーソルを合わせます。 | |
rbxasset://SystemCursors/SizeNS | 垂直方向のサイズ変更ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/SizeEW | 水平方向のサイズ変更ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/SizeNESW | 角のサイズ変更ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/SizeNWSE | 角のサイズ変更ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/SizeAll | 多方向のサイズ変更ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/SplitNS | 垂直方向の「分割」ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/SplitEW | 水平方向の「分割」ハンドルにカーソルを合わせます。 | |
rbxasset://SystemCursors/Forbidden | ロック/禁止されたアイテムにカーソルを合わせます。 | |
rbxasset://SystemCursors/Wait | アクションが進行中であることを示しています。 | |
rbxasset://SystemCursors/Busy | システムがビジーであることを示しています。 | |
rbxasset://SystemCursors/Cross | ピンポイント選択範囲にカーソルを合わせます。 |
ユーザーからの意見収集
TextBoxやTextButtonなどの UI 要素は Studio ウィジェットで正常に動作し、通常の Roblox と同じようにインターフェースを構築することができます。 ただし、UserInputServiceやContextActionServiceは、これらのサービスがメインのゲームウィンドウにフォーカスが当たっていることを前提としているため、動作しません。
汎用的なインプットイベントの回避策として、透明なFrameを作成して画面全体を上から覆う方法があります。 以下のコード例では、フレームを作成し、ユーザーがGuiObject.InputBeganフレームをクリックすると、ユーザーがそのクリックを離すまでフレーム上のキーボード入力をイベントとしてキャプチャします。
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1 -- Hide the frame
frame.Size = UDim2.new(1, 0, 1, 0) -- Cover the screen
frame.Position = UDim2.new(0, 0, 0, 0)
frame.Parent = testWidget
local function onInputBegan(inputObject)
-- Process the input object here, for example detect key presses
end
frame.InputBegan:Connect(onInputBegan)
ドラッグ&ドロップインタラクション
ウィジェットでドラッグ&ドロップインタラクションを利用することにより簡単にデータの流れを改善できます。 このインタラクションを作成するには、ドラッグする要素を定義し、ドロップターゲットを作成後、ドロップアクションを処理します。
ドラッグソースの作成
Plugin:StartDrag()を呼び出すことでドラッグ操作を開始できますユーザーが通常TextButtonの UI 要素でマウスボタンを押すもしくはImageButtonウィジェット内。 以下のコードサンプルでは、1つのウィンドウウィジェットを作成し、その中にテキストボタンを作成します。
-- Create the widget firstlocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Drag Source", widgetInfo)dragSourceWidget.Title = "Drag Source"-- Create a TextButton that will initiate the draglocal dragButton = Instance.new("TextButton")dragButton.Size = UDim2.new(1, 0, 1, 0)dragButton.Text = "Drag me!" dragButton.Parent = dragSourceWidget
ドラッグの開始
ユーザーがTextButtonをクリックするとユーザーがマウスボタンに触れるとすぐに始動するMouseButton1Down()イベントでドラッグを開始できます。
接続されている関数の中で、ドラッグするデータを決定します。 データのタイプはMimeTypeキーに反映されると、ドラッグの内容が反映されますDataキーの中で、送信者はキー内にそれ自体を記述する必要がありますSenderキー。 詳細についてはPlugin:StartDrag()ページをご覧ください。
local function onButton1Down()
local dragInfo = {
Data = "Hello, world", -- The data being dragged
MimeType = "text/plain", -- Describes the MIME type of the data
Sender = "SomeDragSource", -- Describes from where the data originated
MouseIcon = "", -- Image content to use for the cursor
DragIcon = "", -- Image content to render under the cursor during drag
HotSpot = Vector2.new(0, 0) -- Where on the DragIcon to center the cursor
}
plugin:StartDrag(dragInfo)
end
dragButton.MouseButton1Down:Connect(onButton1Down)
ドロップターゲットの作成
このPluginGui.PluginDragDroppedイベントは、ドラッグ中にユーザーがウィンドウ上でマウスを離したときに発生します。 いつこのような場合、ドロップを検出するためにTextLabelを持つ2番目のウィジェットなどのドロップターゲットを定義する必要があります。
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Drop Target", widgetInfo)dragTargetWidget.Title = "Drop Target"-- This TextLabel will display what was droppedlocal textLabel = Instance.new("TextLabel")textLabel.Size = UDim2.new(1, 0, 1, 0)textLabel.Text = "Drop here..." textLabel.Parent = dragTargetWidget
ドロップアクションの処理
ドロップターゲットを作成したら、ドロップターゲットのウィジェットでPluginGui.PluginDragDroppedイベントを接続します。
local function onDragDrop(dragData)
print("PluginDragDropped")
if dragData.MimeType == "text/plain" then
textLabel.Text = dragData.Data
else
textLabel.Text = dragData.MimeType
end
end
dragTargetWidget.PluginDragDropped:Connect(onDragDrop)
ドラッグが進行している間、ユーザーがマウスをウィジェット上に移動させると、これら3つのイベントが発生します:
- PluginDragEntered– ユーザーがウィンドウにマウスを合わせると始動します
- PluginDragMoved–ユーザーがウィンドウ上でマウスを動かすと繰り返し始動します。 」というメッセージを表示するのに便利です「ここにドロップ!
- PluginDragLeftーユーザーのカーソルがウィンドウから離れたときに始動します。 これは、