Plugin mouse bug

Yesterday I coded a building plugin that spawns a part on the user’s mouse and when clicked it places a part, it all worked until I clicked on the select tool where it stops working all together where only the gui buttons remove the part but no moving is done anymore.
The only way I have found so far to avoid this is disabling the plugin function(disabling it by the button on its own gui) and then closing the gui and only then selecting the select tool

local CoreGui = game:GetService(“CoreGui”)

local plg = plugin
plg :Activate(true)
local pluginToolbar = plg:CreateToolbar(“Plugin”)

local pluginToolbarButton = pluginToolbar:CreateButton(
“Open Test Plugin”,
“Click to toggle the plugin UI”,
“rbxassetid://13761772453”
)

local pluginUI = script.Parent
local buildingPlugin = pluginUI.Parent

local mouse = plg:GetMouse()

local predictionPart = pluginUI.PredictPartRef.Value
local blockSize = predictionPart.Size.X – Assume cubic
local frame = pluginUI.Frame
local enabled = frame.Enable
local custom = frame.Customize
local texture = frame.Texture
local texturing = false
local gPart = script.Parent.ghostpart

local building = false
local isCustomEnabled = false
local active = false

–When plugin is selected add it to the hierarchy otherwise remove it
local function onClick()
if active then

  pluginUI.Enabled = false
  active = false
  pluginUI.Parent = buildingPlugin

else

  pluginUI.Enabled = true
  
  active = true
  pluginUI.Parent = CoreGui

end
– plg:Activate(active)

end

pluginToolbarButton.Click:Connect(onClick)

local function snap(vector3)
local posX = math.ceil(vector3.X/ blockSize - .5) *blockSize
local posY = math.round(vector3.Y/ blockSize - .5) *blockSize+ (0.5 * blockSize)
local posZ = math.ceil(vector3.Z/ blockSize - .5) *blockSize
return Vector3.new(posX, posY, posZ)
end

– Check if user is currently placing a block. If true then have the part be semi transparent
local function ghostPart()
if building == true then
local unitRay = workspace.Camera:ViewportPointToRay(mouse.X,mouse.Y)
local params = RaycastParams.new() --Rewrite!! Creates a new object each time the mouse is moved
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {predictionPart,gPart}
local raycastResult = workspace:Raycast(unitRay.Origin,unitRay.Direction500, params)
if raycastResult then
local position = snap(raycastResult.Position + raycastResult.Normal * (blockSize
0.5))
gPart.Position = position
predictionPart.Position = gPart.Position
end
end
end

local function toggleBuild()
print(building) --REMOVE
if not building then

  building = true
  gPart.Parent = workspace
  frame.Enable.Text = "X"

else

  building = false
  gPart.Parent = buildingPlugin
  frame.Enable.Text = ""

end
end
–If the custom button is enabled modify the values to use the below values instead
local function customEnabled(color, material, reflectance, transparent, enabled)
color = if (color == “”) then “100,100,0” else color
material = if (material == “”) then “SmoothPlastic” else material
reflectance = 0 or reflectance
transparent = 0 or transparent
print(color)
if enabled then
isCustomEnabled = not isCustomEnabled
custom.Text = “X”
local colors = string.split(color, “,”)

  predictionPart.Color = Color3.fromRGB(colors[1],colors[2],colors[3])
  predictionPart.Material = Enum.Material[material]
  predictionPart.Reflectance = reflectance
  predictionPart.Transparency = transparent

else
custom.Text = “”
end
end

frame.Color.FocusLost:Connect(function()customEnabled(frame.Color.Text,frame.Material.Text,frame.Reflectance.Text,frame.Transparent.Text, true) end)

custom.Activated:Connect(function() customEnabled(frame.Color.Text,frame.Material.Text,frame.Reflectance.Text,frame.Transparent.Text, not isCustomEnabled) end)

frame.Texture.MouseButton1Click:Connect(function()
if not texturing then
texturing = true
frame.Texture.Text = “X”
print(texturing)
else
texturing = false
frame.Texture.Text = “”
print(texturing)
end
end)

if texturing == true then
local hue, saturation, value = predictionPart.Color:ToHSV()
saturation = math.clamp(saturation+math.random(-15,15)*0.005,0,1)

local saturate = Color3.fromHSV(hue,saturation,value)
predictionPart.Color = saturate

end

local function place()
if building == true then
print(“Part was placed”)
local placedPart = predictionPart:Clone()
print(placedPart.Name)
placedPart.Parent = workspace
end
end

pluginUI.Frame.Enable.MouseButton1Click:Connect(toggleBuild)
mouse.Move:Connect(ghostPart)
mouse.Button1Down:Connect(place)

Any help will be appreciated!

1 Like

In the place function, you’re cloning the predictionPart into placedPart, but then you’re not setting its position. You need to set the position of the placed part before parenting it to the workspace.

Update the place function like this:

local function place()
    if building == true then
        print("Part was placed")
        local placedPart = predictionPart:Clone()
        placedPart.Position = snap(gPart.Position)
        placedPart.Parent = workspace
    end
end

This will set the position of the placed part before parenting it to the workspace, it ensures that the part is correctly positioned and should work consistently, even when switching to the select tool. The position of the part is determined by the snap function, which helps in accurate placement.

The problem is not really that, after selecting the select tool, the plugin stops working completely, only being fixed when re saving the plugin.

Make sure that you are disconnecting any unnecessary or unused events when the plugin is deactivated or not in use. For example, if there are event listeners attached to the mouse object, make sure to disconnect them when the plugin is deactivated.

For example

-- Disconnect events when the plugin is deactivated
plg.Deactivation:Connect(function()
    mouse.Move:Disconnect()
    mouse.Button1Down:Disconnect()
    -- Disconnect any other events if present
end)

Double-check the activation and deactivation process

Add print statements to try and trace the problem.