Part Dragging not working

So i’m trying to make a dragging system, but I have 2 problems right now :

  1. The part goes through the wall when it goes too fast.
  2. The part has a gap between the wall and itself when it goes fast.

Here’s a video showing what I mean,

And here’s my script that moves it,

local function MoveTo(Pos:Vector3)
	local lastPos = Part.Position
	Part.Position = Pos
	
	if #workspace:GetPartsInPart(Part) > 0 then
		local delta = lastPos - Pos
		
		repeat
			Part.Position += delta
		until #workspace:GetPartsInPart(Part) == 0
	end
end

while task.wait() do
	local Hit = MS.Hit.Position
	
	if Part then
		local Goal = Vector3.new(Hit.X + Offset.X,Part.Size.Y / 2,Hit.Z + Offset.Z)
		local Pos = Part.Position:Lerp(Goal,.3)
		
		MoveTo( Vector3.new(Pos.X,Pos.Y,Part.Position.Z) )
		MoveTo( Vector3.new(Part.Position.X,Pos.Y,Pos.Z) )
		-- I move the X and Z positions seperately so that it checks X and Z collisions, not both.
	end
end

Does anyone know how to fix this?

Try if it would work better if you used RunService.Stepped instead of task.wait().

Right now, you are adding the entire delta immediately, which really removes the purpose of having it in a loop.
Try doing Part.Position += delta/100 instead. This way, it will gradually move back towards lastPos instead of snapping there immediately. If you want it less/more exact, you can decrease/increase the divisor.

Thanks, but this only solves the second problem, the other problem is that it would go through a wall when it is dragged too fast.

Heres the new script

local function MoveTo(Pos:Vector3)
	local lastPos = Part.Position
	Part.Position = Pos

	if #workspace:GetPartsInPart(Part) > 0 then
		local delta = lastPos - Pos

		repeat
			Part.Position += delta / 100
		until #workspace:GetPartsInPart(Part) == 0
	end
end

RunService.RenderStepped:Connect(function()
	local Hit = MS.Hit.Position
	
	if Part then
		local Goal = Vector3.new(Hit.X + Offset.X,Part.Size.Y / 2,Hit.Z + Offset.Z)
		local Pos = Part.Position:Lerp(Goal,.3)
		
		MoveTo( Vector3.new(Pos.X,Pos.Y,Part.Position.Z) )
		MoveTo( Vector3.new(Part.Position.X,Pos.Y,Pos.Z) )
	end
end)

Ok, I thought of an idea how, maybe instead of just setting it to the position, I can just go through each position, but it didn’t really work.

local function MoveTo(Pos:Vector3)
	local off = Part.Position.Magnitude - Pos.Magnitude
	local s = off / math.abs(off) * -.5
	
	local currentPos = Part.Position
	for i = currentPos.Magnitude, Pos.Magnitude, s do
		local lastPos = Part.Position
		Part.Position = Pos

		if #workspace:GetPartsInPart(Part) > 0 then
			local delta = lastPos - Pos

			repeat
				Part.Position += delta / 100
			until #workspace:GetPartsInPart(Part) == 0
			
			break
		end
	end
end

Oh okay. I suggest you use the repeat loop way to move it to your new position. This should solve both issues since it won’t let the part continue if something is in the way.
Try changing your current MoveTo function’s content to something like this.

local startPos = Part.Position
local delta = Pos - startPos
i = 0
repeat
	Part.Position += delta / 100
	i = i + 1
until (#workspace:GetPartsInPart(Part) == 1) or i => 100

Didn’t work sadly

local function MoveTo(Pos:Vector3)
	local lastPos = Part.Position
	Part.Position = Pos

	if #workspace:GetPartsInPart(Part) > 0 then
		local delta = Pos - Part.Position
		
		for i = 0, 100 do
			Part.Position += delta / 100
			
			if #workspace:GetPartsInPart(Part) > 0 then break end
		end
	end
end

It just goes through the wall now

You are first setting the position with Part.Position = Pos which removes the need to loop towards it.
I meant the entire MoveTo function. Try removing everything in your function and pasting what I sent.

I don’t know how to explain this

local function MoveTo(Pos:Vector3)
	local startPos = Part.Position
	local delta = Pos - startPos
	local i = 0
	
	repeat
		Part.Position += delta / 100
		i = i + 1
	until (#workspace:GetPartsInPart(Part) == 1) or i >= 100
end

Nevermind, I was able to fix it

local function MoveTo(Pos:Vector3)
	local startPos = Part.Position
	local delta = Pos - startPos
	local i = 0
	
	repeat
		local lastPos = Part.Position
		Part.Position += delta / 100
		if #workspace:GetPartsInPart(Part) > 0 then
			Part.Position = lastPos
			break
		end
		
		i = i + 1
	until i >= 100
end

Thanks for helping me!

Great, no problem!
Also, I think that with this new method, you could just send over the Goal variable itself instead of running it twice for X and Z.

I sent the X and Z seperately because I wanted to check the collisions seperately, if I just sent the Goal variable, it would not be able to slide on a surface. Heres what I mean

1 Like

Oh I see, didn’t think of that. Okay :slight_smile: