Mouse.Activate disruption by building script

Hi, I’m making a game where you can build but also shoot, attack… (by tools). The problem is when the game starts my building script starts working etc… And it uses raycast values a blacklist and the player mouse properties and functions. Everything works fine but my tools don’t wanna use there Tool.Activate function as long as the buildingscript is enabled and running. They’re both local scripts and my building script uses the strategy of “OOP” to communicate with the server.

Below the localscript of my tool: this script is used for an Axe to chop down trees. See vid file below the script.

local RS = game:GetService("ReplicatedStorage")
local RF = RS:WaitForChild("PropCropped")
local Player = game.Players.LocalPlayer

local STATS = script.Parent.Stats
local DMG = STATS.Dmg

local Tool = script.Parent
local Activatebool = true
local TargetGroup = "Tree"

local Mouse = Player:GetMouse()

if Player:FindFirstChild("EmoteName") then
	Player:FindFirstChild("EmoteName").Value = "Axe"
else
	print("no values found")
end
-- Sets name of the emote for another script to run player emotes.

Tool.Activated:Connect(function()
	local hit = Mouse.Target
	if hit and hit:FindFirstAncestorOfClass("Model") and hit:FindFirstAncestorOfClass("Model"):FindFirstChild("stats") and hit:FindFirstAncestorOfClass("Model").stats.TargetName.Value == TargetGroup and (hit:FindFirstAncestorOfClass("Model").PrimaryPart.Position - Player.Character.PrimaryPart.Position).Magnitude < 8 then
	--Checks so it cancels out air, the baseplate, other models than the mineable ones, 
	--and checks if the player is closer than 8 studs from the mineable object.	
		if Activatebool == true and hit:FindFirstAncestorOfClass("Model").stats.Mined.Value ~= true then
			Activatebool = false --checks if the object is already mined or not.
			if hit:FindFirstAncestorOfClass("Model").stats.HP.Value - DMG.Value > 0 then
				hit:FindFirstAncestorOfClass("Model").stats.HP.Value -= DMG.Value
			else
				RF:InvokeServer("Tree",hit,hit:FindFirstAncestorOfClass("Model").stats.DropAmount.Value,hit:FindFirstAncestorOfClass("Model").stats.PropName.Value)
				-- invokes server that the object (in this case a tree) is mined.
			end
			-- triggers the emotescript + adds time values to match the emote
			Player:FindFirstChild("EmoteTrigger").Value = not Player:FindFirstChild("EmoteTrigger").Value
			wait(1)
			if hit:FindFirstAncestorOfClass("Model").PrimaryPart:FindFirstChild("PE") and hit:FindFirstAncestorOfClass("Model").stats.HP.Value - DMG.Value > 0 then
				hit:FindFirstAncestorOfClass("Model").PrimaryPart:FindFirstChild("PE").Enabled = true
				wait(.3)
				hit:FindFirstAncestorOfClass("Model").PrimaryPart:FindFirstChild("PE").Enabled = false
			end
			wait(1)
			Activatebool = true
		end	
	end
end)

robloxapp-20230711-1525333.wmv (1.8 MB)

As you can see in the vid the chopping works fine without the building script. Once the building script is enabled the tool refuses to use it’s Tool.Activate function. Is there a way to let them co-work with each other?

Building local script:

-- player variables
local player = game.Players.LocalPlayer
local Char = player.Character

-- plot seeker
local myslot = nil
local canvas = nil
for _, slot in pairs(game.Workspace.Slots:GetChildren()) do
	if slot:FindFirstChild("PlotBuild") ~= nil and slot.Owner.Value == tostring(player.Name) then
		myslot = slot
		canvas = slot:WaitForChild("PlotBuild").Placementfloors["1"]
	end
end

-- Services
local replicatedStorage = game:GetService("ReplicatedStorage")
local runservice = game:GetService("RunService")
local UIS = game:GetService("UserInputService")

local remotes = game:GetService("ReplicatedStorage"):WaitForChild("Remotes")
local builds = game:GetService("ReplicatedStorage"):WaitForChild("Builds")

