Advertisement
Guest User

Face Selector Plugin Source Code

a guest
Nov 9th, 2021
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.21 KB | None | 0 0
  1. local toolbar = plugin:CreateToolbar("Face Selector")
  2. local button = toolbar:CreateButton("Part Face Selector", "Shows selected face of models and baseparts. Can also display directional vectors.", "rbxassetid://5602410390")
  3. local mouse = plugin:GetMouse()
  4.  
  5. local runService = game:GetService("RunService")
  6. local selection = game:GetService("Selection")
  7. local coreGUI = game:GetService("CoreGui")
  8.  
  9. local gColor = Enum.StudioStyleGuideColor
  10. local gModifier = Enum.StudioStyleGuideModifier
  11. local v3 = Vector3.new
  12. local abs = math.abs
  13.  
  14. local connections = {}
  15.  
  16. local retrievedActive = plugin:GetSetting("active") or true
  17. local retrievedShowDirectionalVectors = plugin:GetSetting("showDirectionalVectors") or false
  18. local retrievedDynamicHighlight = plugin:GetSetting("dynamicHighlight") or true
  19. local retrievedHightlightThickness = plugin:GetSetting("highlightThickness") or 0.15
  20.  
  21. local state = {
  22.     selectedFace = nil,
  23.     currentlySelected = nil,
  24.     binded = false,
  25.     selectedObjectEvent = nil,
  26.     setting = {
  27.         active = retrievedActive,
  28.         showDirectionalVectors = retrievedShowDirectionalVectors,
  29.         dynamicHighlight = retrievedDynamicHighlight,
  30.         highlightThickness = retrievedHightlightThickness,
  31.     }
  32. }
  33.  
  34.  
  35. local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, false, 200, 400, 0, 100)
  36. local WIDGET = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)
  37. WIDGET.Title = "Select Face"
  38. local gui = script.MainBackground
  39. gui.Parent = WIDGET
  40. local visuals = script.FaceSelectorVisuals
  41. visuals.Parent = coreGUI
  42. local faces = visuals.Face
  43. local direction = visuals.Direction
  44.  
  45.  
  46.  
  47. local function getUIColor(guideColor, guideModifier)
  48.     return settings().Studio.Theme:GetColor(gColor[guideColor], gModifier[guideModifier or "Default"])
  49. end
  50.  
  51. local function updatePluginTheme()
  52.     gui.BackgroundColor3 = getUIColor("MainBackground")
  53.     gui.BorderColor3 = getUIColor("Border")
  54.     gui.ScrollContainer.BorderColor3 = getUIColor("Border")
  55.     gui.ScrollContainer.ScrollBarImageColor3 = getUIColor("Dark")
  56.     local cont = gui.ScrollContainer
  57.     cont.ActiveGui.Text.TextColor3 = getUIColor("MainText")
  58.     cont.ActiveGui.CheckBox.BackgroundColor3 = getUIColor("Dark")
  59.     cont.ActiveGui.CheckBox.Display.BackgroundColor3 = getUIColor("Button", "Selected")--Color3.fromRGB(0, 162, 255)
  60.     cont.FaceSelectorBackground.BackgroundColor3 = getUIColor("Shadow")
  61.     for _, ui in pairs(cont.FaceSelectorBackground.FaceSelector:GetChildren()) do
  62.         if ui.ClassName ~= "UIListLayout" then
  63.             local typ = ui.Name == state.selectedFace and "Selected" or "Default"
  64.             ui.BackgroundColor3 = getUIColor("RibbonButton", typ)
  65.             ui.TextColor3 = getUIColor("MainText")
  66.             ui.BorderColor3 = getUIColor("Border", "Default")
  67.         end
  68.     end
  69.     for _, ui in pairs(cont.CheckBoxes:GetChildren()) do
  70.         if ui.ClassName ~= "UIListLayout" then
  71.             if ui:FindFirstChild("CheckBox") then
  72.                 ui.Text.TextColor3 = getUIColor("MainText")
  73.                 ui.CheckBox.BackgroundColor3 = getUIColor("Dark")
  74.                 ui.CheckBox.Display.BackgroundColor3 = getUIColor("Button", "Selected")
  75.             elseif ui:FindFirstChild("TextBox") then
  76.                 ui.Text.TextColor3 = getUIColor("MainText")
  77.                 ui.TextBox.TextColor3 = getUIColor("MainText")
  78.                 ui.TextBox.BackgroundColor3 = getUIColor("DialogButton")
  79.                 ui.TextBox.BorderColor3 = getUIColor("Border")
  80.             else
  81.                 for _, folder in pairs(ui:GetChildren()) do
  82.                     for _, text in pairs(folder:GetChildren()) do
  83.                         text.TextColor3 = getUIColor("MainText")
  84.                     end
  85.                 end
  86.             end
  87.         end
  88.     end
  89. end
  90. updatePluginTheme()
  91.  
  92. local function withinBounds(obj)
  93.     local tx,ty = obj.AbsolutePosition.X, obj.AbsolutePosition.Y
  94.     local bx,by = tx + obj.AbsoluteSize.X, ty + obj.AbsoluteSize.Y
  95.     return (mouse.X >= tx and mouse.X <= bx and mouse.Y >= ty and mouse.Y <= by)
  96. end
  97.  
  98. local function getObjSize()
  99.     local objCFrame, objSize
  100.     if state.currentlySelected:IsA("Model") then
  101.         return state.currentlySelected:GetBoundingBox()
  102.     elseif state.currentlySelected:IsA("BasePart") then
  103.         return state.currentlySelected.CFrame, state.currentlySelected.Size
  104.     end
  105. end
  106.  
  107. local function updateLookVectorText(update)
  108.     if update then
  109.         for _,t in pairs(gui.ScrollContainer.CheckBoxes.Vectors:GetChildren()) do
  110.             local vector = getObjSize()[t.Name]
  111.             for _,d in pairs(t:GetChildren()) do
  112.                 if d.Name ~= "Text" then
  113.                     d.Text = string.sub(tostring(vector[d.Name]), 0, 6)
  114.                 end
  115.             end
  116.         end
  117.     else
  118.         for _,t in pairs(gui.ScrollContainer.CheckBoxes.Vectors:GetChildren()) do
  119.             for _,d in pairs(t:GetChildren()) do
  120.                 if d.Name ~= "Text" then
  121.                     d.Text = ""
  122.                 end
  123.             end
  124.         end
  125.     end
  126. end
  127.  
  128. local faceOffsets = {
  129.     Back = v3(0,0,1),
  130.     Bottom = v3(0,-1,0),
  131.     Front = v3(0,0,-1),
  132.     Left = v3(-1,0,0),
  133.     Right = v3(1,0,0),
  134.     Top = v3(0,1,0),
  135. }
  136. local targfaces = {"Top", "Bottom", "Left", "Right"}
  137.  
  138. function updateFaceAdornees(objSize)
  139.     if state.selectedFace then
  140.         local index = 1
  141.         for i,v in pairs(faceOffsets) do
  142.             if v:Cross(faceOffsets[state.selectedFace]) ~= v3() then
  143.                 local targetAdornee = faces[targfaces[index]]
  144.                 targetAdornee.Adornee = state.currentlySelected
  145.                 local targOffset = faceOffsets[state.selectedFace] + v
  146.                 targetAdornee.SizeRelativeOffset = targOffset
  147.                 local ts = v:Cross(faceOffsets[state.selectedFace])
  148.                 local min_size = math.min(objSize.X, objSize.Y, objSize.Z)
  149.                 local thick
  150.                 if state.setting.dynamicHighlight then
  151.                     thick = math.max(0.05 * min_size,0.05)
  152.                 else
  153.                     thick = state.setting.highlightThickness
  154.                 end
  155.                 targetAdornee.Size = v3(abs(ts.X) * objSize.X + thick, abs(ts.Y) * objSize.Y + thick, abs(ts.Z) * objSize.Z + thick)
  156.                 index = index + 1
  157.             end
  158.         end
  159.     else
  160.         for i,v in pairs(targfaces) do
  161.             local targetAdornee = faces[v]
  162.             targetAdornee.Adornee = nil
  163.         end
  164.     end
  165. end
  166.  
  167. local function updateObject()
  168.     if state.currentlySelected then
  169.         local objCFrame, objSize = getObjSize()
  170.         updateFaceAdornees(objSize)
  171.         updateLookVectorText(true)
  172.         local targetSize = math.max(objSize.X, objSize.Y, objSize.Z)
  173.         for i,v in pairs(direction:GetChildren()) do
  174.             v.Adornee = state.currentlySelected
  175.         end
  176.         direction.lookVector.Size = v3(0.1, 0.1, targetSize)
  177.         direction.lookVector.SizeRelativeOffset = v3(0, 0, -targetSize/objSize.Z)
  178.         direction.rightVector.Size = v3(targetSize, 0.1, 0.1)
  179.         direction.rightVector.SizeRelativeOffset = v3(targetSize/objSize.X, 0, 0)
  180.         direction.upVector.Size = v3(0.1, targetSize, 0.1)
  181.         direction.upVector.SizeRelativeOffset = v3(0, targetSize/objSize.Y, 0)
  182.     else
  183.         for i,v in pairs(targfaces) do
  184.             faces[v].Adornee = nil
  185.         end
  186.         for i,v in pairs(direction:GetChildren()) do
  187.             v.Adornee = nil
  188.         end
  189.         updateLookVectorText(false)
  190.     end
  191. end
  192.  
  193. local function connectSelectionChanged()
  194.     for i,v in pairs(selection:Get()) do
  195.         if v:IsA("BasePart") or v:IsA("Model") then
  196.             state.currentlySelected = v
  197.             updateObject()
  198.             state.selectedObjectEvent = state.currentlySelected.Changed:Connect(updateObject)
  199.             break
  200.         end
  201.     end
  202.     updateLookVectorText(state.currentlySelected ~= nil)
  203.     table.insert(connections, selection.SelectionChanged:Connect(function()
  204.         state.currentlySelected = nil
  205.         for i,v in pairs(selection:Get()) do
  206.             if v:IsA("BasePart") or v:IsA("Model") then
  207.                 state.currentlySelected = v
  208.                 updateObject()
  209.                 state.selectedObjectEvent = state.currentlySelected.Changed:Connect(updateObject)
  210.                 break
  211.             end
  212.         end
  213.         if not state.currentlySelected then
  214.             if state.selectedObjectEvent then
  215.                 state.selectedObjectEvent:Disconnect()
  216.                 state.selectedObjectEvent = nil
  217.             end
  218.             updateObject()
  219.         end
  220.     end))
  221. end
  222.  
  223. local function updateActive()
  224.     local transparency = state.setting.active and 0.5 or 1
  225.     gui.ScrollContainer.ActiveGui.CheckBox.Display.Visible = state.setting.active
  226.     for _,ad in pairs(visuals.Face:GetChildren()) do
  227.         ad.Transparency = transparency
  228.     end
  229.     for _,ad in pairs(visuals.Direction:GetChildren()) do
  230.         ad.Transparency = (state.setting.active and state.setting.showDirectionalVectors) and 0.5 or 1
  231.     end
  232. end
  233.  
  234. local function updateVectors()
  235.     gui.ScrollContainer.CheckBoxes.ShowVectors.CheckBox.Display.Visible = state.setting.showDirectionalVectors
  236.     local transparency = (state.setting.showDirectionalVectors and state.setting.active) and 0.5 or 1
  237.     for _,ad in pairs(visuals.Direction:GetChildren()) do
  238.         ad.Transparency = transparency
  239.     end
  240. end
  241.  
  242. local function updateDynamicHighlight()
  243.     gui.ScrollContainer.CheckBoxes.DynamicHighlight.CheckBox.Display.Visible = state.setting.dynamicHighlight
  244.     if state.currentlySelected then
  245.         local objCFrame, objSize = getObjSize()
  246.         updateFaceAdornees(objSize)
  247.     end
  248. end
  249.  
  250. local function updateHighlightThickness(high_thick)
  251.     local success, err = pcall(function()
  252.         local target_thickness = tonumber(high_thick.Text)
  253.         if target_thickness ~= nil then
  254.             if target_thickness >= 0 then
  255.                 state.setting.highlightThickness = target_thickness
  256.                 plugin:SetSetting("highlightThickness", target_thickness)
  257.                 if state.currentlySelected then
  258.                     local objCFrame, objSize = getObjSize()
  259.                     updateFaceAdornees(objSize)
  260.                 end
  261.             else
  262.                 high_thick.Text = state.setting.highlightThickness
  263.             end
  264.         else
  265.             high_thick.Text = state.setting.highlightThickness
  266.         end
  267.     end)
  268. end
  269.  
  270. local function faceSelectorClickConnection()
  271.     local faceSelector = gui.ScrollContainer.FaceSelectorBackground.FaceSelector
  272.     for _, ui in pairs(faceSelector:GetChildren()) do
  273.         if ui.ClassName ~= "UIListLayout" then
  274.             table.insert(connections, ui.MouseButton1Click:Connect(function()
  275.                 if faceSelector:FindFirstChild(state.selectedFace or "") then
  276.                     faceSelector[state.selectedFace].BackgroundColor3 = getUIColor("RibbonButton", "Default")
  277.                     faceSelector[state.selectedFace].TextColor3 = getUIColor("MainText", "Default")
  278.                 end
  279.                 if ui.Name ~= state.selectedFace then
  280.                     state.selectedFace = ui.Name
  281.                     ui.BackgroundColor3 = getUIColor("RibbonButton", "Selected")
  282.                     ui.TextColor3 = getUIColor("MainText")
  283.                 else
  284.                     state.selectedFace = nil
  285.                 end
  286.                 updateObject()
  287.             end))
  288.         end
  289.     end
  290. end
  291.  
  292. settings().Studio.ThemeChanged:Connect(updatePluginTheme)
  293. local high_thick = gui.ScrollContainer.CheckBoxes.HighlightThickness.TextBox
  294.  
  295. connectSelectionChanged()
  296. faceSelectorClickConnection()
  297. updateActive()
  298. updateVectors()
  299. updateDynamicHighlight()
  300. high_thick.Text = state.setting.highlightThickness
  301. table.insert(connections, gui.ScrollContainer.ActiveGui.CheckBox.MouseButton1Click:Connect(function()
  302.     state.setting.active = not state.setting.active
  303.     plugin:SetSetting("active", state.setting.active)
  304.     updateActive()
  305. end))
  306. table.insert(connections, gui.ScrollContainer.CheckBoxes.ShowVectors.CheckBox.MouseButton1Click:Connect(function()
  307.     state.setting.showDirectionalVectors = not state.setting.showDirectionalVectors
  308.     plugin:SetSetting("showDirectionalVectors", state.setting.showDirectionalVectors)
  309.     updateVectors()
  310. end))
  311. table.insert(connections, gui.ScrollContainer.CheckBoxes.DynamicHighlight.CheckBox.MouseButton1Click:Connect(function()
  312.     state.setting.dynamicHighlight = not state.setting.dynamicHighlight
  313.     plugin:SetSetting("dynamicHighlight", state.setting.dynamicHighlight)
  314.     updateDynamicHighlight()
  315. end))
  316.  
  317. table.insert(connections, high_thick.FocusLost:Connect(function()
  318.     updateHighlightThickness(high_thick)
  319. end))
  320.  
  321.  
  322. button.Click:connect(function()
  323.     WIDGET.Enabled = true
  324. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement