UI 拖曳檢測器

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

UIDragDetector 實例促進並鼓勵與遊戲中的 2D 使用者介面元素互動,例如滑桿、旋轉器等。主要功能包括:

  • 在任何 GuiObject 實例下放置一個 UIDragDetector,使其能夠通過所有使用者輸入進行拖曳,而無需編寫一行代碼。

  • 從幾個 DragStyle 選項中選擇,定義物件如何對運動做出反應,通過 ResponseStyle,並可選擇應用軸、運動限制或拖曳邊界。

  • 腳本可以對拖曳物件的操作做出反應,以驅動邏輯響應,例如調整設置。

  • UIDragDetectors 在 Studio 的編輯和播放模式下工作,只要您使用 選擇移動縮放旋轉 工具,或某些插件或 Studio 的 UI 編輯工具。

使 UI 元素可拖曳

要使任何 GuiObject 實例可拖曳,只需將 UIDragDetector 作為直接子項添加。

  1. Explorer 窗口中,將滑鼠懸停在 GuiObject 實例上,然後單擊 ⊕ 按鈕。將顯示上下文菜單。

  2. 從菜單中插入 UIDragDetector

  3. 默認情況下,該物件現在將在 LayerCollector 界面中可拖曳。

自定義 UI 拖曳檢測器

拖曳樣式

UIDragDetectors 將游標運動映射以計算建議的 2D 運動和/或旋轉。通過 DragStyle 屬性,您可以從不同的映射中選擇以滿足您的需求。例如,Enum.UIDragDetectorDragStyle.TranslatePlaneLayerCollector 的 2D 平面中產生平移,而 Enum.UIDragDetectorDragStyle.Rotate 通常產生旋轉而不是平移。

設置描述
TranslateLine沿檢測器的 DragAxis 的 1D 運動。
TranslatePlaneLayerCollector 的平面中的 2D 運動。
Rotate默認情況下,圍繞檢測器的父 GuiObject 的絕對中心位置進行旋轉。如果設置了 ReferenceUIInstance,則旋轉將圍繞該實例的絕對中心位置進行。
Scriptable通過 SetDragStyleFunction() 提供的自定義函數計算所需的運動。

拖曳方向

默認情況下,2D 運動和相關的 DragStyle 映射到祖先 LayerCollector 的空間。然而,您可能希望在構建不同的 UI 元件時更改 ReferenceUIInstanceDragAxis

設置描述默認值
ReferenceUIInstance一個 GuiObject 實例,其本地空間和絕對中心位置是檢測器的參考空間和原點。設置此參考會影響屬性,例如 DragUDim2DragRotationDragAxis 的行為。nil
DragAxisVector2 值,定義當 DragStyle 設置為 Enum.UIDragDetectorDragStyle.TranslateLine 時被拖曳物件的運動軸。該軸在 UIDragDetector 的本地空間中定義,除非定義了 ReferenceUIInstance,在這種情況下,該軸在該實例的本地空間中定義。(1, 0)

對運動的響應

UIDragDetector.ResponseStyle 屬性指定物件的位置值如何通過建議的運動進行更改。自定義響應樣式允許您根據需要使用結果的 UIDragDetector.DragUDim2UIDragDetector.DragRotation 值,而無需檢測器的父項執行建議的運動。

設置描述
Offset根據檢測器父項的 GuiObject.Position 值的 Offset 值移動。這是默認設置。
Scale根據檢測器父項的 GuiObject.Position 值的 Scale 值移動。
CustomOffsetUI 元素將完全不移動,但檢測器的 DragUDim2Offset 值仍將被更新,並且檢測器的事件仍將觸發,允許您根據需要對拖曳操作做出響應。
CustomScaleUI 元素將完全不移動,但檢測器的 DragUDim2Scale 值仍將被更新,並且檢測器的事件仍將觸發,允許您根據需要對拖曳操作做出響應。

平移與旋轉限制

默認情況下,2D 運動沒有限制,僅受 DragStyle 的固有限制。如果需要,可以通過以下屬性聲明最小和最大平移和旋轉的限制。此外,您可以定義被拖曳物件在指定的 GuiObject(例如 Frame)的邊界內受到約束的方式。