-- extern scripts
local placementClass = require(game:GetService("ReplicatedStorage"):WaitForChild("Placement"))
local placement = placementClass.fromSerialization(canvas, remotes.DSPlacement:InvokeServer(false, false))
placement.GridUnit = 10
-- Gui vars
local buildmenu = script.Parent:WaitForChild("BuildGui").BuildFrame
local closebuildGui = script.Parent:WaitForChild("BuildGui").BuildFrame.Close.TextButton
local switchbuildgui = script.Parent:WaitForChild("BuildGui").BuildButton.ImageButton
local lockscreen = script.Parent:WaitForChild("BuildGui").BuildFrame.Lockscreen
local anouncementtext = script.Parent.BuildGui.Anouncementtext
-- gui buttons
local movebutton = script.Parent.BuildGui.BuildFrame.Move
local sellbutton = script.Parent.BuildGui.BuildFrame.Sell
local storebutton = script.Parent.BuildGui.BuildFrame.Store
-- else
local Camera = workspace.CurrentCamera
local mouse = game.Players.LocalPlayer:GetMouse()
mouse.TargetFilter = placement.CanvasObjects
-- bool variables
local Hoverinstance = nil
local selectedbuild = nil
local Editmode = nil
local freeplacement = false
local model = nil
-- script values
local rotation = 0
-- extern values
local Build = script.Parent.BuildGui.BuildFrame.Build
local Category = script.Parent.BuildGui.BuildFrame.Cat
local trigger = script.Parent.BuildGui.BuildFrame.trigger
local freebuildTrigger = script.Parent:WaitForChild("BuildGui").BuildFrame.Freeplacement

-- lockscreen controller
local function enablelockscreen(bool)
	local InvF = buildmenu.InventoryFrame
	local WallF = buildmenu.WallFrame
	local FloorF = buildmenu.FloorFrame
	local WDF = buildmenu["Window/doorFrame"]
	local RoofF = buildmenu.ceilingFrame
	local LightsF = buildmenu.LightsFrame
	local TADF = buildmenu.TrapsAndDefenceFrame
	if model then
		model:Destroy()
		model = nil
	end
	if selectedbuild then
		if selectedbuild:FindFirstChild("Outline") ~= nil then
			selectedbuild.Outline.Visible = false
		end
	end
	if bool == true then
		buildmenu.framehandler.Enabled = false
		buildmenu.Close.Visible = false
		buildmenu.Inventory.Visible = false
		buildmenu.Materials.Visible = false
		buildmenu.MyfishFrame.Visible = false
		InvF.Visible = false
		WallF.Visible = false
		FloorF.Visible = false
		WDF.Visible = false
		RoofF.Visible = false
		LightsF.Visible = false
		TADF.Visible = false
		lockscreen.Visible = true
	elseif bool == false then
		buildmenu.framehandler.Enabled = true
		lockscreen.Visible = false
		buildmenu.Close.Visible = true
		buildmenu.Inventory.Visible = true
		buildmenu.Materials.Visible = true
		InvF.Visible = true
	end
end

local function WeldEnabler(newbuild)
	for _, w in pairs(newbuild.Welds:GetChildren()) do
		w.Enabled = true
	end
	if newbuild:FindFirstChild("SWelds") then
		for _, w in pairs(newbuild.SWelds:GetChildren()) do
			w.Enabled = true
		end
	end
end

-- build category seeker
local function setexcat(buildtocat)
	if tostring(buildtocat):match("W") then
		return "Walls"
	elseif tostring(buildtocat):match("F") then
		return "Floors"
	elseif tostring(buildtocat):match("RK") then
		return "TAD"
	elseif tostring(buildtocat):match("S") then
		return "TAD"
	elseif tostring(buildtocat):match("L") then
		return "Lights"
	elseif tostring(buildtocat):match("G") then
		return "WinAndDoors"
	elseif tostring(buildtocat):match("R") then
		return "Roofs"
	end
end

-- update the build guis function
local function updateinvGui()
	for _, v in pairs(script.Parent.Purchases:GetChildren()) do
		local frame = buildmenu.InventoryFrame.ScrollingFrame:FindFirstChild(v.Name)
		if frame then
			if v.Value ~= 0 and v.Value ~= nil then
				frame.TextLabel.Text = tostring(v.Value.."x")
				frame.Visible = true
			else
				frame.Visible = false
			end
		end
	end
end

-- build edit + position functions ---------------------------------

-- move function to Placementmodule
local function onSwitch(actionName, userInputState, input, inv)
	if (userInputState == Enum.UserInputState.Begin) then
		if inv == nil then
			if model then
				if model.Name ~= builds:FindFirstChild(Category.Value):FindFirstChild(Build.Value).Name then
					if (model) then
						model:Destroy()
						model = nil
					end
					model = builds:FindFirstChild(Category.Value):FindFirstChild(Build.Value):Clone()
					WeldEnabler(model)
					model.Parent = placement.CanvasObjects
				else
					model:Destroy()
					model = nil
				end
			else
				if selectedbuild then
					if selectedbuild:FindFirstChild("Outline") ~= nil then
						selectedbuild.Outline.Visible = false
					end
				end
				model = builds:FindFirstChild(Category.Value):FindFirstChild(Build.Value):Clone()
				WeldEnabler(model)
				model.Parent = placement.CanvasObjects
			end
		else
			model = selectedbuild
			model.Parent = placement.CanvasObjects
		end
	end
