Thể hiện của UIDragDetector tạo điều kiện và khuyến khích sự tương tác với các phần tử giao diện người dùng 2D trong một trải nghiệm, chẳng hạn như thanh trượt, vòng quay 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 nào của GuiObject để làm cho nó có thể kéo được thông 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.
Lựa chọn từ một số tùy chọn DragStyle, xác định cách mà đối tượng phản hồi với chuyển động thông qua ResponseStyle, và tuỳ chọn áp dụng trục, giới hạn chuyển động, hoặc ranh giới kéo.
Các script có thể phản hồi với việc thao tác các đối tượng bị kéo để điều khiển các phản ứng logic, chẳng hạn như điều chỉnh các 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ụ UI của Studio.
Làm cho các phần tử UI có thể kéo được
Để làm cho bất kỳ thể hiện nào của GuiObject có thể kéo được, chỉ cần thêm một UIDragDetector như một đối tượng con trực tiếp.
Từ menu, chèn một UIDragDetector.

Theo mặc định, đối tượng giờ sẽ có thể kéo trong giao diện LayerCollector.
Tùy chỉnh bộ phát hiện kéo UI
Kiểu kéo
UIDragDetectors ánh xạ chuyển động 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 phép dịch 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 GuiObject cha mẹ của bộ phát hiện. Nếu ReferenceUIInstance được đặt, xoay diễn 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 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. Việc đặt 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 định nghĩa trục chuyển động cho đối tượng bị kéo khi DragStyle được đặt thành Enum.UIDragDetectorDragStyle.TranslateLine. Trục được định nghĩa trong không gian cục bộ của UIDragDetector trừ khi ReferenceUIInstance được định nghĩa, trong trường hợp đó, trục được định nghĩa 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 mà giá trị vị trí của một đối tượng bị thay đổi bởi chuyển động đề xuất. Các kiểu phản hồi tùy chỉnh cho phép bạn sử dụng các giá trị UIDragDetector.DragUDim2 và UIDragDetector.DragRotation kết quả như mong muốn, mà không cần phép phát hiện cha thực hiện chuyển động đề xuất.
| Cài đặt | Mô tả |
|---|---|
| Offset | Di chuyển theo giá trị Offset của giá trị GuiObject.Position của bộ phát hiện cha. Đây là cài đặt theo mặc định. |
| Scale | Di chuyển theo giá trị Scale của giá trị GuiObject.Position của bộ phát hiện cha. |
| 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 theo cách mà 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 theo cách mà bạn muốn. |
Giới hạn dịch chuyển & xoay
Theo mặc định, không có giới hạn đối với chuyển động 2D ngoài những 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 muốn. Ngoài ra, bạn có thể xác định cách mà đối tượng bị kéo bị giới hạn trong các ranh giới của một GuiObject được chỉ định, chẳng hạn như một Frame.
| Các thuộc tính | Mô tả | Mặc định |
|---|---|---|
| MinDragTranslation MaxDragTranslation | Giới hạn cho việc dịch chuyển kéo 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 đặt thành Enum.UIDragDetectorDragStyle.Rotate, hoặc nếu các hàm được thiết lập qua SetDragStyleFunction() hoặc AddConstraintFunction() định nghĩa 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 ranh giới của thể hiện UIDragDetector khi BoundingUI được đặt. Đặt giá trị này thành EntireObject sẽ ranh giới toàn bộ UI bị kéo trong BoundingUI, trong khi đặt thành HitPoint sẽ ranh giới UI bị kéo chỉ bởi điểm chính xác gắp và vị trí tương ứng của nó sau khi dịch chuyển/xoay. Như một sự thuận tiện, giá trị mặc định của Automatic bắt chước hành vi 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 chỉ nằm một phần ngoài BoundingUI. | Automatic |
Điều chỉnh tốc độ
Thông qua SelectionModeDragSpeed và SelectionModeRotateSpeed, bạn có thể điều chỉnh tốc độ kéo/xoay tối đa cho một bộ phát hiện. Hơn nữa, thông qua UIDragSpeedAxisMapping, bạn có thể điều chỉnh tốc độ kéo trong không gian X/Y, dựa trên SelectionModeDragSpeed.
| 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 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 không gian X/Y, dựa trên SelectionModeDragSpeed. 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 khác là XX và YY, có nghĩa là cả hai trục X và Y đều dựa trên trục X (XX) hoặ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}, cài đặt 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). |
Các phản ứng script 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 script có thể phản hồi với việc thao tác các phần tử UI bị kéo để điều khiển các cài đặt khác nhau hoặc đưa ra các quyết định logic, chẳng hạn như các thanh trượt điều chỉnh âm lượng nhạc và hiệu ứng âm thanh riêng biệt.
Tín hiệu sự kiện
Thông qua các tín hiệu sự kiện sau đây, 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 ngừng kéo đối tượng. |
Thiết kế thanh trượt sau đây chỉ định bộ chứa của nó là BoundingUI để giới hạn chuyển động bê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 lập trình thêm.
UIDragDetector - Thay đổi sự kiện tín hiệu độ trong suốt
-- Cấu trúc là SliderContainer ⟩ Handle ⟩ UIDragDetector ⟩ (script này)
local sliderContainer = script.Parent.Parent.Parent
local handle = sliderContainer:FindFirstChild("Handle")
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.ResponseStyle = Enum.UIDragDetectorResponseStyle.Scale -- Đặt kéo theo tỷ lệ
uiDragDetector.DragStyle = Enum.UIDragDetectorDragStyle.TranslateLine -- Giới hạn kéo theo đường thẳng
uiDragDetector.BoundingUI = sliderContainer
-- Ban đầu, đặt độ trong suốt của bộ chứa thành giá trị tỷ lệ X của tay cầm
sliderContainer.BackgroundTransparency = 1 - handle.Position.X.Scale
-- Mở rộng viền tay cầm để chỉ ra rằng đã bắt đầu gắp
uiDragDetector.DragStart:Connect(function(inputPosition)
handle:FindFirstChildWhichIsA("UIStroke").Thickness = 6
end)
-- Thay đổi độ trong suốt theo lượng đã kéo trong tỷ lệ
uiDragDetector.DragContinue:Connect(function(inputPosition)
sliderContainer.BackgroundTransparency = 1 - handle.Position.X.Scale
end)
-- Khôi phục lại viền tay cầm để chỉ ra rằng đã kết thúc gắp
uiDragDetector.DragEnd:Connect(function(inputPosition)
handle:FindFirstChildWhichIsA("UIStroke").Thickness = 4
end)
Thay đổi vị trí & xoay
Ngoài các tín hiệu sự kiện, bạn có thể theo dõi những thay đổi với DragUDim2 và/hoặc thuộc tính DragRotation của bộ phát hiện trực tiếp.
Bộ phát hiện sau đây có DragStyle được đặt thành Rotate, cho phép người dùng kéo tay cầm xung quanh vòng quay sắc thái, trong khi tất cả đều phát hiện sự thay đổi về xoay kéo thông qua Instance:GetPropertyChangedSignal().
UIDragDetector - Thay đổi Động Xoay
local handle = script.Parent.Parent -- Phần tử UI để kéo
local uiDragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
uiDragDetector.DragStyle = Enum.UIDragDetectorDragStyle.Rotate -- Đặt 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 đặt màu sắc vào 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 được lập trình
Nếu bạn đặt UIDragDetector.DragStyle của bộ phát hiện thành Enum.UIDragDetectorDragStyle.Scriptable, bạn có thể cung cấp hàm của riêng bạn mà 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ố float (xoay). Bộ phát hiện sẽ cập nhật đối tượng đến vị trí/xoay đã 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, UDim2 và float 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 tại vẫn sẽ áp dụng, như cũng sẽ có các giới hạn ranh giới do một thể hiện BoundingUI được chỉ định đặt ra.
Ví dụ sau đây kéo một phần tử UI theo một sóng sine đượ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 đặt thành Enum.UIDragDetectorDragSpace.Relative.
UIDragDetector - Kéo theo sóng sine
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 để đ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 cho 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 đây sử dụng một hàm ràng buộc mà giới hạn dịch chuyển 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 đặt thành Enum.UIDragDetectorResponseStyle.Scale và BoundingUI của nó được đặt thành bộ chứa lưới.
UIDragDetector - Kéo trong Lưới, Snapping vào Gạch
-- Cấu trúc là GridContainer ⟩ Handle ⟩ UIDragDetector ⟩ (script 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 -- Đặt 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)