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)); }