explore
key systems
new
docs
discord
search scripts
⌘K
explore
key systems
new
docs
discord
sign in
⌘↵
--
publishes from anywhere on this page
new paste
untitled.luau
empty
/ 512kb
open file
⌘O
explore
key systems
new
docs
sign in
better-dex-by-rafan-keyless-copy.lua
971 lines · 46.5kb
/ 512kb
open file
⌘O
assert(plugin, "Better Dex must run as a Roblox Studio Plugin."); local TweenService = game:GetService("TweenService"); local Selection = game:GetService("Selection"); local ChangeHistoryService = game:GetService("ChangeHistoryService"); local ScriptEditorService = game:GetService("ScriptEditorService"); local UserInputService = game:GetService("UserInputService"); local BRAND = "Better Dex By Rafan (MayBeeHub)"; local VERSION = "2.0.0"; local SETTINGS_TUTORIAL_KEY = "BetterDex_TutorialCompleted_v2"; local C = {bg=Color3.fromRGB(17, 22, 42),surface=Color3.fromRGB(25, 32, 58),surface2=Color3.fromRGB(31, 40, 69),surface3=Color3.fromRGB(39, 50, 82),line=Color3.fromRGB(55, 72, 108),cyan=Color3.fromRGB(0, 225, 245),cyan2=Color3.fromRGB(0, 170, 210),cyanSoft=Color3.fromRGB(90, 235, 245),text=Color3.fromRGB(235, 245, 255),muted=Color3.fromRGB(145, 165, 190),green=Color3.fromRGB(65, 190, 135),red=Color3.fromRGB(225, 82, 100),amber=Color3.fromRGB(245, 185, 80)}; local function make(className, props, parent) local object = Instance.new(className); for key, value in pairs(props or {}) do object[key] = value; end object.Parent = parent; return object; end local function addCorner(object, radius) make("UICorner", {CornerRadius=UDim.new(0, radius or 8)}, object); end local function addStroke(object, color, transparency, thickness) return make("UIStroke", {Color=(color or C.line),Transparency=(transparency or 0),Thickness=(thickness or 1)}, object); end local function tween(object, duration, properties, style, direction) local info = TweenInfo.new(duration, style or Enum.EasingStyle.Quint, direction or Enum.EasingDirection.Out); local animation = TweenService:Create(object, info, properties); animation:Play(); return animation; end local function safeGet(instance, property) local ok, value = pcall(function() return instance[property]; end); if ok then return value; end return nil; end local function safeString(value) local ok, result = pcall(tostring, value); return (ok and result) or "<unavailable>"; end local function setStatus(text, color) if _G.__BETTER_DEX_STATUS then _G.__BETTER_DEX_STATUS(text, color); end end local function performChange(name, displayName, callback) local recording; local beginOk, beginResult = pcall(function() return ChangeHistoryService:TryBeginRecording(name, displayName or name); end); if beginOk then recording = beginResult; end if not recording then setStatus("Studio tidak dapat memulai recording undo. Coba di Edit mode.", C.amber); return false, "Could not begin ChangeHistory recording"; end local ok, result = pcall(callback); local finishOk, finishError = pcall(function() ChangeHistoryService:FinishRecording(recording, (ok and Enum.FinishRecordingOperation.Commit) or Enum.FinishRecordingOperation.Cancel); end); if not ok then setStatus("Action failed: " .. safeString(result), C.red); return false, result; end if not finishOk then setStatus("ChangeHistory warning: " .. safeString(finishError), C.amber); end return true, result; end local toolbar = plugin:CreateToolbar("Better Dex"); local toggleButton = toolbar:CreateButton("BetterDexOpen", "Open Better Dex By Rafan (MayBeeHub)", ""); toggleButton.ClickableWhenViewportHidden = true; local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, false, 760, 820, 570, 520); local widget = plugin:CreateDockWidgetPluginGuiAsync("BetterDex_Rafan_MayBeeHub_v2", widgetInfo); widget.Title = BRAND; widget.ZIndexBehavior = Enum.ZIndexBehavior.Sibling; toggleButton.Click:Connect(function() widget.Enabled = not widget.Enabled; end); widget:BindToClose(function() end); local root = make("Frame", {Name="Root",Size=UDim2.fromScale(1, 1),BackgroundColor3=C.bg,BorderSizePixel=0,ClipsDescendants=true}, widget); local rootGradient = make("UIGradient", {Color=ColorSequence.new({ColorSequenceKeypoint.new(0, Color3.fromRGB(20, 29, 57)),ColorSequenceKeypoint.new(1, Color3.fromRGB(13, 18, 35))}),Rotation=90}, root); local header = make("Frame", {Name="Header",Size=UDim2.new(1, 0, 0, 62),BackgroundColor3=C.surface,BorderSizePixel=0,ZIndex=2}, root); make("UIGradient", {Color=ColorSequence.new(C.surface2, C.surface),Rotation=0}, header); local brandMark = make("Frame", {Position=UDim2.fromOffset(14, 12),Size=UDim2.fromOffset(38, 38),BackgroundColor3=C.cyan2,BorderSizePixel=0,ZIndex=3}, header); addCorner(brandMark, 11); addStroke(brandMark, C.cyan, 0.2, 1.3); make("TextLabel", {Size=UDim2.fromScale(1, 1),BackgroundTransparency=1,Text="BD",TextColor3=C.bg,Font=Enum.Font.GothamBlack,TextSize=17,ZIndex=4}, brandMark); make("TextLabel", {Position=UDim2.fromOffset(62, 8),Size=UDim2.new(1, -260, 0, 25),BackgroundTransparency=1,Text="BETTER DEX",TextColor3=C.text,Font=Enum.Font.GothamBlack,TextSize=17,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=3}, header); make("TextLabel", {Position=UDim2.fromOffset(63, 32),Size=UDim2.new(1, -260, 0, 17),BackgroundTransparency=1,Text=("By Rafan (MayBeeHub) • v" .. VERSION),TextColor3=C.cyanSoft,Font=Enum.Font.GothamMedium,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=3}, header); local function headerButton(text, rightOffset, tooltip) local button = make("TextButton", {AnchorPoint=Vector2.new(1, 0.5),Position=UDim2.new(1, -rightOffset, 0.5, 0),Size=UDim2.fromOffset(34, 32),BackgroundColor3=C.surface3,Text=text,TextColor3=C.text,Font=Enum.Font.GothamBold,TextSize=14,AutoButtonColor=false,BorderSizePixel=0,ZIndex=3}, header); addCorner(button, 8); addStroke(button, C.line, 0.25, 1); button.MouseEnter:Connect(function() tween(button, 0.13, {BackgroundColor3=C.cyan2}); end); button.MouseLeave:Connect(function() tween(button, 0.13, {BackgroundColor3=C.surface3}); end); button:SetAttribute("Tooltip", tooltip or ""); return button; end local helpButton = headerButton("?", 126, "Open tutorial"); local refreshButton = headerButton("↻", 84, "Refresh explorer"); local minimizeButton = headerButton("×", 42, "Close Better Dex panel"); minimizeButton.MouseButton1Click:Connect(function() widget.Enabled = false; end); local sidebar = make("Frame", {Position=UDim2.fromOffset(0, 62),Size=UDim2.new(0, 58, 1, -62),BackgroundColor3=C.surface,BorderSizePixel=0,ZIndex=1}, root); local sidebarLine = make("Frame", {Position=UDim2.new(1, -1, 0, 0),Size=UDim2.new(0, 1, 1, 0),BackgroundColor3=C.line,BackgroundTransparency=0.35,BorderSizePixel=0}, sidebar); local content = make("Frame", {Position=UDim2.fromOffset(58, 62),Size=UDim2.new(1, -58, 1, -62),BackgroundTransparency=1,BorderSizePixel=0}, root); local navButtons = {}; local function navButton(glyph, label, y) local button = make("TextButton", {Position=UDim2.fromOffset(7, y),Size=UDim2.fromOffset(44, 48),BackgroundColor3=C.surface,Text=(glyph .. "\n" .. label),TextColor3=C.muted,Font=Enum.Font.GothamBold,TextSize=10,AutoButtonColor=false,BorderSizePixel=0,ZIndex=2}, sidebar); addCorner(button, 9); navButtons[label] = button; button.MouseEnter:Connect(function() if (button:GetAttribute("Active") ~= true) then tween(button, 0.12, {BackgroundColor3=C.surface2,TextColor3=C.text}); end end); button.MouseLeave:Connect(function() if (button:GetAttribute("Active") ~= true) then tween(button, 0.12, {BackgroundColor3=C.surface,TextColor3=C.muted}); end end); return button; end local explorerNav = navButton("⌕", "Explorer", 15); local createNav = navButton("+", "Create", 72); local toolsNav = navButton("⚙", "Tools", 129); local contentTop = make("Frame", {Size=UDim2.new(1, -20, 0, 42),Position=UDim2.fromOffset(10, 9),BackgroundTransparency=1}, content); local searchBox = make("TextBox", {Size=UDim2.new(1, -390, 0, 34),Position=UDim2.fromOffset(0, 3),BackgroundColor3=C.surface2,TextColor3=C.text,PlaceholderColor3=C.muted,PlaceholderText="Search instances...",Text="",ClearTextOnFocus=false,Font=Enum.Font.Gotham,TextSize=11,TextXAlignment=Enum.TextXAlignment.Left,BorderSizePixel=0}, contentTop); addCorner(searchBox, 8); addStroke(searchBox, C.line, 0.4, 1); local function actionButton(parent, text, width, color) local button = make("TextButton", {Size=UDim2.fromOffset(width, 32),BackgroundColor3=(color or C.surface2),Text=text,TextColor3=C.text,Font=Enum.Font.GothamBold,TextSize=10,AutoButtonColor=false,BorderSizePixel=0}, parent); addCorner(button, 7); addStroke(button, C.line, 0.45, 1); button.MouseEnter:Connect(function() tween(button, 0.12, {BackgroundColor3=((color and color:Lerp(C.cyan, 0.12)) or C.surface3)}); end); button.MouseLeave:Connect(function() tween(button, 0.12, {BackgroundColor3=(color or C.surface2)}); end); return button; end local addObjectButton = actionButton(contentTop, "+ Object", 74, C.cyan2); addObjectButton.Position = UDim2.new(1, -382, 0, 4); local addScriptButton = actionButton(contentTop, "+ Script", 74, C.green); addScriptButton.Position = UDim2.new(1, -302, 0, 4); local duplicateButton = actionButton(contentTop, "Duplicate", 76); duplicateButton.Position = UDim2.new(1, -220, 0, 4); local deleteButton = actionButton(contentTop, "Delete", 64, C.red); deleteButton.Position = UDim2.new(1, -138, 0, 4); local explorerPanel = make("Frame", {Position=UDim2.fromOffset(10, 58),Size=UDim2.new(1, -20, 0.51, -58),BackgroundColor3=C.surface,BorderSizePixel=0}, content); addCorner(explorerPanel, 10); addStroke(explorerPanel, C.line, 0.25, 1); local explorerPanelHeader = make("Frame", {Size=UDim2.new(1, 0, 0, 30),BackgroundColor3=C.surface2,BorderSizePixel=0}, explorerPanel); addCorner(explorerPanelHeader, 10); make("TextLabel", {Position=UDim2.fromOffset(12, 0),Size=UDim2.new(1, -24, 1, 0),BackgroundTransparency=1,Text="EXPLORER / DATA MODEL",TextColor3=C.cyanSoft,Font=Enum.Font.GothamBold,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left}, explorerPanelHeader); local tree = make("ScrollingFrame", {Position=UDim2.fromOffset(6, 34),Size=UDim2.new(1, -12, 1, -40),BackgroundTransparency=1,BorderSizePixel=0,ScrollBarThickness=5,ScrollBarImageColor3=C.cyan2,CanvasSize=UDim2.new()}, explorerPanel); local treeLayout = make("UIListLayout", {Padding=UDim.new(0, 1),SortOrder=Enum.SortOrder.LayoutOrder}, tree); local propsPanel = make("Frame", {Position=UDim2.new(0, 10, 0.51, 8),Size=UDim2.new(1, -20, 0.49, -54),BackgroundColor3=C.surface,BorderSizePixel=0}, content); addCorner(propsPanel, 10); addStroke(propsPanel, C.line, 0.25, 1); local propsHeader = make("Frame", {Size=UDim2.new(1, 0, 0, 32),BackgroundColor3=C.surface2,BorderSizePixel=0}, propsPanel); addCorner(propsHeader, 10); make("TextLabel", {Position=UDim2.fromOffset(12, 0),Size=UDim2.new(0.5, -12, 1, 0),BackgroundTransparency=1,Text="PROPERTIES",TextColor3=C.cyanSoft,Font=Enum.Font.GothamBold,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left}, propsHeader); local propertySearch = make("TextBox", {AnchorPoint=Vector2.new(1, 0.5),Position=UDim2.new(1, -9, 0.5, 0),Size=UDim2.new(0.5, -10, 0, 23),BackgroundColor3=C.surface3,TextColor3=C.text,PlaceholderColor3=C.muted,PlaceholderText="Filter properties...",Text="",ClearTextOnFocus=false,Font=Enum.Font.Gotham,TextSize=10,BorderSizePixel=0}, propsHeader); addCorner(propertySearch, 6); local propsScroll = make("ScrollingFrame", {Position=UDim2.fromOffset(6, 36),Size=UDim2.new(1, -12, 1, -42),BackgroundTransparency=1,BorderSizePixel=0,ScrollBarThickness=5,ScrollBarImageColor3=C.cyan2,CanvasSize=UDim2.new()}, propsPanel); local propsLayout = make("UIListLayout", {Padding=UDim.new(0, 2),SortOrder=Enum.SortOrder.LayoutOrder}, propsScroll); local footer = make("Frame", {AnchorPoint=Vector2.new(0, 1),Position=UDim2.new(1, -10, 1, -9),Size=UDim2.new(1, -20, 0, 26),BackgroundColor3=C.surface2,BorderSizePixel=0}, content); addCorner(footer, 7); local footerStatus = make("TextLabel", {Position=UDim2.fromOffset(10, 0),Size=UDim2.new(1, -20, 1, 0),BackgroundTransparency=1,Text="Ready • Select an Instance to inspect it",TextColor3=C.muted,Font=Enum.Font.Gotham,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left}, footer); _G.__BETTER_DEX_STATUS = function(text, color) if (footerStatus and footerStatus.Parent) then footerStatus.Text = tostring(text); footerStatus.TextColor3 = color or C.muted; end end; local activeToast; local function toast(message, color) if activeToast then activeToast:Destroy(); end local card = make("Frame", {AnchorPoint=Vector2.new(0.5, 0),Position=UDim2.new(0.5, 0, 0, 70),Size=UDim2.fromOffset(320, 42),BackgroundColor3=C.surface3,BackgroundTransparency=0.08,BorderSizePixel=0,ZIndex=90}, root); activeToast = card; addCorner(card, 9); addStroke(card, color or C.cyan, 0.1, 1.2); local text = make("TextLabel", {Size=UDim2.new(1, -20, 1, 0),Position=UDim2.fromOffset(10, 0),BackgroundTransparency=1,Text=message,TextColor3=C.text,TextSize=11,Font=Enum.Font.GothamMedium,TextWrapped=true,ZIndex=91}, card); card.Position = UDim2.new(0.5, 0, 0, 48); tween(card, 0.25, {Position=UDim2.new(0.5, 0, 0, 72)}); task.delay(2.6, function() if (card and card.Parent) then tween(card, 0.2, {BackgroundTransparency=1,Position=UDim2.new(0.5, 0, 0, 56)}); task.wait(0.22); if card then card:Destroy(); end end end); end local selected = workspace; local expanded = {[game]=true,[workspace]=true}; local searchQuery = ""; local propertyQuery = ""; local refreshing = false; local showProperties; local refreshExplorer; local showTutorial; local showChoicePopup; local function isValidParent(instance) return (typeof(instance) == "Instance") and (instance.Parent ~= nil); end local function updateSelection(instance) if (not isValidParent(instance) and (instance ~= game)) then instance = workspace; end selected = instance; pcall(function() Selection:Set({instance}); end); end local function clearGui(container, keepLayout) for _, child in ipairs(container:GetChildren()) do if not (keepLayout and (child == keepLayout)) then child:Destroy(); end end end local function addPropertyRow(name, value, editorType, setter, choices) if ((propertyQuery ~= "") and not name:lower():find(propertyQuery, 1, true)) then return; end local row = make("Frame", {Size=UDim2.new(1, -4, 0, 29),BackgroundColor3=C.surface2,BorderSizePixel=0}, propsScroll); addCorner(row, 5); make("TextLabel", {Position=UDim2.fromOffset(8, 0),Size=UDim2.new(0.36, -8, 1, 0),BackgroundTransparency=1,Text=name,TextColor3=C.muted,Font=Enum.Font.Gotham,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left,TextTruncate=Enum.TextTruncate.AtEnd}, row); if (editorType == "bool") then local toggle = make("TextButton", {AnchorPoint=Vector2.new(1, 0.5),Position=UDim2.new(1, -8, 0.5, 0),Size=UDim2.fromOffset(66, 21),BackgroundColor3=((value and C.green) or C.surface3),Text=((value and "ON") or "OFF"),TextColor3=C.text,Font=Enum.Font.GothamBold,TextSize=9,BorderSizePixel=0}, row); addCorner(toggle, 6); toggle.MouseButton1Click:Connect(function() local ok, err = performChange("Edit " .. name, "Change " .. name, function() setter(not value); end); if ok then toast(name .. " updated", C.green); else toast("Could not update " .. name, C.red); end if selected then showProperties(selected); end refreshExplorer(); end); elseif (editorType == "choice") then local choiceButton = make("TextButton", {AnchorPoint=Vector2.new(1, 0.5),Position=UDim2.new(1, -8, 0.5, 0),Size=UDim2.new(0.58, -10, 0, 22),BackgroundColor3=C.surface3,Text=(safeString(value) .. " ▾"),TextColor3=C.text,Font=Enum.Font.Gotham,TextSize=9,BorderSizePixel=0,TextTruncate=Enum.TextTruncate.AtEnd}, row); addCorner(choiceButton, 5); choiceButton.MouseButton1Click:Connect(function() local opts = choices or {}; showChoicePopup(name, opts, function(choice) local ok = performChange("Set " .. name, "Set " .. name, function() setter(choice); end); if ok then toast(name .. " updated", C.green); end if selected then showProperties(selected); end end); end); else local input = make("TextBox", {AnchorPoint=Vector2.new(1, 0.5),Position=UDim2.new(1, -8, 0.5, 0),Size=UDim2.new(0.58, -10, 0, 22),BackgroundColor3=C.surface3,Text=safeString(value),TextColor3=C.text,PlaceholderColor3=C.muted,PlaceholderText="Enter value",Font=Enum.Font.Gotham,TextSize=9,ClearTextOnFocus=false,TextXAlignment=Enum.TextXAlignment.Left,BorderSizePixel=0,TextTruncate=Enum.TextTruncate.AtEnd}, row); addCorner(input, 5); input.FocusLost:Connect(function(enterPressed) if not enterPressed then return; end local ok, result = performChange("Edit " .. name, "Edit " .. name, function() setter(input.Text); end); if ok then toast(name .. " updated", C.green); if selected then showProperties(selected); end refreshExplorer(); else toast("Invalid value for " .. name .. ": " .. safeString(result), C.red); if selected then showProperties(selected); end end end); end end function showChoicePopup(title, options, callback) if _G.__BETTER_DEX_SHOW_MENU then _G.__BETTER_DEX_SHOW_MENU(title, options, callback); else toast("Choice menu is not ready yet", C.amber); end end local function parseVector3(text) local parts = {}; for number in string.gmatch(text, "[^,%s]+") do table.insert(parts, tonumber(number)); end assert((#parts == 3) and parts[1] and parts[2] and parts[3], "Use x, y, z"); return Vector3.new(parts[1], parts[2], parts[3]); end local function parseColor3(text) local parts = {}; for number in string.gmatch(text, "[^,%s]+") do table.insert(parts, tonumber(number)); end assert((#parts == 3) and parts[1] and parts[2] and parts[3], "Use r, g, b from 0 to 255"); return Color3.fromRGB(math.clamp(parts[1], 0, 255), math.clamp(parts[2], 0, 255), math.clamp(parts[3], 0, 255)); end function showProperties(instance) clearGui(propsScroll, propsLayout); if not instance then addPropertyRow("Selection", "No Instance selected"); return; end addPropertyRow("Name", instance.Name, "text", function(value) assert(value ~= "", "Name cannot be empty"); instance.Name = value; end); addPropertyRow("ClassName", instance.ClassName); addPropertyRow("Parent", (instance.Parent and instance.Parent:GetFullName()) or "nil"); addPropertyRow("Archivable", instance.Archivable, "bool", function(value) instance.Archivable = value; end); addPropertyRow("GetFullName", instance:GetFullName()); if instance:IsA("BasePart") then addPropertyRow("Anchored", instance.Anchored, "bool", function(v) instance.Anchored = v; end); addPropertyRow("CanCollide", instance.CanCollide, "bool", function(v) instance.CanCollide = v; end); addPropertyRow("CanTouch", instance.CanTouch, "bool", function(v) instance.CanTouch = v; end); addPropertyRow("CanQuery", instance.CanQuery, "bool", function(v) instance.CanQuery = v; end); addPropertyRow("CastShadow", instance.CastShadow, "bool", function(v) instance.CastShadow = v; end); addPropertyRow("Transparency", instance.Transparency, "number", function(v) local n = tonumber(v); assert(n and (n >= 0) and (n <= 1), "Use a number from 0 to 1"); instance.Transparency = n; end); addPropertyRow("Reflectance", instance.Reflectance, "number", function(v) local n = tonumber(v); assert(n and (n >= 0) and (n <= 1), "Use a number from 0 to 1"); instance.Reflectance = n; end); addPropertyRow("Size", instance.Size, "text", function(v) instance.Size = parseVector3(v); end); addPropertyRow("Position", instance.Position, "text", function(v) instance.Position = parseVector3(v); end); addPropertyRow("Color", string.format("%d, %d, %d", math.floor(instance.Color.R * 255), math.floor(instance.Color.G * 255), math.floor(instance.Color.B * 255)), "text", function(v) instance.Color = parseColor3(v); end); local materials = {"Plastic","SmoothPlastic","Neon","Wood","WoodPlanks","Concrete","Metal","DiamondPlate","Foil","Glass","Brick","Granite","Marble","Grass","Sand","Fabric","Slate","Ice"}; addPropertyRow("Material", instance.Material.Name, "choice", function(v) local material = Enum.Material[v]; assert(material, "Unknown material"); instance.Material = material; end, materials); elseif instance:IsA("Humanoid") then addPropertyRow("Health", instance.Health, "number", function(v) local n = tonumber(v); assert(n, "Number required"); instance.Health = n; end); addPropertyRow("MaxHealth", instance.MaxHealth, "number", function(v) local n = tonumber(v); assert(n and (n > 0), "Positive number required"); instance.MaxHealth = n; end); addPropertyRow("WalkSpeed", instance.WalkSpeed, "number", function(v) local n = tonumber(v); assert(n, "Number required"); instance.WalkSpeed = n; end); addPropertyRow("JumpPower", instance.JumpPower, "number", function(v) local n = tonumber(v); assert(n, "Number required"); instance.JumpPower = n; end); addPropertyRow("AutoRotate", instance.AutoRotate, "bool", function(v) instance.AutoRotate = v; end); elseif instance:IsA("ValueBase") then local value = instance.Value; local kind = typeof(value); addPropertyRow("Value", value, "text", function(v) if (kind == "number") then local n = tonumber(v); assert(n, "Number required"); instance.Value = n; elseif (kind == "boolean") then assert((v == "true") or (v == "false"), "Enter true or false"); instance.Value = v == "true"; else instance.Value = v; end end); elseif instance:IsA("Tool") then addPropertyRow("ToolTip", instance.ToolTip, "text", function(v) instance.ToolTip = v; end); addPropertyRow("RequiresHandle", instance.RequiresHandle, "bool", function(v) instance.RequiresHandle = v; end); addPropertyRow("CanBeDropped", instance.CanBeDropped, "bool", function(v) instance.CanBeDropped = v; end); elseif instance:IsA("LuaSourceContainer") then if (instance:IsA("Script") or instance:IsA("LocalScript")) then addPropertyRow("Enabled", instance.Enabled, "bool", function(v) instance.Enabled = v; end); addPropertyRow("RunContext", safeString(instance.RunContext), "choice", function(v) local context = Enum.RunContext[v]; assert(context, "Unknown RunContext"); instance.RunContext = context; end, {"Legacy","Server","Client"}); end elseif instance:IsA("GuiObject") then addPropertyRow("Visible", instance.Visible, "bool", function(v) instance.Visible = v; end); addPropertyRow("Active", instance.Active, "bool", function(v) instance.Active = v; end); addPropertyRow("BackgroundTransparency", instance.BackgroundTransparency, "number", function(v) local n = tonumber(v); assert(n and (n >= 0) and (n <= 1), "Use 0 to 1"); instance.BackgroundTransparency = n; end); if (instance:IsA("TextLabel") or instance:IsA("TextButton") or instance:IsA("TextBox")) then addPropertyRow("Text", instance.Text, "text", function(v) instance.Text = v; end); addPropertyRow("TextSize", instance.TextSize, "number", function(v) local n = tonumber(v); assert(n and (n > 0), "Positive number required"); instance.TextSize = n; end); end elseif instance:IsA("Light") then addPropertyRow("Enabled", instance.Enabled, "bool", function(v) instance.Enabled = v; end); addPropertyRow("Brightness", instance.Brightness, "number", function(v) local n = tonumber(v); assert(n, "Number required"); instance.Brightness = n; end); addPropertyRow("Range", instance.Range, "number", function(v) local n = tonumber(v); assert(n and (n >= 0), "Non-negative number required"); instance.Range = n; end); end propsScroll.CanvasSize = UDim2.fromOffset(0, propsLayout.AbsoluteContentSize.Y + 8); end local modalLayer = make("Frame", {Name="ModalLayer",Size=UDim2.fromScale(1, 1),BackgroundTransparency=1,Visible=false,ZIndex=30}, root); local modalBackdrop = make("TextButton", {Size=UDim2.fromScale(1, 1),BackgroundColor3=Color3.new(0, 0, 0),BackgroundTransparency=0.42,Text="",AutoButtonColor=false,BorderSizePixel=0,ZIndex=30}, modalLayer); local modalCard = make("Frame", {AnchorPoint=Vector2.new(0.5, 0.5),Position=UDim2.fromScale(0.5, 0.5),Size=UDim2.fromOffset(390, 440),BackgroundColor3=C.surface,BorderSizePixel=0,ZIndex=31}, modalLayer); addCorner(modalCard, 13); addStroke(modalCard, C.cyan2, 0.22, 1.2); local modalTitle = make("TextLabel", {Position=UDim2.fromOffset(16, 10),Size=UDim2.new(1, -32, 0, 30),BackgroundTransparency=1,Text="SELECT",TextColor3=C.cyanSoft,Font=Enum.Font.GothamBlack,TextSize=14,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=32}, modalCard); local modalClose = make("TextButton", {AnchorPoint=Vector2.new(1, 0),Position=UDim2.new(1, -10, 0, 9),Size=UDim2.fromOffset(28, 27),BackgroundColor3=C.surface3,Text="×",TextColor3=C.text,Font=Enum.Font.GothamBold,TextSize=18,ZIndex=32}, modalCard); addCorner(modalClose, 6); local modalSearch = make("TextBox", {Position=UDim2.fromOffset(13, 48),Size=UDim2.new(1, -26, 0, 30),BackgroundColor3=C.surface2,TextColor3=C.text,PlaceholderText="Search...",PlaceholderColor3=C.muted,Text="",ClearTextOnFocus=false,Font=Enum.Font.Gotham,TextSize=11,ZIndex=32}, modalCard); addCorner(modalSearch, 6); local modalList = make("ScrollingFrame", {Position=UDim2.fromOffset(13, 86),Size=UDim2.new(1, -26, 1, -99),BackgroundTransparency=1,BorderSizePixel=0,ScrollBarThickness=5,ScrollBarImageColor3=C.cyan2,CanvasSize=UDim2.new(),ZIndex=32}, modalCard); local modalLayout = make("UIListLayout", {Padding=UDim.new(0, 3),SortOrder=Enum.SortOrder.LayoutOrder}, modalList); local modalCallback; local modalOptions = {}; local function closeModal() modalLayer.Visible = false; end modalClose.MouseButton1Click:Connect(closeModal); modalBackdrop.MouseButton1Click:Connect(closeModal); local function renderModalList() clearGui(modalList, modalLayout); local query = modalSearch.Text:lower(); local count = 0; for _, option in ipairs(modalOptions) do if ((query == "") or option:lower():find(query, 1, true)) then count += 1 local button = make("TextButton", {Size=UDim2.new(1, -4, 0, 31),BackgroundColor3=C.surface2,Text=(" " .. option),TextColor3=C.text,TextXAlignment=Enum.TextXAlignment.Left,Font=Enum.Font.Gotham,TextSize=11,BorderSizePixel=0,LayoutOrder=count,ZIndex=33}, modalList); addCorner(button, 6); button.MouseEnter:Connect(function() tween(button, 0.1, {BackgroundColor3=C.surface3}); end); button.MouseLeave:Connect(function() tween(button, 0.1, {BackgroundColor3=C.surface2}); end); button.MouseButton1Click:Connect(function() local callback = modalCallback; closeModal(); if callback then callback(option); end end); end end modalList.CanvasSize = UDim2.fromOffset(0, modalLayout.AbsoluteContentSize.Y + 6); end local function showModal(title, options, callback) modalTitle.Text = title:upper(); modalOptions = options; modalCallback = callback; modalSearch.Text = ""; renderModalList(); modalLayer.Visible = true; modalCard.Position = UDim2.fromScale(0.5, 0.53); tween(modalCard, 0.2, {Position=UDim2.fromScale(0.5, 0.5)}, Enum.EasingStyle.Back); end modalSearch:GetPropertyChangedSignal("Text"):Connect(renderModalList); _G.__BETTER_DEX_SHOW_MENU = showModal; local treeNodeCount = 0; local MAX_TREE_NODES = 1800; local function subtreeMatches(instance, query, depth) if (instance.Name:lower():find(query, 1, true) or instance.ClassName:lower():find(query, 1, true)) then return true; end if (depth >= 12) then return false; end for _, child in ipairs(instance:GetChildren()) do if subtreeMatches(child, query, depth + 1) then return true; end end return false; end local function createTreeRow(instance, depth) local children = instance:GetChildren(); local hasChildren = #children > 0; local isSelected = selected == instance; treeNodeCount += 1 local row = make("Frame", {Size=UDim2.new(1, -4, 0, 23),BackgroundColor3=((isSelected and C.selected) or C.surface),BorderSizePixel=0,LayoutOrder=treeNodeCount}, tree); addCorner(row, 4); local indent = math.min(depth * 15, 245); local expand = make("TextButton", {Position=UDim2.fromOffset(indent + 2, 0),Size=UDim2.fromOffset(18, 23),BackgroundTransparency=1,Text=((hasChildren and ((expanded[instance] and "▾") or "›")) or ""),TextColor3=C.cyanSoft,Font=Enum.Font.GothamBold,TextSize=13}, row); local icon = (instance:IsA("LuaSourceContainer") and "⌘") or (instance:IsA("BasePart") and "▣") or (instance:IsA("Folder") and "▰") or (instance:IsA("Model") and "◇") or "◆"; local nameButton = make("TextButton", {Position=UDim2.fromOffset(indent + 20, 0),Size=UDim2.new(1, -(indent + 22), 1, 0),BackgroundTransparency=1,Text=(icon .. " " .. instance.Name .. " · " .. instance.ClassName),TextColor3=((isSelected and C.text) or C.muted),Font=Enum.Font.Gotham,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left,TextTruncate=Enum.TextTruncate.AtEnd}, row); row.MouseEnter:Connect(function() if (selected ~= instance) then tween(row, 0.08, {BackgroundColor3=C.surface2}); end end); row.MouseLeave:Connect(function() if (selected ~= instance) then tween(row, 0.08, {BackgroundColor3=C.surface}); end end); local function selectThis() selected = instance; pcall(function() Selection:Set({instance}); end); showProperties(instance); refreshExplorer(); end nameButton.MouseButton1Click:Connect(selectThis); expand.MouseButton1Click:Connect(function() if hasChildren then expanded[instance] = not expanded[instance]; refreshExplorer(); else selectThis(); end end); return hasChildren; end function refreshExplorer() if refreshing then return; end refreshing = true; clearGui(tree, treeLayout); treeNodeCount = 0; local query = searchQuery:lower(); local function addBranch(instance, depth) if (treeNodeCount >= MAX_TREE_NODES) then return; end if ((query ~= "") and not subtreeMatches(instance, query, 0)) then return; end local children = getChildrenSorted(instance); local hasChildren = createTreeRow(instance, depth); if (hasChildren and (expanded[instance] or (query ~= "")) and (depth < 18)) then for _, child in ipairs(children) do addBranch(child, depth + 1); if (treeNodeCount >= MAX_TREE_NODES) then break; end end end end addBranch(game, 0); tree.CanvasSize = UDim2.fromOffset(0, treeLayout.AbsoluteContentSize.Y + 8); refreshing = false; end local objectCatalog = {"Part","SpawnLocation","TrussPart","WedgePart","CornerWedgePart","Model","Folder","Configuration","Attachment","Bone","WeldConstraint","Weld","Motor6D","AlignPosition","AlignOrientation","BodyGyro","BodyVelocity","VectorForce","LinearVelocity","AngularVelocity","BoolValue","IntValue","NumberValue","StringValue","ObjectValue","RemoteEvent","RemoteFunction","BindableEvent","BindableFunction","PointLight","SpotLight","SurfaceLight","ParticleEmitter","Beam","Trail","Decal","Texture","Highlight","BillboardGui","SurfaceGui","ScreenGui","Frame","ScrollingFrame","TextLabel","TextButton","TextBox","ImageLabel","ImageButton","UIListLayout","UIGridLayout","UIPadding","UICorner","UIStroke","UIGradient","ProximityPrompt","ClickDetector","Sound","Animation","Camera","HumanoidDescription"}; local scriptTemplates = {"Empty Script","Empty LocalScript","Empty ModuleScript","Server Script - Hello","LocalScript - Hello","Module - Table","Part Touch Event","Button Click Event"}; local function chooseObjectParent() if (selected and (selected ~= game) and selected.Parent) then return selected; end return workspace; end local function createObject(className) local parent = chooseObjectParent(); local ok, newInstance = performChange("Create " .. className, "Create " .. className, function() local object = Instance.new(className); object.Name = "New" .. className; if object:IsA("BasePart") then object.Anchored = true; object.Size = Vector3.new(4, 1, 4); local camera = workspace.CurrentCamera; if camera then object.Position = camera.CFrame.Position + (camera.CFrame.LookVector * 12); end elseif object:IsA("ScreenGui") then object.ResetOnSpawn = false; end object.Parent = parent; return object; end); if (ok and newInstance) then expanded[parent] = true; selected = newInstance; pcall(function() Selection:Set({newInstance}); end); showProperties(newInstance); refreshExplorer(); toast(className .. " created inside " .. parent.Name, C.green); end end local function scriptTarget(className) local current = selected; if (current and (current ~= game) and (current ~= workspace) and current.Parent) then if (className ~= "LocalScript") then return current; end local validLocalParents = {StarterPlayerScripts=true,StarterCharacterScripts=true,StarterGui=true,StarterPack=true}; if (validLocalParents[current.Name] or current:IsA("Tool")) then return current; end end if (className == "Script") then return game:GetService("ServerScriptService"); end if (className == "LocalScript") then return game:GetService("StarterPlayer"):WaitForChild("StarterPlayerScripts"); end return game:GetService("ReplicatedStorage"); end local function getTemplateSource(template) local sources = {["Empty Script"]="-- Server Script\n\n",["Empty LocalScript"]="-- LocalScript\n\n",["Empty ModuleScript"]="local Module = {}\n\nreturn Module\n",["Server Script - Hello"]='-- Server Script\nprint(\"Hello from the server!\")\n',["LocalScript - Hello"]='-- LocalScript\nlocal Players = game:GetService(\"Players\")\nlocal player = Players.LocalPlayer\nprint(\"Hello, \" .. player.Name)\n',["Module - Table"]='local Module = {}\n\nfunction Module.Init()\n print(\"Module initialized\")\nend\n\nreturn Module\n',["Part Touch Event"]='local part = script.Parent\n\npart.Touched:Connect(function(hit)\n local character = hit.Parent\n local humanoid = character and character:FindFirstChildOfClass(\"Humanoid\")\n if humanoid then\n print(character.Name .. \" touched the part\")\n end\nend)\n',["Button Click Event"]='local button = script.Parent\n\nbutton.Activated:Connect(function()\n print(\"Button clicked\")\nend)\n'}; return sources[template] or "-- New Script\n"; end local function createScriptFromTemplate(template) local className = "Script"; if template:find("LocalScript") then className = "LocalScript"; end if template:find("Module") then className = "ModuleScript"; end local parent = scriptTarget(className); if not parent then toast("StarterPlayerScripts container not found", C.red); return; end local ok, newScript = performChange("Create " .. className, "Create " .. template, function() local object = Instance.new(className); object.Name = template:gsub("[^%w]", ""); object.Parent = parent; ScriptEditorService:UpdateSourceAsync(object, function() return getTemplateSource(template); end); return object; end); if (ok and newScript) then expanded[parent] = true; selected = newScript; pcall(function() Selection:Set({newScript}); end); showProperties(newScript); refreshExplorer(); task.spawn(function() local opened, err = ScriptEditorService:OpenScriptDocumentAsync(newScript, {}); if not opened then toast("Script created; editor did not open: " .. safeString(err), C.amber); else toast(template .. " created", C.green); end end); end end addObjectButton.MouseButton1Click:Connect(function() showModal("Add Object", objectCatalog, createObject); end); addScriptButton.MouseButton1Click:Connect(function() showModal("Add Script Template", scriptTemplates, createScriptFromTemplate); end); local function duplicateSelected() if (not selected or (selected == game)) then toast("Select an Instance first", C.amber); return; end local source = selected; local parent = source.Parent; local ok, clone = performChange("Duplicate Instance", "Duplicate " .. source.Name, function() local copy = source:Clone(); assert(copy, "Instance could not be cloned. Check Archivable."); copy.Name = source.Name .. "_Copy"; copy.Parent = parent; return copy; end); if (ok and clone) then selected = clone; expanded[parent] = true; pcall(function() Selection:Set({clone}); end); showProperties(clone); refreshExplorer(); toast("Instance duplicated", C.green); end end duplicateButton.MouseButton1Click:Connect(duplicateSelected); local function confirmDelete() if (not selected or (selected == game)) then toast("Select an Instance first", C.amber); return; end local target = selected; showModal("Confirm Delete", {"Cancel",("Delete: " .. target.Name)}, function(choice) if (choice == "Cancel") then return; end local parent = target.Parent; local ok = performChange("Delete Instance", "Delete " .. target.Name, function() target:Destroy(); end); if ok then selected = parent or workspace; pcall(function() Selection:Set({selected}); end); showProperties(selected); refreshExplorer(); toast("Instance deleted (Undo is available)", C.green); end end); end deleteButton.MouseButton1Click:Connect(confirmDelete); local function setNavActive(activeLabel) for label, button in pairs(navButtons) do local active = label == activeLabel; button:SetAttribute("Active", active); button.BackgroundColor3 = (active and C.surface3) or C.surface; button.TextColor3 = (active and C.cyan) or C.muted; end end explorerNav.MouseButton1Click:Connect(function() setNavActive("Explorer"); searchBox:CaptureFocus(); searchBox:ReleaseFocus(); toast("Explorer ready", C.cyan); end); createNav.MouseButton1Click:Connect(function() setNavActive("Create"); showModal("Create Instance", objectCatalog, createObject); end); toolsNav.MouseButton1Click:Connect(function() setNavActive("Tools"); showModal("Tools", {"Refresh Explorer","Duplicate Selected","Delete Selected","Add Object","Add Script","Open Tutorial"}, function(choice) if (choice == "Refresh Explorer") then refreshExplorer(); showProperties(selected); elseif (choice == "Duplicate Selected") then duplicateSelected(); elseif (choice == "Delete Selected") then confirmDelete(); elseif (choice == "Add Object") then showModal("Add Object", objectCatalog, createObject); elseif (choice == "Add Script") then showModal("Add Script Template", scriptTemplates, createScriptFromTemplate); elseif (choice == "Open Tutorial") then showTutorial(true); end end); end); searchBox:GetPropertyChangedSignal("Text"):Connect(function() searchQuery = searchBox.Text; refreshExplorer(); end); propertySearch:GetPropertyChangedSignal("Text"):Connect(function() propertyQuery = propertySearch.Text:lower(); showProperties(selected); end); refreshButton.MouseButton1Click:Connect(function() refreshExplorer(); showProperties(selected); toast("Explorer refreshed", C.cyan); end); Selection.SelectionChanged:Connect(function() local selection = Selection:Get(); if selection[1] then selected = selection[1]; showProperties(selected); refreshExplorer(); end end); local tutorialSteps = {{"Welcome to Better Dex","A Studio explorer with a dark cyan interface, a searchable hierarchy, and a properties inspector."},{"Explore the DataModel","Use the search field to filter Instances. Click a row to select it; click the arrow to expand or collapse children."},{"Inspect Properties","Select an Instance to inspect common properties. Editable values are saved as Studio changes and support Undo when recording is available."},{"Create Objects & Scripts","Use + Object or + Script to insert Instances and starter script templates under the selected parent or the recommended service."},{"Work safely","Delete asks for confirmation. Use Studio Undo (Ctrl+Z) to reverse plugin changes. Save your place regularly."}}; local tutorialLayer = make("Frame", {Name="TutorialLayer",Size=UDim2.fromScale(1, 1),BackgroundColor3=Color3.new(0, 0, 0),BackgroundTransparency=0.38,Visible=false,ZIndex=60}, root); local tutorialCard = make("Frame", {AnchorPoint=Vector2.new(0.5, 0.5),Position=UDim2.fromScale(0.5, 0.54),Size=UDim2.fromOffset(430, 270),BackgroundColor3=C.surface,BorderSizePixel=0,ZIndex=61}, tutorialLayer); addCorner(tutorialCard, 15); addStroke(tutorialCard, C.cyan, 0.15, 1.4); local tutorialEyebrow = make("TextLabel", {Position=UDim2.fromOffset(22, 20),Size=UDim2.new(1, -44, 0, 19),BackgroundTransparency=1,Text="BETTER DEX • QUICK TOUR",TextColor3=C.cyan,Font=Enum.Font.GothamBold,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=62}, tutorialCard); local tutorialTitle = make("TextLabel", {Position=UDim2.fromOffset(22, 53),Size=UDim2.new(1, -44, 0, 39),BackgroundTransparency=1,Text="Welcome",TextColor3=C.text,Font=Enum.Font.GothamBlack,TextSize=20,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=62}, tutorialCard); local tutorialBody = make("TextLabel", {Position=UDim2.fromOffset(22, 99),Size=UDim2.new(1, -44, 0, 85),BackgroundTransparency=1,Text="",TextColor3=C.muted,Font=Enum.Font.Gotham,TextSize=12,TextWrapped=true,TextYAlignment=Enum.TextYAlignment.Top,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=62}, tutorialCard); local tutorialProgress = make("TextLabel", {Position=UDim2.fromOffset(22, 190),Size=UDim2.new(1, -44, 0, 18),BackgroundTransparency=1,Text="STEP 1 / 5",TextColor3=C.cyanSoft,Font=Enum.Font.GothamBold,TextSize=10,TextXAlignment=Enum.TextXAlignment.Left,ZIndex=62}, tutorialCard); local tutorialSkip = make("TextButton", {Position=UDim2.new(0, 22, 1, -49),Size=UDim2.fromOffset(92, 31),BackgroundColor3=C.surface3,Text="Skip",TextColor3=C.text,Font=Enum.Font.GothamBold,TextSize=11,ZIndex=62}, tutorialCard); addCorner(tutorialSkip, 7); local tutorialNext = make("TextButton", {AnchorPoint=Vector2.new(1, 0),Position=UDim2.new(1, -22, 1, -49),Size=UDim2.fromOffset(112, 31),BackgroundColor3=C.cyan2,Text="Next →",TextColor3=C.bg,Font=Enum.Font.GothamBlack,TextSize=11,ZIndex=62}, tutorialCard); addCorner(tutorialNext, 7); local tutorialIndex = 1; local function finishTutorial() tutorialLayer.Visible = false; plugin:SetSetting(SETTINGS_TUTORIAL_KEY, true); toast("Tutorial completed", C.green); end local function updateTutorial() local step = tutorialSteps[tutorialIndex]; tutorialTitle.Text = step[1]; tutorialBody.Text = step[2]; tutorialProgress.Text = string.format("STEP %d / %d", tutorialIndex, #tutorialSteps); tutorialNext.Text = ((tutorialIndex == #tutorialSteps) and "Finish ✓") or "Next →"; end function showTutorial(force) if (not force and (plugin:GetSetting(SETTINGS_TUTORIAL_KEY) == true)) then return; end tutorialIndex = 1; updateTutorial(); tutorialLayer.Visible = true; tutorialCard.Position = UDim2.fromScale(0.5, 0.54); tween(tutorialCard, 0.22, {Position=UDim2.fromScale(0.5, 0.5)}, Enum.EasingStyle.Back); end tutorialSkip.MouseButton1Click:Connect(finishTutorial); tutorialNext.MouseButton1Click:Connect(function() if (tutorialIndex >= #tutorialSteps) then finishTutorial(); else tutorialIndex += 1 updateTutorial(); tutorialTitle.TextTransparency = 1; tutorialBody.TextTransparency = 1; tween(tutorialTitle, 0.18, {TextTransparency=0}); tween(tutorialBody, 0.18, {TextTransparency=0}); end end); helpButton.MouseButton1Click:Connect(function() showTutorial(true); end); local splash = make("Frame", {Name="LoadingSplash",Size=UDim2.fromScale(1, 1),BackgroundColor3=Color3.fromRGB(20, 25, 48),BorderSizePixel=0,ZIndex=100}, root); make("UIGradient", {Color=ColorSequence.new({ColorSequenceKeypoint.new(0, Color3.fromRGB(26, 30, 56)),ColorSequenceKeypoint.new(1, Color3.fromRGB(13, 20, 39))}),Rotation=90}, splash); local glow = make("Frame", {AnchorPoint=Vector2.new(0.5, 0.5),Position=UDim2.new(0.5, 0, 0.4, 0),Size=UDim2.fromOffset(180, 180),BackgroundColor3=C.cyan,BackgroundTransparency=0.94,BorderSizePixel=0,ZIndex=101}, splash); addCorner(glow, 100); local function makeSpinnerRing(diameter, segmentCount, radius, segmentWidth, segmentHeight, reverse) local ring = make("Frame", {AnchorPoint=Vector2.new(0.5, 0.5),Position=UDim2.new(0.5, 0, 0.4, 0),Size=UDim2.fromOffset(diameter, diameter),BackgroundTransparency=1,BorderSizePixel=0,ZIndex=103}, splash); for index = 1, segmentCount do local angle = ((index - 1) / segmentCount) * math.pi * 2; local x = ((diameter / 2) + (math.cos(angle) * radius)) - (segmentWidth / 2); local y = ((diameter / 2) + (math.sin(angle) * radius)) - (segmentHeight / 2); local alpha = 0.08 + (((index - 1) / segmentCount) * 0.68); local segment = make("Frame", {Position=UDim2.fromOffset(x, y),Size=UDim2.fromOffset(segmentWidth, segmentHeight),Rotation=(math.deg(angle) + 90),BackgroundColor3=C.cyan,BackgroundTransparency=alpha,BorderSizePixel=0,ZIndex=104}, ring); addCorner(segment, segmentWidth); end local targetRotation = (reverse and -360) or 360; local spin = TweenService:Create(ring, TweenInfo.new((reverse and 4.4) or 3.6, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1), {Rotation=targetRotation}); spin:Play(); return ring, spin; end local outerRing, outerSpin = makeSpinnerRing(132, 30, 55, 5, 15, false); local innerRing, innerSpin = makeSpinnerRing(92, 22, 37, 4, 11, true); local splashTitle = make("TextLabel", {AnchorPoint=Vector2.new(0.5, 0),Position=UDim2.new(0.5, 0, 0.66, 0),Size=UDim2.new(1, -30, 0, 30),BackgroundTransparency=1,Text=BRAND,TextColor3=C.text,Font=Enum.Font.GothamBlack,TextSize=17,ZIndex=105}, splash); local splashSub = make("TextLabel", {AnchorPoint=Vector2.new(0.5, 0),Position=UDim2.new(0.5, 0, 0.66, 32),Size=UDim2.new(1, -30, 0, 20),BackgroundTransparency=1,Text="INITIALIZING EXPLORER",TextColor3=C.cyanSoft,Font=Enum.Font.GothamMedium,TextSize=9,ZIndex=105}, splash); local splashBarBack = make("Frame", {AnchorPoint=Vector2.new(0.5, 0),Position=UDim2.new(0.5, 0, 0.66, 65),Size=UDim2.fromOffset(180, 3),BackgroundColor3=C.surface3,BorderSizePixel=0,ZIndex=105}, splash); addCorner(splashBarBack, 3); local splashBar = make("Frame", {Size=UDim2.new(0.08, 0, 1, 0),BackgroundColor3=C.cyan,BorderSizePixel=0,ZIndex=106}, splashBarBack); addCorner(splashBar, 3); tween(splashBar, 1.45, {Size=UDim2.new(1, 0, 1, 0)}, Enum.EasingStyle.Sine); tween(glow, 1.1, {BackgroundTransparency=0.9,Size=UDim2.fromOffset(205, 205)}, Enum.EasingStyle.Sine); local function updateCanvasSizes() tree.CanvasSize = UDim2.fromOffset(0, treeLayout.AbsoluteContentSize.Y + 8); propsScroll.CanvasSize = UDim2.fromOffset(0, propsLayout.AbsoluteContentSize.Y + 8); end treeLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(updateCanvasSizes); propsLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(updateCanvasSizes); setNavActive("Explorer"); showProperties(selected); refreshExplorer(); task.spawn(function() task.wait(2.15); if not splash.Parent then return; end local fadeInfo = TweenInfo.new(0.42, Enum.EasingStyle.Quint, Enum.EasingDirection.Out); for _, object in ipairs(splash:GetDescendants()) do if object:IsA("TextLabel") then TweenService:Create(object, fadeInfo, {TextTransparency=1}):Play(); elseif object:IsA("Frame") then TweenService:Create(object, fadeInfo, {BackgroundTransparency=1}):Play(); end end TweenService:Create(splash, fadeInfo, {BackgroundTransparency=1}):Play(); task.wait(0.45); if splash then splash:Destroy(); end if outerSpin then outerSpin:Cancel(); end if innerSpin then innerSpin:Cancel(); end if (plugin:GetSetting(SETTINGS_TUTORIAL_KEY) ~= true) then showTutorial(true); end end); plugin.Unloading:Connect(function() if outerSpin then outerSpin:Cancel(); end if innerSpin then innerSpin:Cancel(); end _G.__BETTER_DEX_STATUS = nil; _G.__BETTER_DEX_SHOW_MENU = nil; end); setStatus("Ready • " .. BRAND, C.cyan);