Help with mining system

So I have a pickaxe for mining blocks but one problem is that it keeps destroying and creating a new selection box.

The pickaxe is an accessory.

It works normally with a wait here:

task.wait(0.1)
if (not isMouseTargetValid and newBreakSelectionBox) or not mouseTarget then
	removeBreakSelectionBox()
	selectedBlock = nil
end

but I don’t want that.

Client Script:

RunService.Heartbeat:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	for i,v in ipairs(BreakableBlocks) do
		if mouseTarget == v then
			local distance = (v.Position - character.PrimaryPart.Position).Magnitude

			if distance <= breakRange then
				isMouseTargetValid = true

				if selectedBlock ~= v then
					removeBreakSelectionBox()
				end

				selectedBlock = v

				if not newBreakSelectionBox then
					newBreakSelectionBox = BreakSelectionBox:Clone()
					newBreakSelectionBox.Adornee = v
					newBreakSelectionBox.Visible = true
					newBreakSelectionBox.Parent = v
				end
			end
		end
	end

	if (not isMouseTargetValid and newBreakSelectionBox) or not mouseTarget then
		removeBreakSelectionBox()
		selectedBlock = nil
	end

	mouse.TargetFilter = mouseTarget
end)

The pickaxe works when putting it in StarterCharacterScripts, but when cloning and parenting to the character, it doesn’t work correctly.


Any fixes?

Any help appreciated.

1 Like

It’s a little difficult to debug this without the entire script.

1 Like

The entire script is a bit long but here is another part of it:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local selectedBlock = nil

local function removeBreakSelectionBox()
	if newBreakSelectionBox then
		newBreakSelectionBox:Destroy()
		newBreakSelectionBox = nil
	end
end

RunService.Heartbeat:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	for i,v in ipairs(BreakableBlocks) do -- Tags (plugin)
		if mouseTarget == v then
			local distance = (v.Position - character.PrimaryPart.Position).Magnitude

			if distance <= breakRange then
				isMouseTargetValid = true

				if selectedBlock ~= v then
					removeBreakSelectionBox()
				end

				selectedBlock = v

				if not newBreakSelectionBox then
					newBreakSelectionBox = BreakSelectionBox:Clone()
					newBreakSelectionBox.Adornee = v
					newBreakSelectionBox.Visible = true
					newBreakSelectionBox.Parent = v
				end
			end
		end
	end

	if (not isMouseTargetValid and newBreakSelectionBox) or not mouseTarget then
		removeBreakSelectionBox()
		selectedBlock = nil
	end

	mouse.TargetFilter = mouseTarget
end)
1 Like

you can try something like:

if distance <= breakRange then
if not isMouseTargetValid then
				isMouseTargetValid = true

				if selectedBlock ~= v then
					removeBreakSelectionBox()
				end

				selectedBlock = v

				if not newBreakSelectionBox then
					newBreakSelectionBox = BreakSelectionBox:Clone()
					newBreakSelectionBox.Adornee = v
					newBreakSelectionBox.Visible = true
					newBreakSelectionBox.Parent = v
				end
			end
end

Not sure if it works, kinda hard to tell there.

1 Like

So judging by this you’re actually using a Model or Part as the selection box correct? I assumed you were using Roblox’s SelectionBox

I’m using Roblox’s Selectionbox.

This doesn’t work, same result.

Why are you destroying and cloning the selection box? Just set the Adornee to nil

But wouldn’t that make it glitch still?

do you use models or parts for the selection thing

The Selectionbox:
image

Let me show you an example:

RunService.Heartbeat:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	for i,v in ipairs(BreakableBlocks) do
		if mouseTarget == v then
			local distance = (v.Position - character.PrimaryPart.Position).Magnitude

			if distance <= breakRange then
				isMouseTargetValid = true ------- sets it true

				if selectedBlock ~= v then
					removeBreakSelectionBox()
				end

				selectedBlock = v

				if not newBreakSelectionBox then
					newBreakSelectionBox = BreakSelectionBox:Clone()
					newBreakSelectionBox.Adornee = v
					newBreakSelectionBox.Visible = true
					newBreakSelectionBox.Parent = v
				end
			end
		end
	end

	if (not isMouseTargetValid and newBreakSelectionBox) or not mouseTarget then
		
		print(isMouseTargetValid) ------- prints false???????
		
		removeBreakSelectionBox()
		selectedBlock = nil
	end

	mouse.TargetFilter = mouseTarget
end)

I think the problem is that you’re setting the mouse.TargetFilter to the object you’re hovering over which results in your mouse.Target returning the object behind the block which deletes the SelectionBox

