Thể hiện của UIDragDetector tạo điều kiện và khuyến khích tương tác với các phần tử giao diện người dùng 2D trong một trò chơi, chẳng hạn như thanh trượt, bộ điều chỉnh và nhiều hơn nữa. Các tính năng chính bao gồm:
Đặt một UIDragDetector dưới bất kỳ thể hiện GuiObject nào để làm cho nó có thể kéo thả qua tất cả các đầu vào của người dùng mà không cần một dòng mã nào.
Chọn từ một số tùy chọn DragStyle, xác định cách đối tượng phản ứng với chuyển động thông qua ResponseStyle, và tùy chọn áp dụng trục, giới hạn chuyển động hoặc ranh giới kéo thả.
Các kịch bản có thể phản ứng với việc thao tác các đối tượng bị kéo thả để điều khiển các phản ứng logic, chẳng hạn như điều chỉnh cài đặt.
UIDragDetectors hoạt động trong chế độ chỉnh sửa và chơi của Studio miễn là bạn không sử dụng các công cụ Chọn, Di chuyển, Tỉ lệ, hoặc Xoay, cũng như một số plugin hoặc công cụ chỉnh sửa UI của Studio.
Làm cho các phần tử UI có thể kéo thả
Để làm cho bất kỳ thể hiện GuiObject nào có thể kéo thả, chỉ cần thêm một UIDragDetector làm con cháu trực tiếp.
Từ menu, chèn một UIDragDetector.

