public void UseDash(DashData dashData)
{
    var dashDirection = dashData.Type switch
    {
        DashType.Forward     =>  transform.forward,
        DashType.Backward    => -transform.forward,
        DashType.Left        => -transform.right,
        DashType.Right       =>  transform.right,
        DashType.InputVector =>  inputVector != Vector3.zero ? inputVector : transform.forward,
        DashType.Random      =>  new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)).normalized,

        _ => Vector3.zero
    };

    if (dashCoroutine != null)
    {
        StopCoroutine(dashCoroutine);
        dashCoroutine = null;
    }

    dashCoroutine = DashCoroutine(dashDirection, dashData);
    StartCoroutine(dashCoroutine);
}

private IEnumerator DashCoroutine(Vector3 direction, DashData dashData)
{
    var startPosition = transform.position;
    var targetDistance = dashData.Distance;
    if (Physics.SphereCast(startPosition, controller.radius, direction, out var hit, targetDistance, Layers.WallOrObstacle))
    {
        targetDistance = hit.distance - controller.radius;
    }

    OnDash?.Invoke(direction);
    controller.detectCollisions = false;

    var endPosition = startPosition + direction * targetDistance;
    var elapsedTime = 0f;
    while (elapsedTime < dashData.Duration)
    {
        elapsedTime += Time.deltaTime;

        var t = elapsedTime / dashData.Duration;
        var lerpT = dashData.Easing != null ? dashData.Easing.Evaluate(t) : Mathf.SmoothStep(0f, 1f, t);
        transform.position = Vector3.Lerp(startPosition, endPosition, lerpT);

        if (!animHandler.IsPlayLayerBusy() && (dashData.Type == DashType.InputVector || dashData.Type == DashType.Forward))
        {
            SlerpRotate(Quaternion.LookRotation(direction), settings.IdleRotateSpeed);
        }

        yield return null;
    }

    transform.position = endPosition;
    controller.detectCollisions = true;
    dashCoroutine = null;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

public UniTask UseDash(DashData dashData)
{
    dashCts?.Cancel();
    dashCts = CTSHelper.CreateLinkedCTS(CTSHelper.GlobalToken, skillSystem.EntityToken);

    var dashDirection = dashData.Type switch
    {
        DashType.Forward     =>  transform.forward,
        DashType.Backward    => -transform.forward,
        DashType.Left        => -transform.right,
        DashType.Right       =>  transform.right,
        DashType.InputVector =>  inputVector != Vector3.zero ? inputVector : transform.forward,
        DashType.Random      =>  new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)).normalized,

        _ => Vector3.zero
    };

    return MovementAsync(dashDirection, dashData, dashCts.Token);
}

private async UniTask MovementAsync(Vector3 direction, DashData data, CancellationToken token)
{
    var startPosition = transform.position;
    var targetDistance = data.Distance;

    if (Physics.SphereCast(startPosition, controller.radius, direction, out var hit, targetDistance, Layers.WallOrObstacle))
    {
        targetDistance = hit.distance - controller.radius;
    }

    OnDash?.Invoke(direction);
    controller.detectCollisions = false;

    var endPosition = startPosition + direction * targetDistance;
    var elapsedTime = 0f;
    while (elapsedTime < data.Duration)
    {
        if (token.IsCancellationRequested) break;

        elapsedTime += Time.deltaTime;
        var t = elapsedTime / data.Duration;
        var lerpT = data.Easing != null ? data.Easing.Evaluate(t) : Mathf.SmoothStep(0f, 1f, t);
        transform.position = Vector3.Lerp(startPosition, endPosition, lerpT);

        if (!animHandler.IsPlayLayerBusy() && (data.Type == DashType.Forward || data.Type == DashType.InputVector))
        {
            SlerpRotate(Quaternion.LookRotation(direction), settings.IdleRotateSpeed);
        }

        await UniTask.Yield(PlayerLoopTiming.Update, token);
    }

    transform.position = endPosition;
    controller.detectCollisions = true;
}



코루틴이었던 놈을 유니태스크로 바꿨는데 동작을 안 함
토큰이 캔슬됐나? 아님
중단점 찍어보면 와일문을 바로 빠져나가던데.. 그렇다해도
endPosition 위치로 이동은 되어야하는데 제자리에 있음

유니태스크로 바꾼 로직을 몬스터에 썼을 땐 또 제대로 동작함(캐릭터컨트롤러가 아닌 네브메쉬에이전트인 점만 다름)

뭐지? 진짜 모르겠음