UI 拖曳檢測器

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

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

  • UIDragDetector 安置在任何 GuiObject 實例之下,即可透過所有使用者輸入使其可拖曳,而無需撰寫一行程式碼。

  • 可選擇多種 DragStyle 方案,定義物件如何對運動做出反應,透過 ResponseStyle,並可選擇性地應用軸線、運動限制或拖曳邊界。

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

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

使 UI 元素可拖曳

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

  1. 資源管理器 窗口中,將鼠標懸停在 GuiObject 實例上,然後點擊 ⊕ 按鈕。將顯示一個上下文菜單。

  2. 從菜單中插入 UIDragDetector

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

自訂 UI 拖曳檢測器

拖曳樣式

UIDragDetectors 將游標運動映射到計算提議的 2D 運動和/或旋轉。透過 DragStyle 屬性,您可以從不同的映射中選擇,以滿足您的需求。例如,Enum.UIDragDetectorDragStyle.TranslatePlane 會在 LayerCollector 的 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 值將仍然更新,並且檢測器的事件仍然會觸發,允許您以自己喜歡的方式對拖曳操作做出反應。

平移和旋轉限制

默認情況下,對於 DragStyle 的固有限制,2D 運動沒有任何限制。如果需要,您可以透過以下屬性聲明最小和最大平移和旋轉的限制。此外,您還可以定義被拖曳物件在指定的 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 行為,否則為 HitPoint,適用於部份在 BoundingUI 之外的 UI 物件。Automatic

速度調整

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

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

替代方案為 XXYY,意味着 XY 軸的速度基於 ScaleX (XX) 或 Y (YY),同時 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 delta 使其在屏幕上向上移動
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 是我們在美國及其他國家地區的部分註冊與未註冊商標。