Panning a part on a surface so it points mostly upwords

Trying to achieve this kind of part panning behavior on surfaces using raycasters
(red squares show how it should be right)


In essence, it’s doing alright when raycasted perpendicular to the surface, but otherwise it rotates wrong.
Need some help gathering the offset angle
Code snippet:

local cam = workspace.CurrentCamera
local mouse = player:GetMouse()
local angle =  0
runSv.RenderStepped:Connect(function(dt)	
	local mousePos = mouse.Hit.p
	local camPos = cam.CFrame.p
	local diff = (mousePos-camPos)
	local mag = diff.magnitude
	
	local result = workspace:Raycast(camPos,diff.Unit*500,filter)
	if result == nil then
		if prevPart.Parent ~= script then
			prevPart.Parent = script
		end
	else
		if prevPart.Parent ~= workspace then
			prevPart.Parent = workspace
		end
		local norm = result.Normal
		local lookV = cam.CFrame.lookVector
		
		local fw = norm:Cross(lookV):Cross(norm)
		
		prevPart.CFrame = CFrame.lookAt(result.Position, result.Position+fw, -norm) *
			CFrame.Angles(0,math.rad(angle)+90-vectorsAngle(fw,lookV),0) -- what should I do here in order to make the movement right ?
	end
end)
1 Like

I would personally just do:

local directionYouWantItToBe = Vector3.new(0,1,0)

prevPart.CFrame = CFrame.fromMatrix(position,directionYouWantItToBe:Cross(norm),directionYouWantItToBe:Cross(norm):Cross(norm))
1 Like

Thank you very much for your help :heart:
Here’s some final adjustment:

local UP = Vector3.new(0,1,0)
if norm ~= UP then
prevPart.CFrame = CFrame.fromMatrix(
	result.Position,
	UP:Cross(norm),
	UP:Cross(norm):Cross(norm)
) * CFrame.Angles(-math.pi/2,0,0) -- so it faces upwords
else
	prevPart.CFrame = CFrame.fromMatrix(result.Position, fw, -norm) *
		CFrame.Angles(math.pi,math.rad(angle),0) -- so it faces upwords		
end

When the part was perpendicular with the UP direction it mostly bugged out the matrix so I had to test it. Now it works :slight_smile:

1 Like