How can i make a part avoid moving into another part?

I’m making a thing where the player can move a part depending on the keys they’re pressing, this is done through bool values that are on and off when keys are pressed, and it runs on a loop.

I need to add boundaries to this, to prevent the part from moving beyond specific parts that are used as borders, however, i haven’t been able to find a way to execute this, as every method i’ve tried has either not worked or has made the part get stuck inside the border block

This is my sample, the “GetTouchingParts” was the method i was trying to do, with a part that’s 1 stud larger than the main part serving as a hitbox.

while wait(0.005) do
	local v1 = Vector3.new(0,0,0)
	local v2 = Vector3.new(0,0,0)
	local v3 = Vector3.new(0,0,0)
	local v4 = Vector3.new(0,0,0)
	
	local rv1 = Vector3.new(0,0,0)
	local rv2 = Vector3.new(0,0,0)
	
	if forward == true then
		v1 = Vector3.new(0,0,-0.25)
	end
	if left == true then
		v2 = Vector3.new(-0.25,0,0)
	end
	if backward == true then
		v3 = Vector3.new(0,0,0.25)
	end
	if right == true then
		v4 = Vector3.new(0.25,0,0)
	end
	
	if ccw == true then
		rv1 = Vector3.new(0,1,0)
	end
	if cw == true then
		rv2 = Vector3.new(0,-1,0)
	end
	
	vector = v1 + v2 + v3 + v4
	rvector = rv1 + rv2
	--print(tostring(vector))
	
	local hitParts = pos.PosHitChecker:GetTouchingParts() -- // Assume this is the returned value from :GetTouchingParts()
	
	if hitParts == nil then
		touching = false
	else
		for _, part in ipairs(hitParts) do
			if part:FindFirstAncestor("HitBarriers") then
				touching = true
			end
		end
	end
	
	if touching == false then
		pos.Position = pos.Position + vector
		pos.Orientation = pos.Orientation + rvector
			
		pos.PosHitChecker.Position = pos.Position
		pos.PosHitChecker.Orientation = pos.Orientation
	end
end

I really need to find a fix for this, because if i dont manage to fix this then i wont be able to progress on the project, so any help is appreciated, thank you!

i’ll explain anything needed, i’m kind of desperate here…

1 Like

I’ve modified your script to make use of :GetPartBoundsInBox() instead of GetTouchingParts, as well as made a couple of other small changes, to get what I think is the desired result.

It doesn’t require the PosHitChecker object to be there, instead you can change the size of the hitbox by changing HitBoxSize

local HitBoxSize = Vector3.new(2,2,2) -- How much is added to the box's size for the hitbox. 

while true do
	local v1 = Vector3.new(0,0,0)
	local v2 = Vector3.new(0,0,0)
	local v3 = Vector3.new(0,0,0)
	local v4 = Vector3.new(0,0,0)

	local rv1 = Vector3.new(0,0,0)
	local rv2 = Vector3.new(0,0,0)

	if forward == true then
		v1 = Vector3.new(0,0,-0.25)
	end
	if left == true then
		v2 = Vector3.new(-0.25,0,0)
	end
	if backward == true then
		v3 = Vector3.new(0,0,0.25)
	end
	if right == true then
		v4 = Vector3.new(0.25,0,0)
	end

	if ccw == true then
		rv1 = Vector3.new(0,1,0)
	end
	if cw == true then
		rv2 = Vector3.new(0,-1,0)
	end

	vector = v1 + v2 + v3 + v4
	rvector = rv1 + rv2
	local hitParts = workspace:GetPartBoundsInBox(pos.CFrame + vector, pos.Size + HitBoxSize)
	local touching = false -- This wasn't in your original script. You may need to remove it for it to function in your environnment.
	if #hitParts == 0 then
		touching = false
	else
		for _, part in ipairs(hitParts) do
			if part:FindFirstAncestor("HitBarriers") then
				touching = true
			end
		end
	end
	
	if not touching then
		pos.Position = pos.Position + vector
		pos.Orientation = pos.Orientation + rvector

		-- posHitChecker can be achieved using welds instead of manually updating it here! Just use a weld constraint, set pos as part 0 and posHitChecker as part 1
	end
	wait()
end
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.