end
-- rotate build function 
local function onRotate(actionName, userInputState, input)
	if (userInputState == Enum.UserInputState.Begin) then
		rotation = rotation + math.pi/2
	end
end
-- place build function after mouseclick to Placementmodule
local function onPlace(actionName, userInputState, input)
	if model then
		if (userInputState == Enum.UserInputState.Begin) then
			local cf = placement:CalcPlacementCFrame(model, mouse.Hit.p, rotation)
			local price = model:FindFirstChild("Price").Value
			placement:Place(builds:FindFirstChild(setexcat(model.Name)):FindFirstChild(model.Name), cf, placement:isColliding(model), freeplacement, price, Editmode)
			if Editmode then
				model:Destroy()
				model = nil
				freeplacement = false
			end
			if not Editmode and player.PlayerGui.Purchases:FindFirstChild(model.Name).Value == 0 and freeplacement == true then
				model:Destroy()
				model = nil
				freeplacement = false
			end
			wait(.1)
			updateinvGui()
		end
	end
end
-- delete function to Placementmodule
local function onDelete(actionName, userInputState, input)
	if (userInputState == Enum.UserInputState.Begin) then
		if selectedbuild and selectedbuild:FindFirstChild("Price") then
			local price = selectedbuild:FindFirstChild("Price").Value
			placement:Remove(selectedbuild, true, price)
		else
			print("no build selected")
		end
	end
end
-- store function to Placementmodule
local function onStore(actionName, userInputState, input)
	if (userInputState == Enum.UserInputState.Begin) then
		if selectedbuild and selectedbuild:FindFirstChild("Price") then
			local price = selectedbuild:FindFirstChild("Price").Value
			placement:Remove(selectedbuild, false, nil)
		else
			print("no build selected")
		end
	end
end
--------------------------------------------------------------------


--[[local function onSave(actionName, userInputState, input)
	if (userInputState == Enum.UserInputState.Begin) then
		placement:Save()
	end
end]]-- disabled see line 227

-- triggers from outside the script (build trigger and free placement idicator) see "framehandler" playergui
trigger:GetPropertyChangedSignal("Value"):Connect(function()
	onSwitch(nil, Enum.UserInputState.Begin, nil, nil)
end)
freebuildTrigger:GetPropertyChangedSignal("Value"):Connect(function()
	freeplacement = true
end)
-- context actions
game:GetService("ContextActionService"):BindAction("rotate", onRotate, false, Enum.KeyCode.R)
game:GetService("ContextActionService"):BindAction("place", onPlace, false, Enum.UserInputType.MouseButton1)
--game:GetService("ContextActionService"):BindAction("Delete", onDelete, false, Enum.KeyCode.C) -- disabled no self plot wipe function needed "OnDelete" is in use for the deleting of builds
--game:GetService("ContextActionService"):BindAction("save", onSave, false, Enum.KeyCode.F) -- disabled no self save function needed

-- sets build cf + rotation
game:GetService("RunService").RenderStepped:Connect(function(dt)
	if model then
		local cf = placement:CalcPlacementCFrame(model, mouse.Hit.p, rotation)
		for _, v in pairs(model:GetChildren()) do
			if v:IsA("BasePart") then
				v.CanCollide = false
			end
		end
		model:SetPrimaryPartCFrame(cf)
	end
end)

-- buildmouseraycast + blacklist
local function MouseRayCast(blacklist)
	local MouseP = UIS:GetMouseLocation()
	local mouseRay = Camera:ViewportPointToRay(MouseP.X, MouseP.Y)
	local RayCastParams = RaycastParams.new()
	RayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
	RayCastParams.FilterDescendantsInstances = blacklist

	local raycastresult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction*1000, RayCastParams)
	return raycastresult
end

-- build grid enabler
local function showbuildpads(val)
	for _, slot in pairs(game.Workspace.Slots:GetChildren()) do
		if slot:FindFirstChild("PlotBuild") ~= nil and slot.Owner.Value == tostring(game.Players.LocalPlayer.Name) then
			myslot = slot
			for _, buildfloor in pairs(slot:FindFirstChild("PlotBuild").Placementfloors:GetChildren()) do
				if buildfloor.Owned.Value == true then
					buildfloor.BuildGrid.Transparency = val
				end
			end
		end
	end
