Lerp를 Pro처럼 작성하는 방법

유니티 Lerp란?

Unity의 Lerp("선형 보간"의 줄임말)는 개발 및 컴퓨터 그래픽에서 일반적으로 사용되는 수학 함수입니다. 이 함수를 사용하면 지정된 기간 동안 두 값 사이를 부드럽게 보간하여 부드러운 전환이나 애니메이션을 만들 수 있습니다.

Lerp 함수에는 시작 값(start), 끝 값(end), 그리고 보간을 어느 정도까지 해야 하는지를 나타내는 t값(0과 1 사이의 값)의 세 가지 파라미터를 제공합니다.

Lerp는 t값을 기준으로 시작 값과 끝 값 사이에 있는 새 값을 계산합니다. t값이 0에 가까울수록 결과가 시작 값에 가까워지고, 1에 가까울수록 결과가 끝 값에 가까워집니다.

Unity에서는 다양한 데이터 유형에 따라 Mathf.Lerp를 사용하여 실수 값 사이를 보간하거나 Vector3.Lerp를 사용하여 Vector3 값 사이를 보간할 수 있습니다.


Simple Lerp

Vector3.Lerp(transform.position, transform.position + Vector3.forward, 0.6f);

유니티를 이용한 개발을 하실 때, 평소 Lerp를 위와 같은 방식밖에 생각하지 못하신 분들은 아래 글을 읽으시면 도움이 될 것이라 믿습니다!

 

위와 같이 작성하면 문제점은 t값(여기서 t는 0.6f)을 바꾸고 싶을 때마다 스크립트를 수정해야하는 번거로움이 있다는 점입니다.

또한, t값을 0.6f으로 설정할 때의 문제점은 Vector3.forward값에 영원히 도달할 수 없다는 점입니다.

이해를 돕기 위한 사진 ㅎㅎ..

왜냐하면 A위치에서 B위치를 향해  0.6만큼 이동하는데, 0.6만큼 이동하고 나면 그 위치가 다시 기준점(0)이 되고 또 다시 0.6만큼 가므로 아무리 진행되도 1에 도달할순 없게 됩니다.

 

이러한 문제점을 개선하기 위해 Lerp함수에서 t값을 변형할 필요가 있습니다.


변형된 Lerp

private float currentTime;
    
[SerializeField] private float lerpTime = 1f;

private void Update()
{
     currentTime += Time.deltaTime;
     if (currentTime >= lerpTime)
     {
         currentTime = lerpTime;
     }

     Vector3.Lerp(transform.position, transform.position + Vector3.forward, currentTime / lerpTime);
}

위와 같이 코드를 작성하면  에디터에서 스크립트로 와서 계속 수정할 필요가 없게 됩니다.

 

또한, currentTime이 lerpTime가 같아지므로, 즉 값이 1이 될 수 있으므로 A 에서 B로 다가갈 수 있게 됩니다.

 


더 고급진 유니티 Lerp 활용법

 

How to Lerp like a pro

I see this sort of thing far too often: transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime); The person posting it is usually convinced that Vector3.Lerp is “broken”, bu…

chicounity3d.wordpress.com

위 홈페이지를 참고해서 코드를 작성한다면 고급진 Lerp를 만들어 낼 수 있습니다.

 

예시

처음엔 빠르고 도착할 땐 Smooth하게 움직임을 표현하고 싶으면 아래와 같이 작성할 수 있습니다.

    private float currentTime;
    private float lerpTime = 1f;

    private void Update()
    {
        currentTime += Time.deltaTime;
        if (currentTime >= lerpTime)
        {
            currentTime = lerpTime;
        }

        float t = currentTime / lerpTime;
        //t = t*t*t*(t*(6f*t-15f) + 10f);
        t = Mathf.Sin(t * Mathf.PI * 0.5f);
        Vector3.Lerp(transform.position, transform.position + Vector3.forward, t);
    }

 

처음엔 빠르고 도착할 땐 Smooth하게 하는 수학식