The player travels across a Bezier curve, but since the character just teleports to separate positions I used a raycast between their current position and the next position.

Supposedly, if the space between the first position and the next position is more than the space between the first position and an object on the ray, the loop should break to not make the character go through the object.

local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {character}
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
	
for t = 0, 1, 0.04 do
	wait()
	local pos = QuadraticBezier(t, tPos, targetPos, target)
		
	local raycastResult = workspace:Raycast(character.HumanoidRootPart.Position, pos, rayParams) 
	if raycastResult then 
		if (character.HumanoidRootPart.Position - raycastResult.Position).Magnitude <= (character.HumanoidRootPart.Position - pos).Magnitude then
			break
		end
	end
		
	character.HumanoidRootPart.Position = pos
	character.HumanoidRootPart.CFrame = CFrame.lookAt(pos, target)
		
end