Bridge system glitches when mouse is on top of block

The name says it all. I have a bridging system similar to Minecraft Bedrock edition and when you’re bridging the game thinks you are building on top.

Video of glitch:

My code:

wait()

local camera = workspace.CurrentCamera

local players = game:GetService("Players")
local uis = game:GetService("UserInputService")
local reps = game:GetService("ReplicatedStorage")
local rs = game:GetService("RunService")
local player = players.LocalPlayer
local tool = script.Parent
local parts = reps:WaitForChild("Parts")
local outline = parts.Outline:clone()
local block = parts.Block
local lastblock = nil
local mouse = player:GetMouse()
local reach = 100
local castParams = RaycastParams.new()
local result = nil
local result2 = nil
local pos = Vector3.new()
local equipped = false

local mmoving = false
local bridging = false
local movedAfterBridge = false

local mspd = Vector2.new(0,0)
local mlastpos = Vector2.new(0,0)

local char = player.Character

while not char do
	char = player.Character
	wait()
end

local hrp = char:WaitForChild("HumanoidRootPart")

outline.Parent = workspace
outline.SelectionBox.Transparency = 1

local function snap(v3)
	return Vector3.new(math.round(v3.x/4)*4,math.round(v3.y/4)*4,math.round(v3.z/4)*4)
end

tool.Equipped:Connect(function()
	equipped = true
	outline.SelectionBox.Transparency = 0
end)

tool.Unequipped:Connect(function()
	equipped = false
	outline.SelectionBox.Transparency = 1
end)

local blocks = {}

mouse.Move:Connect(function()
	mmoving = true
end)

mouse.Idle:Connect(function()
	mmoving = false
end)

local function getCloseParts()
	local closeparts = {}
	
	for _,child in ipairs(workspace:GetDescendants()) do
		if child:IsA("Part") and child.Name == "Block" then
			if (hrp.Position-child.Position).Magnitude<16 then
				table.insert(closeparts,child)
			end
		end
	end
	
	return closeparts
end

local function checkParts()
	local closeblocks = {nil,nil,nil}
	for _,child in ipairs(workspace:GetDescendants()) do
		if child:IsA("Part") and child.Name == "Block" and (hrp.Position-child.Position).Magnitude<16 then
			local mousepos = Vector2.new(mouse.X,mouse.Y)
			local vector, onScreen = camera:WorldToScreenPoint(child.Position)
			local truedist = mousepos - Vector2.new(vector.X, vector.Y)
			if onScreen then
				local Distance = (mousepos - Vector2.new(vector.X, vector.Y)).Magnitude
				if closeblocks[1] == nil then closeblocks = {Distance, child,truedist} continue end
				if Distance < closeblocks[1] then
					closeblocks = {Distance, child,truedist}
				end
			end
		end
	end
	if closeblocks[1] then
		if math.abs(closeblocks[3].X) > 150 and closeblocks[3].Y < -100 or closeblocks[3].Y > 0 then
			closeblocks = {nil,nil,nil}
			bridging = false
		end
	end
	if closeblocks[2] then
		local oldpos = closeblocks[2].Position
		local camlv = camera.CFrame.LookVector
		local rlv = Vector3.new(math.round(camlv.X/0.1),0,math.round(camlv.Z/0.1))
		local nlv = rlv
		if math.abs(rlv.X)>4 then
			nlv = Vector3.new(4*(rlv.X/math.abs(rlv.X)),0,0)
		end
		if math.abs(rlv.Z)>4 then
			nlv = Vector3.new(0,0,4*(rlv.Z/math.abs(rlv.Z)))
		end
		closeblocks = {nil,oldpos+(nlv)}
		bridging = true
	end
	return closeblocks[2]
end

mouse.TargetFilter = outline

mouse.Button1Down:Connect(function()
	if equipped then
		if result or checkParts() then
			script.Parent.Place:FireServer(snap(pos))
		end
	end
end)

rs.RenderStepped:Connect(function()
	mspd = math.floor((Vector2.new(mouse.X, mouse.Y) - mlastpos).Magnitude + 0.5)
	mlastpos = Vector2.new(mouse.X,mouse.Y)
	if equipped then
		local unitRay = mouse.UnitRay
		castParams.FilterDescendantsInstances = getCloseParts()
		castParams.FilterType = Enum.RaycastFilterType.Whitelist
		local result = workspace:Raycast(unitRay.Origin,unitRay.Direction*reach,castParams)
		if result then -- (what i changed)
			pos = result.Position+result.Normal*2
		elseif not result then
			if checkParts() then
				pos = checkParts()
			else
				pos = Vector3.new(0,100000,0)
			end
		end
		outline.Position = snap(pos)
	end
end)

I want it to keep bridging forwards when your mouse doesn’t move. I tried that by changing if result then to if result and not mmoving then (mmoving is a bool that checks if the mouse is moving)
I can bridge properly but then I have to move my mouse If I want to build upwards.

2 Likes

whats the point… afurajaadjiaodjaojsda

this actually isn’t a bug, if you put the video to a REALLY slow motion, you can see that your mouse does indeed go ABOVE the block (rather then infront of it), and therefore itshould build up instead of forward.

To make it not build up, maybe try using the player’s facing direction instead of the mouse when the mouse isn’t moving (or hasn’t moved)

i’m already using the cameras facing direction to find out where the block is placed when the mouse is off the map, i really dont know what to do. sorry for the late response (also i know the footage looks like im purposely moving my mouse to build up but it actually happens)

yes, however, if you slow the thing down, you can see the mouse gets ON the map at that point. instead, you probably want to use a variable to check if the mouse moved, and use the camera direction as long as the mouse didn’t move, as even if the mouse didn’t move, moving your camera/location can still make the mouse go onto the map (which is what happened, you place faster then you walk)

Ok, i modified my code but it seems that when you build up it sort of delays for some reason, and you still have to move your mouse to fix it.

Code:

rs.RenderStepped:Connect(function()
	mspd = math.floor((Vector2.new(mouse.X, mouse.Y) - mlastpos).Magnitude + 0.5)
	mlastpos = Vector2.new(mouse.X,mouse.Y)
	if equipped then
		local unitRay = mouse.UnitRay
		castParams.FilterDescendantsInstances = getCloseParts()
		castParams.FilterType = Enum.RaycastFilterType.Whitelist
		local result = workspace:Raycast(unitRay.Origin,unitRay.Direction*reach,castParams)
		if result then -- ontop of block
			st.Text = "Status: result"
			if mmoving and bridging then -- mouse moving & bridging
				st.Text = "Status: result, mmoving and bridging"
				bridging = false
				pos = result.Position+result.Normal*2
			end
			if not bridging then
				st.Text = "Status: result, not bridging"
				pos = result.Position+result.Normal*2
			end
		elseif not result and not mmoving then -- off map
			st.Text = "Status: no result, not mmoving"
			if checkParts() then
				st.Text = "Status: bridge started"
				pos = checkParts()
			else
				pos = Vector3.new(0,100000,0)
				st.Text = "Status: block in void"
			end
		end
		outline.Position = snap(pos)
	end
end)

st.Text is for debugging

yeah that is kind of the problem with that. I dont really know any way to make it both easy to build forward and up. try using ur old code and just making the delay for building a bit longer (about as long as how long it takes the player to walk the same distance you build) so that the player most liekly wont accidentally glitched it. otherwise, atleast I have no idea how you would make it brigde properly above and infront (im pretty sure bedwars also have this problem, where when brigding u would just accidentally build up, so it shouldn’t be a problem)