private void ChangePath2(SwipeInput.SwipeType swipeType)
        {
            var targetLine = currentRoadId;

            switch (swipeType)
            {
            case SwipeInput.SwipeType.Left:
                targetLine = Mathf.Clamp(--targetLine, 0, levelHolder._lines.Length - 1);
                break;

            case SwipeInput.SwipeType.Right:
                targetLine = Mathf.Clamp(++targetLine, 0, levelHolder._lines.Length - 1);
                break;
            }
            if (targetLine == currentRoadId)
            {
                return;
            }
            var p0 = _follower.result;                                                                                         // point on current spline
            var p1 = levelHolder._lines[targetLine].Evaluate(levelHolder._lines[targetLine].Project(p0.position));             // closest point on side line
            var d  = p0.position - p1.position;

            if (!PlayerMover.CheckLineSwap(levelHolder._lines[targetLine], p0, levelHolder._lineWidth))
            {
                return;
            }
            OnTrackChange?.Invoke(currentRoadId, targetLine);
            currentRoadId = targetLine;
            d.Normalize();
            var d2 = new Vector2(Vector3.Dot(d, p1.right), Vector3.Dot(d, p1.normal));             // offset is [X * point.right + Y * point.normal]

            _follower.computer   = levelHolder._lines[currentRoadId];
            _changeRoadCoroutine = StartCoroutine(SwitchLine(d2));
        }