Make object follow normal

Hi, I want this small object to move along a surface. And also account for the surface normal. Everything is anchored, but it still will just stutter at one position. Any idea on how to solve this? Thanks.

This is the code I'm using
wait(1)

while wait() do
	local RayParams = RaycastParams.new()
	RayParams.FilterType = Enum.RaycastFilterType.Blacklist
	RayParams.FilterDescendantsInstances = {script.Parent}
	local RayResult = workspace:Raycast(script.Parent.Position + Vector3.new(0,3,0),Vector3.new(0,-15,0),RayParams)
	
	if RayResult then
		local norm = RayResult.Normal
		local oldO = script.Parent.Orientation
		script.Parent.CFrame = CFrame.new(RayResult.Position + norm*3,RayResult.Position)
		script.Parent.Orientation = Vector3.new(script.Parent.Orientation.X+90,oldO.Y,script.Parent.Orientation.Z)
	end
	script.Parent.Position += script.Parent.CFrame.LookVector*1
end

Any changes I make don’t affect the movement. It just moves back and forth. The normals seem to not work properly in roblox…

I can’t quite figure out the exact logic you’re going for, here’s my best guess:

Script
local V3 = Vector3.new
local CF = CFrame.new

local HOVER_HEIGHT = 3
local WALK_STEP_SIZE = 0.1

local guy = script.Parent

local walkRayParams = RaycastParams.new()
walkRayParams.FilterType = Enum.RaycastFilterType.Blacklist
walkRayParams.FilterDescendantsInstances = {guy}

function getNextWalkCFrame(): CFrame
	local nextPoint

	--Move the guy a bit forward relative to the last surface they were walking on
	local nextPoint = guy.Position + guy.CFrame.LookVector * WALK_STEP_SIZE

	--Find the new surface the guy is walking on
	local result = game.Workspace:Raycast(nextPoint, guy.CFrame.UpVector * -4, walkRayParams)
	if not result then return guy.CFrame end --Don't know what to do if they're not on a surface :shrug: --TODO: 

	--Hover the guy a bit above the new surface
	local surfacePoint = result.Position
	local surfaceUp = result.Normal
	nextPoint = surfacePoint + surfaceUp * HOVER_HEIGHT

	--Align the guy to the new surface
	local nextCFrame
	local surfaceRight = guy.CFrame.LookVector:Cross(surfaceUp)
	local surfaceForward = surfaceUp:Cross(surfaceRight)
	nextCFrame = CFrame.lookAt(nextPoint, nextPoint+ surfaceForward, surfaceUp)
	
	return nextCFrame
end

while wait() do
	guy.CFrame = getNextWalkCFrame()
end

Animation