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.
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)
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
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
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)
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.
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)
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)