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