end

-- edit connecter
UIS.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	if Hoverinstance and input.KeyCode == Enum.KeyCode.E then
		local model = Hoverinstance:FindFirstAncestorOfClass("Model")

		if model and buildmenu.Visible == true then
			selectedbuild = model
			if Editmode then
				if Editmode == "Move" then
					onSwitch(nil, Enum.UserInputState.Begin, nil, true)
					freeplacement = true
				elseif Editmode == "Sell" then
					onDelete(nil, Enum.UserInputState.Begin, nil)
				elseif Editmode == "Store" then	
					onStore(nil, Enum.UserInputState.Begin, nil)
				end
			end
		else
			selectedbuild = nil
		end
	end

end)

-- build tool disabler + mouseraycast
local slotspawn = nil
runservice.RenderStepped:Connect(function()	
	
	-- disables builds tool outside plot
	for _, slot in pairs(game.Workspace.Slots:GetChildren()) do
		if slot:FindFirstChild("PlotBuild") ~= nil and slot.Owner.Value == tostring(game.Players.LocalPlayer.Name) then
			slotspawn = slot.Spawn
			if (player.Character.HumanoidRootPart.Position - slot:FindFirstChild("PlotBuild").Placementfloors:FindFirstChild("1").Position).Magnitude <= 350 then
				switchbuildgui.Parent.Visible = true
			else
				switchbuildgui.Parent.Visible = false
				closebuildGui.Parent.Parent.Visible = false
			end
		end
	end
	
	-- outline resetter + mouseraycast
	local IgnoreTable = {Char, slotspawn}
	local result = MouseRayCast(IgnoreTable)
	if result and result.Instance and Editmode then
		Hoverinstance = result.Instance
	else
		Hoverinstance = nil
	end
end)

-- edit functions ------------------------------
movebutton.MouseButton1Down:Connect(function()
	if Editmode == "Move" then
		Editmode = nil
		enablelockscreen(false)
	else
		Editmode = "Move"
		enablelockscreen(true)
	end
end)

sellbutton.MouseButton1Down:Connect(function()
	if Editmode == "Sell" then
		Editmode = nil
		enablelockscreen(false)
	else
		Editmode = "Sell"
		enablelockscreen(true)
	end
end)

storebutton.MouseButton1Down:Connect(function()
	if Editmode == "Store" then
		Editmode = nil
		enablelockscreen(false)
	else
		Editmode = "Store"
		enablelockscreen(true)
	end
end)
------------------------------------------------

-- close button
closebuildGui.MouseButton1Down:Connect(function()
	showbuildpads(1)
	if model then
		model:Destroy()
		model = nil
	end
	if selectedbuild then
		if selectedbuild:FindFirstChild("Outline") ~= nil then
			selectedbuild.Outline.Visible = false
		end
	end
	freeplacement = false
	enablelockscreen(false)
end)

-- switchbutton + resets script
switchbuildgui.MouseButton1Down:Connect(function()
	if buildmenu.Visible == true then
		showbuildpads(1)
		enablelockscreen(false)
		script.Disabled = true
		script.Disabled = false
	else
		showbuildpads(0)
	end
end)

Vid to illustrate the building mechanism:

robloxapp-20230711-1538014.wmv (3.7 MB)

It’s a lot of reading work so I want to thank you for your time.

1 Like

Jesus, why such a long one line of code?

2 Likes

yes I can make it a lot shorter it’s still a draft tho.

Does the Tool.Activate stop functioning when you enable the Build script, or does it work up until you do something? Does the Tool.Activate function start working later, maybe if you disable the build script again?

(Maybe it was more clear in the video but I can’t watch it right now)

1 Like

When I Disable the BuildScript before playing the game the tool.Activate works, when it’s enabled when the game starts the tool.activate doesn’t work, I can disable the buildscript during the game from the server but it won’t change, the tool.activate still remains broken once the building script has been activated in that game play session.

The build script is enabled from the start (when the plr joins the game) so the plr can build.

Can u use mutiple Mouse.hit or raycasts at the same time in different scripts? Maby this is the problem?

1 Like

I am guessing this is the part you are having troubles with. It takes the place of mouse click, and even when you exit building mode, the action will still be bound.

3 Likes

Thank you very much, this was indeed the problem XD.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.