Why does a part go so far back when it is following the mouse?

I have created a script that makes a part follow the mouse. I have made a part follow the mouse with BodyPosition and not by changing it’s CFrame/Position. I want to know why it goes so far back when I put my mouse into the skybox. Here is my script:

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

local down = false
local target

mouse.Button1Down:Connect(function()
	down = true
	if mouse.Target and mouse.Target:FindFirstChild("Grabbable") and mouse.Target:FindFirstChild("Grabbable").Value == true then
		target = mouse.Target
		local bp = Instance.new("BodyPosition", mouse.Target)
		bp.MaxForce = Vector3.new("inf", "inf", "inf")
		bp.D = 1500
		bp.P = 2500
		bp.Position = mouse.Hit.p
		mouse.TargetFilter = target
	end
end)

mouse.Move:Connect(function()
	if target and down then
		
		target.BodyPosition.Position = Vector3.new(mouse.Hit.X, mouse.Hit.Y, mouse.Hit.Z)
	end
end)

mouse.Button1Up:Connect(function()
	mouse.TargetFilter = nil
	target.BodyPosition:Destroy()
	target = nil
	down = false
end)

Can somebody please help me with this?

1 Like

I’ve discovered the issue.

So just to clarify your mouse, if over the skybox, will give “so far back” numbers when referenced with mouse.Hit.p (or mouse.Hit.X,Y,Z). It does this because you’re mouse’s position is technically not hitting anything. So it just grabs the point 10k studs away from your camera where you’re mouse is.

if you don’t want your part to move when you’re hovering over the skybox you need to make sure that you’re hitting a part and not the skybox.

In your mouse.Move function just add a check for this:

mouse.Move:Connect(function()
	if target and down and mouse.Target then
		target.BodyPosition.Position = Vector3.new(mouse.Hit.X, mouse.Hit.Y, mouse.Hit.Z)
	end
end)

Let me know if you have any more questions.

1 Like

Okay, but how would I make it follow the mouse even when it is in the skybox, but not go 10k studs back?

1 Like

There’s two methods I know of to be able to do this,
The first involves raycasts, and I’m pretty sure I’ll mess it up since I haven’t experimented with them yet.

So here’s the second and in my opinion easier way.

Ok, so first you’ll need to determine how far back you’ll want the part to go. For my example I’ll just assume 10 studs.

local maxDistance = 10

Next you’ll need to find the directional vector between where you’re mouse ended up in the skybox.

A little explination of what directionalVector means:


It’s the distance traveled in both x and y, to reach exactly 1 stud away from point A to point B.

Here you can see that the directional vector from point A to point B is (0.7, 0.7)
It’s actually (0.7071…, 0.7071…)
If you were to do Pythagorean thrum on this you’d get exactly 1.

Hopefully that made sense,

So in our case we need to figure out the directional vector between the camera and the mouse’s position. Here’s the equation we’d use:

local cameraPosition = game.Workspace.CurrentCamera.CFrame.Position
local mousePosition = mouse.Hit.p
local difference = mousePosition - cameraPosition
local directionVector = difference.unit 
-- Unit converts a Vector3 value into the distance x, y, and z travels to be exactly 1 stud away.

Ok now that we’ve got the directional vector we just need to multiply the distance we’d like to travel.

part.Position = maxDistance * directionVector

One last problem with this, is that in cases where the mouse is actually hitting something close it’ll still go through it. The fix is to just make sure that ‘difference’ magnitude Value isn’t greater then the max distance.

if difference.Magnitude >= maxDistance then
    part.Position = maxDistance * directionVector
else
    part.Position = mouse.Hit.p
end

Hopefully this made sense, let me know if you have any other questions.

1 Like

Tysm! It worked! I’m gonna mark this as the solution!

1 Like