300x250

Lerp 함수는 보간(Interpolation) 기법 중 하나인 선형 보간(Linear Interpolation)을 수행합니다. 이는 두 지점 사이의 값을 일직선 상에 있는 다른 값으로 변환하는 것을 의미합니다. 이를 좀 더 쉽게 이해하기 위해서는, 두 점을 잇는 직선상에 있는 다른 지점들을 구하는 것과 같다고 생각할 수 있습니다.

즉 위 사진처럼 A와 B사이의 좌표를 구한다고 생각하면 편합니다.

이런 식으로 무수하게 많은 좌표가 있을 텐데 Lerp 함수를 사용하면 이각각의 좌표를 쉽게 구할 수 있습니다.


Lerp 함수는 다음과 같은 형태로 사용됩니다.

public static Vector3 Lerp(Vector3 a, Vector3 b, float t);


여기서 a와 b는 각각 선형 보간을 수행할 두 지점이며, t는 a와 b 사이에서 내분되는 비율을 나타내는 값입니다. t 값은 0과 1 사이의 값을 가지며, t가 0이면 결과는 a가 되고, t가 1이면 결과는 b가 됩니다. 그리고 0과 1 사이의 값이 아닌 t 값을 사용하는 경우, Lerp 함수는 a와 b 사이의 값을 내분한 값으로 계산합니다.

예를 들어, A가 0이고 B가 1인 경우, t가 0.5인 Lerp 함수를 호출하면 다음과 같은 결과가 나옵니다.


Vector3.Lerp(a, b, 0.5f); // 결과는 (0.5)


이는 a와 b를 잇는 직선상에서 t = 0.5 지점에 해당하는 값을 반환하는 것입니다.

Lerp 함수는 보간 기법을 적용하기 때문에, 물체의 이동, 회전, 크기 변화 등을 자연스럽게 만들 수 있습니다. 또한, 보간 기법은 게임에서 많이 사용되는 기법 중 하나이므로, 게임 개발자라면 반드시 알고 있어야 하는 개념 중 하나입니다.

 

 

이걸 사용해서 0부터 10000까지 10초 동안 올라가는 코드를 작성해 보겠습니다.

    private IEnumerator LerpTestImpl()
    {
        float delta = 0;
        float duration = 10f;
        int startValue = 0;
        int endValue = 10000;

        while (delta <= duration)
        {
            float t = delta / duration;

            float currentValue = Mathf.Lerp(startValue, endValue, t);
            imgSliderFront.fillAmount = t;
            textPer.text = string.Format("{0}%", t * 100f);
            text.text = currentValue.ToString();

            delta += Time.deltaTime;
            yield return null;
        }
    }

 

 

이렇게 하면 10초 동안 각초마다 정해진 구간만큼 똑같이 이동을 하는데 상황에 따라선 처음엔 빠르게 올라가다가 후반부에 느리게 올라갔으면 하는 연출이 필요할 때가 있습니다. 이럴 때는 

Easing 함수 치트 시트 (easings.net)

 

Easing Functions Cheat Sheet

Easing functions specify the speed of animation to make the movement more natural. Real objects don’t just move at a constant speed, and do not start and stop in an instant. This page helps you choose the right easing function.

easings.net

이 사이트 같은 곳을 참고하셔서 t값에 수식을 적어주시면 됩니다. 수학적인 부분이라 왜 저런 수식이 나왔는지는 설명이 어렵습니다.

 

 

    private IEnumerator LerpTestImpl()
    {
        float delta = 0;
        float duration = 10f;
        int startValue = 0;
        int endValue = 10000;

        while (delta <= duration)
        {
            float t = delta / duration;
            t = Mathf.Sin((t * Mathf.PI) / 2);

            float currentValue = Mathf.Lerp(startValue, endValue, t);
            imgSliderFront.fillAmount = t;
            textPer.text = string.Format("{0}%", t * 100f);
            text.text = currentValue.ToString();

            delta += Time.deltaTime;
            yield return null;
        }
    }

이렇게 하면 빠르게 올라가다가 끝에 가까워질수록 느리게 올라가는 연출을 간단하게 할 수 있습니다.

 

 

그런데 이렇게 끝내면 아래와 같이 9999와 같이 딱 떨어지지 않는 경우가 발생할 수 있습니다. 왜냐하면 Lerp함수와 타임값을 사용해서 중간 좌표를 구해주는 식으로 구현을 했는데 이렇게 하면

이러한 좌표를 구해버릴 수도 있는 겁니다. 그래서 끝시간에 도달했을 때 끝값을 고정해줘야 합니다. 이것을 끝보정이라고 합니다.

    private IEnumerator LerpTestImpl()
    {
        float delta = 0;
        float duration = 10f;
        int startValue = 0;
        int endValue = 10000;

        while (delta <= duration)
        {
            float t = delta / duration;
            t = Mathf.Sin((t * Mathf.PI) / 2);

            float currentValue = Mathf.Lerp(startValue, endValue, t);
            imgSliderFront.fillAmount = t;
            textPer.text = string.Format("{0}%", t * 100f);
            text.text = currentValue.ToString();

            delta += Time.deltaTime;
            yield return null;
        }
        
        // 10초가 지났으니 끝보정
        imgSliderFront.fillAmount = 1;
        textPer.text = string.Format("{0}%", 100f);
        text.text = "10000";
    }

 

이러한식으로 마지막 부분에는 도착지에 해당하는 좌표를 넣어서 세팅을 해주면 정상적으로 작동하는 것을 볼 수 있습니다.

 

 

참고자료 :

(403) [유니티] Lerp를 프로처럼 사용하는 방법 - YouTube

https://easings.net/ko

300x250