Theo mặc định, đối tượng sẽ có thể kéo thả trong giao diện LayerCollector.
Tùy chỉnh các bộ phát hiện kéo thả UI
Kiểu kéo
UIDragDetectors ánh xạ chuyển động của con trỏ để tính toán chuyển động 2D và/hoặc xoay đề xuất. Thông qua thuộc tính DragStyle, bạn có thể chọn từ các ánh xạ khác nhau để phù hợp với nhu cầu của bạn. Ví dụ, Enum.UIDragDetectorDragStyle.TranslatePlane tạo ra sự dịch chuyển trong mặt phẳng 2D của LayerCollector, trong khi Enum.UIDragDetectorDragStyle.Rotate thường tạo ra một sự xoay thay vì dịch chuyển.
| Cài đặt | Mô tả |
|---|---|
| TranslateLine | Chuyển động 1D dọc theo DragAxis của bộ phát hiện. |
| TranslatePlane | Chuyển động 2D trong mặt phẳng của LayerCollector. |
| Rotate | Theo mặc định, xoay quanh vị trí trung tâm tuyệt đối của thể hiện cha GuiObject của bộ phát hiện. Nếu ReferenceUIInstance được thiết lập, xoay sẽ xảy ra quanh vị trí trung tâm tuyệt đối của thể hiện đó. |
| Scriptable | Tính toán chuyển động mong muốn thông qua một hàm tùy chỉnh được cung cấp thông qua SetDragStyleFunction(). |
Hướng kéo
Theo mặc định, chuyển động 2D và DragStyle liên quan ánh xạ đến không gian của tổ tiên LayerCollector. Tuy nhiên, bạn có thể muốn thay đổi ReferenceUIInstance hoặc DragAxis khi xây dựng các thành phần UI khác nhau.
| Cài đặt | Mô tả | Mặc định |
|---|---|---|
| ReferenceUIInstance | Một thể hiện GuiObject mà không gian cục bộ và vị trí trung tâm tuyệt đối của nó là không gian tham chiếu và gốc cho bộ phát hiện. Thiết lập tham chiếu này ảnh hưởng đến các thuộc tính như DragUDim2, DragRotation, và hành vi của DragAxis. | nil |
| DragAxis | Giá trị Vector2 xác định trục chuyển động cho đối tượng bị kéo khi DragStyle được thiết lập thành Enum.UIDragDetectorDragStyle.TranslateLine. Trục được xác định trong không gian cục bộ của UIDragDetector trừ khi ReferenceUIInstance được xác định, trong trường hợp đó trục được xác định trong không gian cục bộ của thể hiện đó. | (1, 0) |
Phản ứng với chuyển động
Thuộc tính UIDragDetector.ResponseStyle xác định cách giá trị vị trí của một đối tượng được thay đổi bởi chuyển động đề xuất. Các kiểu phản ứng tùy chỉnh cho phép bạn sử dụng các giá trị UIDragDetector.DragUDim2 và UIDragDetector.DragRotation kết quả theo cách mong muốn, mà không cần cho cha của bộ phát hiện thực hiện chuyển động đề xuất.
| Cài đặt | Mô tả |
|---|---|
| Offset | Di chuyển theo các giá trị Offset của giá trị GuiObject.Position của cha của bộ phát hiện. Đây là cài đặt theo mặc định. |
| Scale | Di chuyển theo các giá trị Scale của giá trị GuiObject.Position của cha của bộ phát hiện. |
| CustomOffset | Phần tử UI sẽ không di chuyển chút nào, nhưng các giá trị Offset của DragUDim2 của bộ phát hiện vẫn sẽ được cập nhật và các sự kiện của bộ phát hiện vẫn sẽ được kích hoạt, cho phép bạn phản ứng với việc thao tác kéo thả theo cách bạn muốn. |
| CustomScale | Phần tử UI sẽ không di chuyển chút nào, nhưng các giá trị Scale của DragUDim2 của bộ phát hiện vẫn sẽ được cập nhật và các sự kiện của bộ phát hiện vẫn sẽ được kích hoạt, cho phép bạn phản ứng với việc thao tác kéo thả theo cách bạn muốn. |
Giới hạn dịch chuyển & xoay
Theo mặc định, không có giới hạn nào cho chuyển động 2D ngoài các hạn chế vốn có của DragStyle. Các giới hạn cho cả dịch chuyển và xoay tối thiểu và tối đa có thể được khai báo với các thuộc tính sau nếu cần. Ngoài ra, bạn có thể xác định cách đối tượng bị kéo thả bị ràng buộc trong các giới hạn của một GuiObject được chỉ định như một Frame.
| Các thuộc tính | Mô tả | Mặc định |
|---|---|---|
| MinDragTranslation MaxDragTranslation | Giới hạn cho dịch chuyển kéo thả trong mỗi chiều, được xác định bởi một giá trị UDim2. Nếu MaxDragTranslation lớn hơn MinDragTranslation, dịch chuyển sẽ bị giới hạn trong khoảng đó. | {0, 0}, {0, 0} |
| MinDragAngle MaxDragAngle | Chỉ có liên quan nếu DragStyle được thiết lập thành Enum.UIDragDetectorDragStyle.Rotate, hoặc nếu các hàm được thiết lập thông qua SetDragStyleFunction() hoặc AddConstraintFunction() xác định một giá trị xoay. Nếu MaxDragAngle lớn hơn MinDragAngle, xoay sẽ bị giới hạn trong khoảng đó. | 0 |
| BoundingBehavior | Xác định hành vi ràng buộc của thể hiện UIDragDetector khi BoundingUI của nó được thiết lập. Thiết lập điều này thành EntireObject sẽ ràng buộc toàn bộ UI bị kéo thả trong BoundingUI, trong khi thiết lập thành HitPoint sẽ ràng buộc UI bị kéo thả chỉ bởi điểm hit/grab chính xác và vị trí tương ứng của nó sau khi dịch chuyển/xoay. Như một sự tiện lợi, mặc định của Automatic mô phỏng hành vi của EntireObject cho một đối tượng UI hoàn toàn nằm trong BoundingUI, hoặc HitPoint cho một đối tượng UI một phần nằm ngoài BoundingUI. | Automatic |
Điều chỉnh tốc độ
Thông qua SelectionModeDragSpeed và SelectionModeRotateSpeed, bạn có thể tinh chỉnh tốc độ kéo/thả tối đa cho một bộ phát hiện. Hơn nữa, thông qua UIDragSpeedAxisMapping, bạn có thể tinh chỉnh tốc độ kéo trong chiều X/Y, dựa trên SelectionModeDragSpeed của bộ phát hiện.
| Thuộc tính | Mô tả |
|---|---|
| SelectionModeDragSpeed | Xác định tốc độ kéo tối đa cho dịch chuyển như một sự kết hợp của Scale và Offset của tổ tiên đầu tiên ScreenGui hoặc SurfaceGui mà UIDragDetector thuộc về. |
| SelectionModeRotateSpeed | Xác định góc tối đa mỗi giây mà UIDragDetector có thể xoay. |
| UIDragSpeedAxisMapping | Xác định tốc độ kéo trong chiều X/Y, dựa trên SelectionModeDragSpeed của bộ phát hiện. Mặc định là XY, có nghĩa là tốc độ trục X và Y dựa trên các giá trị Scale/Offset tương ứng của X và Y. Các lựa chọn thay thế là XX và YY, có nghĩa là cả tốc độ trục X và Y đều dựa trên trục X (XX) hoặc trục Y (YY) cho Scale, trong khi các giá trị Offset vẫn áp dụng cho các trục tương ứng của chúng. Ví dụ, nếu tổ tiên đầu tiên ScreenGui có kích thước 800×600 và SelectionModeDragSpeed là {0.1, 10}, {0.1, 20}, một cài đặt của XX sẽ dẫn đến tốc độ kéo X/Y là 80+10/80+20, trong khi YY sẽ dẫn đến 60+10/60+20 (lưu ý rằng các giá trị Offset vẫn giữ nguyên trong cả hai trường hợp). |
Phản ứng của kịch bản với việc nhấp và kéo
Thông qua tín hiệu sự kiện, thay đổi thuộc tính, kiểu kéo Scriptable, và các hàm tùy chỉnh, các kịch bản có thể phản ứng với việc thao tác các phần tử UI bị kéo thả để điều khiển các cài đặt khác nhau hoặc đưa ra quyết định logic, chẳng hạn như các thanh trượt điều chỉnh âm nhạc và âm thanh hiệu ứng riêng biệt.
Tín hiệu sự kiện
Thông qua các tín hiệu sự kiện sau, bạn có thể phát hiện khi người dùng bắt đầu, tiếp tục và kết thúc việc kéo một đối tượng.
| Sự kiện | Mô tả |
|---|---|
| DragStart | Kích hoạt khi người dùng bắt đầu kéo đối tượng. |
| DragContinue | Kích hoạt khi người dùng tiếp tục kéo đối tượng sau khi DragStart đã được khởi động. |
| DragEnd | Kích hoạt khi người dùng dừng kéo đối tượng. |
Thiết kế thanh trượt sau chỉ định bộ chứa của nó là BoundingUI để giới hạn chuyển động của nó trong khu vực chứa, cho phép kiểu kéo dựa trên tỉ lệ TranslateLine bị giới hạn trong toàn bộ chiều rộng của bộ chứa mà không cần mã bổ sung.
-- Cấu trúc là SliderContainer ⟩ Handle ⟩ UIDragDetector ⟩ (kịch bản này)
local sliderContainer = script.Parent.Parent.Parent
local handle = sliderContainer:FindFirstChild("Handle")
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.ResponseStyle = Enum.UIDragDetectorResponseStyle.Scale -- Thiết lập kéo theo tỉ lệ
uiDragDetector.DragStyle = Enum.UIDragDetectorDragStyle.TranslateLine -- Giới hạn kéo thả theo đường thẳng
uiDragDetector.BoundingUI = sliderContainer
-- Ban đầu thiết lập độ trong suốt của bộ chứa theo giá trị tỉ lệ X của tay cầm
sliderContainer.BackgroundTransparency = 1 - handle.Position.X.Scale
-- Mở rộng biên tay cầm để chỉ ra bắt đầu kéo
uiDragDetector.DragStart:Connect(function(inputPosition)
handle:FindFirstChildWhichIsA("UIStroke").Thickness = 6
end)
-- Thay đổi độ trong suốt theo mức độ kéo thả trong tỉ lệ
uiDragDetector.DragContinue:Connect(function(inputPosition)
sliderContainer.BackgroundTransparency = 1 - handle.Position.X.Scale
end)
-- Khôi phục biên tay cầm để chỉ ra kết thúc kéo
uiDragDetector.DragEnd:Connect(function(inputPosition)
handle:FindFirstChildWhichIsA("UIStroke").Thickness = 4
end)Thay đổi vị trí & xoay
Ngoài tín hiệu sự kiện, bạn có thể theo dõi các thay đổi đối với DragUDim2 và/hoặc các thuộc tính DragRotation của bộ phát hiện trực tiếp.
Bộ phát hiện sau có DragStyle được thiết lập thành Rotate, cho phép người dùng kéo tay cầm xung quanh vòng xoay màu sắc, đồng thời phát hiện các thay đổi về xoay kéo thông qua Instance:GetPropertyChangedSignal().
local handle = script.Parent.Parent -- Phần tử UI để kéo
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.DragStyle = Enum.UIDragDetectorDragStyle.Rotate -- Thiết lập kiểu kéo thành xoay
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
-- Ban đầu thiết lập màu sắc theo xoay của tay cầm
changeHue()
-- Kết nối hàm với GetPropertyChangedSignal() của xoay kéo của bộ phát hiện
uiDragDetector:GetPropertyChangedSignal("DragRotation"):Connect(changeHue)Kiểu kéo kịch bản
Nếu bạn thiết lập UIDragDetector.DragStyle của một bộ phát hiện thành Enum.UIDragDetectorDragStyle.Scriptable, bạn có thể cung cấp hàm của riêng mình nhận vào một Vector2 của vị trí đầu vào và trả về một UDim2 (vị trí) và một số thực (xoay). Bộ phát hiện sẽ cập nhật đối tượng đến vị trí/xoay được tính toán dựa trên các giá trị trả về, thuộc tính DragSpace, và thuộc tính DragRelativity.
Theo mặc định, giá trị UDim2 và số thực được trả về sẽ là vị trí/xoay cuối cùng mong muốn trong không gian cục bộ của cha của bộ phát hiện. Các giới hạn dịch chuyển/xoay hiện có vẫn sẽ áp dụng, cũng như các giới hạn ranh giới do một thể hiện BoundingUI được chỉ định áp đặt.
Ví dụ sau kéo một phần tử UI theo một sóng sin được tính toán bởi sự thay đổi trong tọa độ X đầu vào. Lưu ý rằng DragSpace của bộ phát hiện được thiết lập thành Enum.UIDragDetectorDragSpace.Relative.
local frame = script.Parent -- Phần tử UI để kéo
local uiDragDetector = frame:FindFirstChildWhichIsA("UIDragDetector")
local initialXValue = 0
local maxHeightChange = 200
local pixelsPerRadian = 75 -- Giảm giá trị này để tăng tần số
uiDragDetector.DragStart:Connect(function(inputPosition)
initialXValue = inputPosition.X
end)
local function computeSinWaveCoordinate(inputPosition)
local deltaX = inputPosition.X - initialXValue
-- Delta Y âm để nó đi "lên" trên màn hình với sự thay đổi Y dương
local deltaY = -math.sin(deltaX / pixelsPerRadian) * maxHeightChange
return UDim2.fromOffset(deltaX, deltaY)
end
uiDragDetector:SetDragStyleFunction(computeSinWaveCoordinate)Hàm ràng buộc tùy chỉnh
UIDragDetectors không có quy tắc chuyển động tích hợp về lưới và snapping, nhưng bạn có thể đăng ký các hàm ràng buộc tùy chỉnh để chỉnh sửa UIDragDetector.DragUDim2 và UIDragDetector.DragRotation của bộ phát hiện trước khi chúng được áp dụng. Ví dụ, bạn có thể giữ chuyển động trên một lưới bằng cách làm tròn các vị trí đến các gia số cụ thể, hoặc xác định các khu vực chuyển động được phép. Lưu ý rằng điều này được áp dụng trước bất kỳ giới hạn dịch chuyển/xoay hiện có nào.
Ví dụ sau sử dụng một hàm ràng buộc mà giới hạn kéo phẳng vào một lưới X/Y dựa trên số lượng hàng và cột. Lưu ý rằng ResponseStyle của bộ phát hiện được thiết lập thành Enum.UIDragDetectorResponseStyle.Scale và BoundingUI của nó được thiết lập thành bộ chứa lưới.
-- Cấu trúc là GridContainer ⟩ Handle ⟩ UIDragDetector ⟩ (kịch bản này)
local gridContainer = script.Parent.Parent.Parent
local handle = gridContainer:FindFirstChild("Handle") -- Phần tử UI để kéo
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.ResponseStyle = Enum.UIDragDetectorResponseStyle.Scale -- Thiết lập kéo theo tỉ lệ
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)