Draggable brick jumps too far and script prints wrong distance

  1. What do you want to achieve?

I’m trying to make a draggable part (called “4D”) by adding two “arrow” parts (pointing away from each other) next to it. The parts are grouped in a model (with a stationary part called “3D” as well) and both the arrows have a click detector in them. I’m using the code further down in the post to make them draggable, where the scripts are inside each of the click detectors and the local script is inside StarterPlayerScripts.

  1. What is the issue?

When I try dragging the arrows, sometimes they jump way further than the intended 1 stud, so that the mouse cursor lands on the other arrow, and sometimes, the distance printed (h) is 1 or -1 even though the part named 4D and the part named 3D share the same position.

  1. What solutions have you tried so far?

When the parts were moving too far at once, I added another condition to an if statement to check if the mouse cursor was over 1 stud away from the part and not only over 1 stud away from the last position. That fixed some of the issue, at least when I only had one draggable arrow, but when I tried making the second arrow draggable too, the problems really started. Since it’s a very specific script, I didn’t really know what to search on the DevForum, so I haven’t really looked for a solution.

  1. Code:

Script:

local cd = script.Parent
local rs = game:GetService("ReplicatedStorage")
local hoverEvent = rs:FindFirstChild("hoverEvent") or Instance.new("RemoteEvent")
hoverEvent.Parent = rs
hoverEvent.Name = "hoverEvent"

cd.MouseHoverEnter:Connect(function(player)
	hoverEvent:FireClient(player, script.Parent.Parent, true)
end)

cd.MouseHoverLeave:Connect(function(player)
	hoverEvent:FireClient(player, script.Parent.Parent, false)
end)

LocalScript:

local cd = script.Parent
local rs = game:GetService("ReplicatedStorage")
local hoverEvent = rs:WaitForChild("hoverEvent")
local player = game.Players.LocalPlayer
local hover = false
local clicked = false

hoverEvent.OnClientEvent:Connect(function(part, h)
	clicked = false
	hover = h
	local mouse = player:GetMouse()
	local pos1
	local pos2
	local R = part.Parent:FindFirstChild("4D").Size.X/2
	mouse.Button1Down:Connect(function()
		clicked = true
		if hover == true then
			pos1 = mouse.Hit.Position
			mouse.Move:Connect(function()
				if hover == true and clicked == true then
					pos2 = mouse.Hit.Position
					if (pos2 - pos1).X > 1 and (pos2 - part.Position).X > 1 then
						pos1 = mouse.Hit.Position
						for i, brick in pairs(part.Parent:GetChildren()) do
							if brick.Name ~= "3D" then
								brick.Position = Vector3.new(brick.Position.X+1,brick.Position.Y,brick.Position.Z)
							else
								local h = (brick.Position - brick.Parent:FindFirstChild("4D").Position).X
								print(h)
								local r = math.sqrt(R^2-h^2)
								brick.Size = Vector3.new(2*r,2*r,2*r)
							end
						end
					elseif (pos2 - pos1).X < -1 and (pos2 - part.Position).X < -1 then
						pos1 = mouse.Hit.Position
						for i, brick in pairs(part.Parent:GetChildren()) do
							if brick.Name ~= "3D" then
								brick.Position = Vector3.new(brick.Position.X-1,brick.Position.Y,brick.Position.Z)
							else
								local h = (brick.Position - brick.Parent:FindFirstChild("4D").Position).X
								print(h)
								local r = math.sqrt(R^2-h^2)
								brick.Size = Vector3.new(2*r,2*r,2*r)
							end
						end
					end
				end
			end)
		end
		mouse.Button1Up:Connect(function()
			clicked = false
		end)
	end)
end)

So the problem with the arrows jumping was that I didn’t disconnect the functions. So I just added a few disconnect functions to the code, and now that works as it should. However, I still have the problem with the code giving me the wrong distance.

If I were you, to prevent jumping I would make a range of values the player could move to via their screen.
(you could up the min and max when the player moves or zooms in out etc)
You would first make the maximum and minimum values that could be attained by moving the mouse, then get the position of the mouse on the screen.
Get the percentage of the mouse to maximum mouse position(camera.ViewportSize).
Then multiply lerp between your max and min to get the new position.

You could also just define the amount of mouse movement needed to move x amount of studs, then divide the actual mouse movement by your preset value.
Then you multiply this preset value(now the percentage of the amount needed to move x studs) by your stud increment.

Either one should work, but this one is simpler.

As I said, I fixed the jumping, but not the wrong distance being used.

Also, I would like the arrows to be draggable in 3D (so that changing the camera angle will also change how fast you can drag it), not just depend on how far to the right the mouse is on the screen. I will add some trigonometric functions to make it work even if the mouse isn’t hovering directly over the arrow at all times. But I think I got that part of the code sorted out. Now it’s just the printed distance (the one used for the calculation of size) being wrong.

All in all its going to be based off the movement of the mouse(unless I misunderstood).

If that is the case, then why don’t you just use mouse.Hit?

I don’t get the problem.

I am using mouse.Hit. The problem is that when I drag the part around, the script prints out the wrong distance between the part named “3D”, which is stationary, and the part named “4D”, which is being dragged around. Check the video. Near the end of it, I show that the script prints out a distance of -1 when the parts are sharing the exact same position. This distance is very important for calculating the size of one of the parts.

Rewrite all of your code, you screwed up somewhere.
:person_shrugging:

I know that I screwed up, that’s why I’m here. If I were to just rewrite my code, I’d probably do the same thing again, since I don’t see what the problem is with my code. This is scripting support. If I ask a question here, it means I don’t know the answer.

Ok that makes sense.

Write out different solutions that make sense to you and try those to avoid repetition. its not that much code to scrap.