It still doesn’t seem to solve it:

RunService.Heartbeat:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	for i,v in ipairs(BreakableBlocks) do
		if mouseTarget == v and selectedBlock ~= v then
			local distance = (v.Position - character.PrimaryPart.Position).Magnitude

			if distance <= breakRange then
				isMouseTargetValid = true

				if selectedBlock ~= v then
					removeBreakSelectionBox()
				end

				selectedBlock = v

				if not newBreakSelectionBox then
					newBreakSelectionBox = BreakSelectionBox:Clone()
					newBreakSelectionBox.Adornee = v
					newBreakSelectionBox.Visible = true
					newBreakSelectionBox.Parent = v
				end
			end
		else
			mouse.TargetFilter = mouseTarget
		end
	end

	if (not isMouseTargetValid and newBreakSelectionBox) or not mouseTarget then
		removeBreakSelectionBox()
		selectedBlock = nil
	end
end)

I modified your script.

function DoesBlockExist(block)
	for _,v in pairs(BreakableBlocks) do
		if v == block then
			return true
		end
	end
	return false
end

RunService.RenderStepped:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	if not DoesBlockExist(mouseTarget) then
		SelectionBox.Adornee = nil
		selectedBlock = nil
		return
	end
	
	local distance = (mouseTarget.Position - character.PrimaryPart.Position).Magnitude
	if distance <= breakRange then
		isMouseTargetValid = true

		if selectedBlock ~= mouseTarget then
			SelectionBox.Adornee = nil
		end

		selectedBlock = mouseTarget
		SelectionBox.Adornee = mouseTarget
	end
end)

Note I think it might be better practice to define the Character inside the loop as it might break if the player resets.

1 Like

Also these were my variables at the top of the script. I just put them together roughly as I didn’t have your full script:

local RunService = game:GetService("RunService");
local Players = game:GetService("Players");

local Player = Players.LocalPlayer
local mouse = Player:GetMouse();

local BreakableBlocks = workspace:WaitForChild("Blocks"):GetChildren()

local breakRange = 100
local SelectionBox = Instance.new("SelectionBox",Player.PlayerGui);
local selectedBlock

Another problem now is that if you walk too far away from the block and also hovering over the part, the selection box is still visible.

local function checkIfMinable(block)
	for i,v in ipairs(BreakableBlocks) do
		if v == block then
			return true
		end
	end
	return false
end

RunService.RenderStepped:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	if not checkIfMinable(mouseTarget) then
		BreakSelectionBox.Adornee = nil
		selectedBlock = nil
		return
	end

	local distance = (mouseTarget.Position - character.PrimaryPart.Position).Magnitude

	if distance <= breakRange then
		isMouseTargetValid = true

		if selectedBlock ~= mouseTarget then
			BreakSelectionBox.Adornee = nil
		end

		selectedBlock = mouseTarget
		BreakSelectionBox.Adornee = mouseTarget
	end
end)

Can add an else to that if statement:

if distance <= breakRange then
	isMouseTargetValid = true

	if selectedBlock ~= mouseTarget then
		BreakSelectionBox.Adornee = nil
	end

	selectedBlock = mouseTarget
	BreakSelectionBox.Adornee = mouseTarget
else
	BreakSelectionBox.Adornee = nil
	selectedBlock = nil
end

That should make it remove the SelectionBox when you walk too far away

just add

if distance <= breakRange then
		isMouseTargetValid = true

		if selectedBlock ~= mouseTarget then
			BreakSelectionBox.Adornee = nil
		end

		selectedBlock = mouseTarget
		BreakSelectionBox.Adornee = mouseTarget
else
-- Set Adornee to nil
	end

Ok, now something is broken in this script. It only sometimes work.

local function checkIfMinable(block)
	for i,v in ipairs(BreakableBlocks) do
		if v == block then
			return true
		end
	end
	return false
end

RunService.RenderStepped:Connect(function()
	local mouseTarget = mouse.Target
	local isMouseTargetValid = false

	if not checkIfMinable(mouseTarget) then
		BreakSelectionBox.Adornee = nil
		selectedBlock = nil
		return
	end

	local distance = (mouseTarget.Position - character.PrimaryPart.Position).Magnitude

	if distance <= breakRange then
		isMouseTargetValid = true

		if selectedBlock ~= mouseTarget then
			BreakSelectionBox.Adornee = nil
		end

		selectedBlock = mouseTarget
		BreakSelectionBox.Adornee = mouseTarget
	else
		BreakSelectionBox.Adornee = nil
		selectedBlock = nil
	end
end)