屬性描述默認值
MinDragTranslation
MaxDragTranslation
在每個維度上的拖曳平移限制,由 UDim2 值定義。如果 MaxDragTranslation 大於 MinDragTranslation,則平移將被限制在該範圍內。{0, 0}, {0, 0}
MinDragAngle
MaxDragAngle
僅在 DragStyle 設置為 Enum.UIDragDetectorDragStyle.Rotate 時相關,或者如果通過 SetDragStyleFunction()AddConstraintFunction() 設置的函數定義了旋轉值。如果 MaxDragAngle 大於 MinDragAngle,則旋轉將被限制在該範圍內。0
BoundingBehavior確定當其 BoundingUI 被設置時,UIDragDetector 實例的邊界行為。將其設置為 EntireObject 將整個拖曳 UI 限制在 BoundingUI 內,而將其設置為 HitPoint 僅根據確切的命中/抓取點及其在平移/旋轉後的相應位置限制拖曳的 UI。作為方便,Automatic 的默認值模擬了對於完全包含在 BoundingUI 中的 UI 物件的 EntireObject 行為,否則對於部分在 BoundingUI 外的 UI 物件的 HitPoint 行為。Automatic

速度調整

通過 SelectionModeDragSpeedSelectionModeRotateSpeed,您可以微調檢測器的最大拖曳/旋轉速度。此外,通過 UIDragSpeedAxisMapping,您可以根據檢測器的 SelectionModeDragSpeed 微調 X/Y 維度的拖曳速度。

屬性描述
SelectionModeDragSpeed定義作為 ScaleOffset 的組合的平移最大拖曳速度,該組合來自檢測器所屬的第一個祖先 ScreenGuiSurfaceGui
SelectionModeRotateSpeed定義 UIDragDetector 可以旋轉的每秒最大角度。
UIDragSpeedAxisMapping根據檢測器的 SelectionModeDragSpeed 確定 X/Y 維度的拖曳速度。默認為 XY,這意味著 XY 軸的速度分別基於 XYScale/Offset 值。

替代方案為 XXYY,這意味著 XY 軸的速度分別基於 X (XX) 或 Y (YY) 軸的 Scale,而 Offset 值仍然適用於其各自的軸。例如,如果第一個祖先 ScreenGui 的大小為 800×600,且 SelectionModeDragSpeed{0.1, 10}, {0.1, 20},則設置為 XX 將導致 X/Y 拖曳速度為 80+10/80+20,而 YY 將導致 60+10/60+20(注意 Offset 值在兩種情況下保持不變)。

腳本對點擊和拖曳的響應

通過 事件信號、屬性變更、Scriptable 拖曳樣式和自定義函數,腳本可以對拖曳 UI 元素的操作做出響應,以驅動各種設置或做出邏輯決策,例如調整音樂和音效音量的滑桿。

事件信號

通過以下事件信號,您可以檢測用戶何時開始、繼續和結束拖曳物件。

事件描述
DragStart當用戶開始拖曳物件時觸發。
DragContinue當用戶在 DragStart 被觸發後繼續拖曳物件時觸發。
DragEnd當用戶停止拖曳物件時觸發。

以下滑桿將其容器指定為 BoundingUI,以限制其在容器區域內的運動,允許基於比例的 TranslateLine 拖曳限制在容器的全寬內,而無需額外的腳本。

UIDragDetector - 事件信號透明度變更
-- 階層為 SliderContainer ⟩ Handle ⟩ UIDragDetector ⟩ (此腳本)
local sliderContainer = script.Parent.Parent.Parent
local handle = sliderContainer:FindFirstChild("Handle")
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.ResponseStyle = Enum.UIDragDetectorResponseStyle.Scale -- 設置為按比例拖曳
uiDragDetector.DragStyle = Enum.UIDragDetectorDragStyle.TranslateLine -- 限制拖曳為直線
uiDragDetector.BoundingUI = sliderContainer
-- 初始設置容器透明度為手柄的 X 比例值
sliderContainer.BackgroundTransparency = 1 - handle.Position.X.Scale
-- 擴展手柄邊框以指示抓取開始
uiDragDetector.DragStart:Connect(function(inputPosition)
handle:FindFirstChildWhichIsA("UIStroke").Thickness = 6
end)
-- 根據拖曳的比例變更透明度
uiDragDetector.DragContinue:Connect(function(inputPosition)
sliderContainer.BackgroundTransparency = 1 - handle.Position.X.Scale
end)
-- 恢復手柄邊框以指示抓取結束
uiDragDetector.DragEnd:Connect(function(inputPosition)
handle:FindFirstChildWhichIsA("UIStroke").Thickness = 4
end)

位置與旋轉變更

除了 事件信號 外,您還可以直接監控檢測器的 DragUDim2 和/或 DragRotation 屬性的變更。

以下檢測器的 DragStyle 設置為 Rotate,允許用戶在色相旋轉器環上拖曳手柄,同時通過 Instance:GetPropertyChangedSignal() 檢測拖曳旋轉的變更。

UIDragDetector - DragRotation 變更
local handle = script.Parent.Parent -- 要拖曳的 UI 元素
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.DragStyle = Enum.UIDragDetectorDragStyle.Rotate -- 設置拖曳樣式為旋轉
local function changeHue()
local currAngle = (math.fmod(handle.Rotation, 360)) / 360
if currAngle < 0 then
currAngle += 1
end
handle.BackgroundColor3 = Color3.fromHSV(currAngle, 1, 1)
end
-- 初始設置色相為手柄旋轉
changeHue()
-- 將函數連接到檢測器的拖曳旋轉的 GetPropertyChangedSignal()
uiDragDetector:GetPropertyChangedSignal("DragRotation"):Connect(changeHue)

腳本化拖曳樣式

如果您將檢測器的 UIDragDetector.DragStyle 設置為 Enum.UIDragDetectorDragStyle.Scriptable,則可以提供自己的函數,該函數接受 Vector2 的輸入位置並返回 UDim2(位置)和浮點數(旋轉)。檢測器將根據返回的計算位置/旋轉、DragSpace 屬性和 DragRelativity 屬性更新物件。

默認情況下,返回的 UDim2 和浮點數將是檢測器父項的本地空間中的最終所需位置/旋轉。現有的平移/旋轉限制仍然適用,並且由指定的 BoundingUI 實例施加的邊界限制也將適用。

以下示例根據 X 坐標輸入的變化拖曳 UI 元素,遵循計算出的正弦波。請注意,檢測器的 DragSpace 設置為 Enum.UIDragDetectorDragSpace.Relative

UIDragDetector - 拖曳遵循正弦波
local frame = script.Parent -- 要拖曳的 UI 元素
local uiDragDetector = frame:FindFirstChildWhichIsA("UIDragDetector")
local initialXValue = 0
local maxHeightChange = 200
local pixelsPerRadian = 75 -- 降低此值以增加頻率
uiDragDetector.DragStart:Connect(function(inputPosition)
initialXValue = inputPosition.X
end)
local function computeSinWaveCoordinate(inputPosition)
local deltaX = inputPosition.X - initialXValue
-- 負的 Y 增量使其在屏幕上隨著正的 Y 變化而“向上”移動
local deltaY = -math.sin(deltaX / pixelsPerRadian) * maxHeightChange
return UDim2.fromOffset(deltaX, deltaY)
end
uiDragDetector:SetDragStyleFunction(computeSinWaveCoordinate)

自定義約束函數

UIDragDetectors 沒有內建的關於網格和對齊的運動規則,但您可以註冊自定義約束函數,以在應用之前編輯檢測器的 UIDragDetector.DragUDim2UIDragDetector.DragRotation。例如,您可以通過將位置四捨五入到特定增量來保持運動在網格上,或定義允許的運動區域。請注意,這是在任何現有的平移/旋轉限制之前應用的。

以下示例利用約束函數將平面拖曳限制在基於行和列數的 X/Y 網格中。請注意,檢測器的 ResponseStyle 設置為 Enum.UIDragDetectorResponseStyle.Scale,其 BoundingUI 設置為網格容器。

UIDragDetector - 在網格中拖曳,對齊到瓷磚
-- 階層為 GridContainer ⟩ Handle ⟩ UIDragDetector ⟩ (此腳本)
local gridContainer = script.Parent.Parent.Parent
local handle = gridContainer:FindFirstChild("Handle") -- 要拖曳的 UI 元素
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.ResponseStyle = Enum.UIDragDetectorResponseStyle.Scale -- 設置為按比例拖曳
uiDragDetector.DragRelativity = Enum.UIDragDetectorDragRelativity.Relative
uiDragDetector.BoundingUI = gridContainer
local NUM_COLUMNS = 10
local NUM_ROWS = 5
local xScaleIncrement = 1 / NUM_COLUMNS
local yScaleIncrement = 1 / NUM_ROWS
local initialParentPosition = uiDragDetector.Parent.Position
uiDragDetector.DragStart:Connect(function()
initialParentPosition = uiDragDetector.Parent.Position
end)
local function dragToGridOnly(proposedPosition, proposedRotation)
local griddedXScale = math.round(proposedPosition.X.Scale / xScaleIncrement) * xScaleIncrement
local griddedYScale = math.round(proposedPosition.Y.Scale / yScaleIncrement) * yScaleIncrement
return UDim2.fromScale(griddedXScale, griddedYScale), proposedRotation
end
uiDragDetector:AddConstraintFunction(1, dragToGridOnly)
©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。