Making a part follow the mouse and behave as it does in Roblox Studio

If this works fine, maybe it can be use to you:
Dragging objects with the mouse - Resources / Community Tutorials - DevForum | Roblox

I found that if you remove temporarily set the parent of the ignored object to nil before the Dragger:MouseMove, then set it back afterwards, it works! But it is very jittery

What do you mean by remove temportally “set the parent?”

the problem is that it doesnt ignore the part that’s being followed, do you mean that one? or the toReference

I meant the ignored part. But it is very jittery. There is probably a newer and better way.

I found this:

To prevent the part from sticking through other ones. I wouldnt recommend using BodyPositions (they are now obsolete)
But you can use raycasts to get the face of the part, and offset it.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local part = Instance.new("Part")
part.Parent = workspace
mouse.TargetFilter = part

mouse.Move:Connect(function()
	part.CFrame = mouse.Hit
end)

You need to set the TargetFilter property of the mouse object itself to the part which is being moved, if you want the highlight box surrounding the part being moved you’ll need to make use of a SelectionBox instance.

Not to mention RenderStepped is purposed specifically for manipulating the player’s camera/the player’s character model.

yeah the problem is that I was making a part follow the part i was dragging with BodyPosition so it was smooth.

1 Like
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local part = Instance.new("Part")
part.Parent = workspace
mouse.TargetFilter = part
local ts = game:GetService("TweenService")

mouse.Move:Connect(function()
	local tween = ts:Create(part, TweenInfo.new(0.1), {["CFrame"] = mouse.Hit})
	tween:Play()
end)

You can just use tweens to create fluid/smooth movement.

That’s not a solution either. Because I also wanted to be able to rotate it.

However! I had an idea when @Misinformater posted the mouse.TargetSurface solution, the problem was if the target was rotated. but with this script I to set an offset depending on the surface.Name

local function SurfaceRelativeToWorld(object)
    local oldOrientation = object.Orientation
    object.Orientation = Vector3.zero
    
    local RelativeSurface = mouse.TargetSurface
    
    object.Orientation = oldOrientation
    return RelativeSurface.Name
end

Using if satements might no be the best solution but I honestly can’t think about anything else.

There is one problem though (but it would be the same with the dragger), if I change the size to a non-cubic form and then rotate it, it’s not going to work (it will intersect once again), because it offsets depending on the size it has locally. So once again, as this has took too much time, I decided to keep the forms all to perfect cubes.

You could easily change the tween to set the Position property instead of the CFrame property of the part and then use mouse.Hit.p instead of mouse.Hit and finally use UserInputService to allow rotation of the part along the three axis.

Hey, I just figured something out using raycasting.

It is smooth, and does not directly intersect, but if you angle it just right against a wall it will. But it shouldn’t be too much of a problem.

Here’s how it looks:

And here’s the code (adapt it for your needs, don’t copy it verbatim):

local dragging = false

local mouseMoveEvent

local ignored = workspace.Ignored

local draggingPart
local wasAnchored

script.Parent.Equipped:Connect(function(mouse)
	mouse.Button1Down:Connect(function()
		draggingPart = mouse.Target
		wasAnchored = draggingPart.Anchored
		draggingPart.Anchored = true
	end)

	mouse.Button1Up:Connect(function()
		if draggingPart then
			draggingPart.Anchored = wasAnchored
			draggingPart = nil
		end	
	end)

	mouse.Move:Connect(function()
		if draggingPart then
			local raycastParams = RaycastParams.new()
			raycastParams.FilterDescendantsInstances = {draggingPart}
			raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
			local unitRay = mouse.UnitRay
			local raycastResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * 500, raycastParams)
			
			if raycastResult then
				draggingPart.Position = raycastResult.Position
				draggingPart.Position += (draggingPart.Size / 2) * raycastResult.Normal
			end
		end
	end)
end)

What matters here (and prevents it from sticking through the wall) is this line here:

draggingPart.Position += (draggingPart.Size / 2) * raycastResult.Normal

(I think this was what OMQ_Kevin666 was mentioning)
It offsets it by the size of the part in the direction that the arrow casted.

Of course, if you want to add exclusions (i.e. the player, or the hologram), add it to the line “FilterDescendantsInstances”

3 Likes

so this fixes the previous problem? That’s great!
In fact, i was getting so desperate because of the way it was working before, TYSM! I’ll try that now.

PD: sorry for answering so late, I took a few days off for exams

1 Like

Okay, this works really well however when i rotate the part messes up. But, for now, im not using any parts that are sized like a square, so thanks :smiley: