Studio mang đến cho bạn sức mạnh để tạo ra các tiện ích tùy chỉnh và sử dụng chúng như các công cụ và phần mở rộng. Những tiện ích này hoạt động như các cửa sổ/tấm bảng tùy chỉnh trong Studio, và bạn có thể dock chúng bên trong giao diện của bạn hoặc để chúng nổi như những cửa sổ riêng biệt.
Tạo giao diện widget
Tất cả các tiện ích Studio bắt đầu dưới dạng đối tượng DockWidgetPluginGui mà bạn có thể lấp đầy bằng GuiObjects, chẳng hạn như nhãn văn bản và nút bấm. Để tạo một giao diện widget trống, hãy gọi hàm CreateDockWidgetPluginGui(), truyền vào một ID và một đối tượng DockWidgetPluginGuiInfo.
Lưu ý rằng hàm khởi tạo DockWidgetPluginGuiInfo.new() yêu cầu các tham số của nó theo một thứ tự cụ thể như sau:
| # | Thuộc tính | Loại | Mô tả |
|---|---|---|---|
| 1 | Enum.InitialDockState | Enum | Một trong các liệt kê Enum.InitialDockState. |
| 2 | InitialEnabled | Boolean | Trạng thái ban đầu được kích hoạt (hiện) của giao diện widget. |
| 3 | InitialEnabledShouldOverrideRestore | Boolean | Nếu đúng, giá trị của InitialEnabled sẽ ghi đè trạng thái được lưu trước đó. |
| 4 | FloatingXSize | Integer | Chiều rộng ban đầu của giao diện khi InitialDockState được đặt thành Enum.InitialDockState.Float. |
| 5 | FloatingYSize | Integer | Chiều cao ban đầu của giao diện khi InitialDockState được đặt thành Enum.InitialDockState.Float. |
| 6 | MinWidth | Integer | Chiều rộng tối thiểu của giao diện, với một số biến thể cụ thể cho nền tảng. |
| 7 | MinHeight | Integer | Chiều cao tối thiểu của giao diện, với một số biến thể cụ thể cho nền tảng. |
-- Tạo đối tượng mới "DockWidgetPluginGuiInfo"local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, -- Widget sẽ được khởi tạo trong bảng nổitrue, -- Widget sẽ được kích hoạt ban đầufalse, -- Không ghi đè trạng thái đã kích hoạt trước đó200, -- Chiều rộng mặc định của cửa sổ nổi300, -- Chiều cao mặc định của cửa sổ nổi150, -- Chiều rộng tối thiểu của cửa sổ nổi150 -- Chiều cao tối thiểu của cửa sổ nổi)-- Tạo giao diện widget mớilocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Widget Kiểm Tra" -- Tiêu đề widget tùy chọn
Tùy chỉnh giao diện widget
Khi bạn tạo một widget, bạn có thể tùy chỉnh giao diện người dùng của nó bằng các GuiObjects như nhãn TextLabels thông tin hoặc ImageButtons tương tác. Ví dụ, đoạn mã sau đây thêm một TextButton cơ bản vào cửa sổ giao diện:
-- Tạo giao diện widget mớilocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Widget Kiểm Tra" -- Tiêu đề widget tùy chọnlocal 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 = "Nhấn Tôi"testButton.Parent = testWidget
Thay đổi giao diện màu Studio
Các tiện ích Studio hiệu quả thường phù hợp với cài đặt chủ đề của Studio và tự động điều chỉnh khi chủ đề thay đổi. Ví dụ, nếu một nhà phát triển đang sử dụng chế độ tối, màu nền của widget, hình ảnh và nhãn văn bản nên trông đẹp bên cạnh các màu chủ đề gốc của Studio.
Đoạn mã sau đây thêm vào một hàm syncGuiColors() mà được gọi ban đầu cùng với một bảng các đối tượng GUI để đồng bộ hóa. Bên trong hàm này, một hàm lồng nhau setColors() lặp qua các đối tượng và đồng bộ hóa các khía cạnh cụ thể của chúng bằng cách sử dụng GetColor() với các liệt kê Enum.StudioStyleGuideColor. Hàm setColors() này sẽ được chạy ngay lập tức để đồng bộ hóa chủ đề Studio, sau đó nó được kết nối với sự kiện ThemeChanged để phát hiện các thay đổi chủ đề trong tương lai.
testButton.Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in objects do
-- Đồng bộ màu nền
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
-- Đồng bộ màu văn bản
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
end
end
-- Chạy hàm 'setColors()' để đồng bộ hóa màu sắc ban đầu
setColors()
-- Kết nối sự kiện 'ThemeChanged' với hàm 'setColors()'
settings().Studio.ThemeChanged:Connect(setColors)
end
-- Chạy hàm 'syncGuiColors()' để đồng bộ hóa màu sắc của các đối tượng được cung cấp
syncGuiColors({testButton})
Tùy chỉnh con trỏ chuột
Để cải thiện tương tác mong đợi với các phần tử widget, bạn có thể đặt con trỏ chuột theo hệ thống cho các sự kiện GUI, chẳng hạn như MouseEnter và MouseLeave. Đoạn mã sau đây cho thấy cách kết nối một hàm với các sự kiện MouseEnter và MouseLeave của testButton để thay đổi con trỏ chuột:
local function setCursor(cursorAsset)
plugin:GetMouse().Icon = cursorAsset
end
testButton.MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton.MouseLeave:Connect(function()
setCursor("")
end)
Tham khảo bảng sau đây để biết danh sách các con trỏ chuột và các trường hợp sử dụng tiềm năng của chúng:
| Biểu tượng Con trỏ Chuột | Tài sản | Trường hợp Sử dụng |
|---|---|---|
| rbxasset://SystemCursors/Arrow | Mặc định cho việc click và chọn. | |
| rbxasset://SystemCursors/PointingHand | Di chuột qua liên kết/nút hoạt động. | |
| rbxasset://SystemCursors/OpenHand | Di chuột qua một vật có thể kéo. | |
| rbxasset://SystemCursors/ClosedHand | Kéo một vật phẩm. | |
| rbxasset://SystemCursors/IBeam | Di chuột trong một trường văn bản. | |
| rbxasset://SystemCursors/SizeNS | Di chuột qua một tay nắm thay đổi kích thước theo chiều dọc. | |
| rbxasset://SystemCursors/SizeEW | Di chuột qua một tay nắm thay đổi kích thước theo chiều ngang. | |
| rbxasset://SystemCursors/SizeNESW | Di chuột qua một tay nắm thay đổi kích thước ở góc. | |
| rbxasset://SystemCursors/SizeNWSE | Di chuột qua một tay nắm thay đổi kích thước ở góc. | |
| rbxasset://SystemCursors/SizeAll | Di chuột qua một tay nắm thay đổi kích thước nhiều hướng. | |
| rbxasset://SystemCursors/SplitNS | Di chuột qua một tay nắm "chia" theo chiều dọc. | |
| rbxasset://SystemCursors/SplitEW | Di chuột qua một tay nắm "chia" theo chiều ngang. | |
| rbxasset://SystemCursors/Forbidden | Di chuột qua một vật bị khóa/cấm. | |
| rbxasset://SystemCursors/Wait | Chỉ ra rằng một hành động đang diễn ra. | |
| rbxasset://SystemCursors/Busy | Chỉ ra rằng hệ thống đang bận. | |
| rbxasset://SystemCursors/Cross | Di chuột qua một khu vực chọn điểm. |
Thu thập đầu vào từ người dùng
Các phần tử UI như TextBox và TextButton hoạt động bình thường trong các tiện ích Studio, và bạn có thể xây dựng các giao diện giống như cách bạn thường làm trên Roblox. Tuy nhiên, UserInputService không hoạt động vì các dịch vụ này yêu cầu cửa sổ trải nghiệm chính phải có tiêu điểm.
Một giải pháp cho các sự kiện đầu vào tổng quát là tạo một Frame trong suốt và phủ lên toàn bộ màn hình. Đoạn mã mẫu sau tạo một khung, và khi người dùng nhấp vào khung, sự kiện GuiObject.InputBegan sẽ bắt đầu thu thập đầu vào từ bàn phím trên khung cho đến khi người dùng nhấp ra ngoài:
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1 -- Ẩn khung
frame.Size = UDim2.new(1, 0, 1, 0) -- Che phủ màn hình
frame.Position = UDim2.new(0, 0, 0, 0)
frame.Parent = testWidget
local function onInputBegan(inputObject)
-- Xử lý đối tượng đầu vào ở đây, ví dụ phát hiện phím nhấn
end
frame.InputBegan:Connect(onInputBegan)
Tương tác kéo và thả
Sử dụng tương tác kéo và thả cho các widget của bạn là một cách đơn giản để cải thiện luồng dữ liệu. Để tạo tương tác này, bạn phải định nghĩa phần tử để kéo, khởi động kéo, tạo một mục thả và xử lý hành động thả.
Tạo nguồn kéo
Bạn có thể bắt đầu hành động kéo bằng cách gọi Plugin:StartDrag() khi người dùng nhấn một nút chuột trên một phần tử UI, thường là một TextButton hoặc ImageButton trong widget. Đoạn mã mẫu sau tạo một widget cửa sổ đơn giản với một nút văn bản bên trong.
-- Tạo widget trướclocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Nguồn Kéo", widgetInfo)dragSourceWidget.Title = "Nguồn Kéo"-- Tạo một TextButton sẽ khởi động kéolocal dragButton = Instance.new("TextButton")dragButton.Size = UDim2.new(1, 0, 1, 0)dragButton.Text = "Kéo tôi!"dragButton.Parent = dragSourceWidget
Khởi động kéo
Khi người dùng nhấp vào TextButton, bạn có thể khởi động kéo thông qua sự kiện MouseButton1Down() sẽ được kích hoạt ngay khi người dùng nhấn nút chuột.
Trong hàm kết nối, xác định dữ liệu để kéo. Kiểu của dữ liệu nên được phản ánh trong khóa MimeType, nội dung của hành động kéo nên được phản ánh trong khóa Data, và người gửi nên mô tả chính nó trong khóa Sender. Xem trang Plugin:StartDrag() để biết thêm chi tiết.
local function onButton1Down()
local dragInfo = {
Data = "Xin chào, thế giới", -- Dữ liệu đang được kéo
MimeType = "text/plain", -- Mô tả loại MIME của dữ liệu
Sender = "NguồnKéoNào", -- Mô tả từ đâu dữ liệu xuất phát
MouseIcon = "", -- Nội dung hình ảnh để sử dụng cho con trỏ
DragIcon = "", -- Nội dung hình ảnh để hiển thị dưới con trỏ trong khi kéo
HotSpot = Vector2.zero -- Vị trí trên DragIcon để căn giữa con trỏ
}
plugin:StartDrag(dragInfo)
end
dragButton.MouseButton1Down:Connect(onButton1Down)
Tạo mục thả
Sự kiện PluginGui.PluginDragDropped sẽ được kích hoạt khi người dùng thả chuột ra trên một cửa sổ trong quá trình kéo. Khi điều này xảy ra, bạn cần xác định một mục thả như một widget thứ hai với một TextLabel để phát hiện các lần thả.
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Mục Thả", widgetInfo)dragTargetWidget.Title = "Mục Thả"-- TextLabel này sẽ hiển thị những gì đã được thảlocal textLabel = Instance.new("TextLabel")textLabel.Size = UDim2.new(1, 0, 1, 0)textLabel.Text = "Thả ở đây..."textLabel.Parent = dragTargetWidget
Xử lý hành động thả
Sau khi tạo một mục thả, kết nối sự kiện PluginGui.PluginDragDropped trên widget mục thả:
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)
Trong khi một hành động kéo vẫn đang diễn ra, ba sự kiện này sẽ được kích hoạt khi người dùng di chuyển chuột của họ trên một widget:
- PluginDragEntered – được kích hoạt khi người dùng di chuột qua một cửa sổ
- PluginDragMoved – được kích hoạt liên tục khi người dùng di chuyển chuột của họ qua một cửa sổ. Điều này hữu ích cho việc hiển thị một thông điệp "Thả ở đây!".
- PluginDragLeft – được kích hoạt khi con trỏ của người dùng rời khỏi một cửa sổ. Điều này hữu ích cho việc ẩn một thông điệp "Thả ở đây!".















