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초 동안 각초마다 정해진 구간만큼 똑같이 이동을 하는데 상황에 따라선 처음엔 빠르게 올라가다가 후반부에 느리게 올라갔으면 하는 연출이 필요할 때가 있습니다. 이럴 때는
이 사이트 같은 곳을 참고하셔서 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";
}
이러한식으로 마지막 부분에는 도착지에 해당하는 좌표를 넣어서 세팅을 해주면 정상적으로 작동하는 것을 볼 수 있습니다.
참고자료 :
'[개인공부] > Unity' 카테고리의 다른 글
[Unity] 에디터 확장 기능으로 스크립트 일괄 제거하기 (2) | 2023.08.21 |
---|---|
[Unity] 로컬 푸쉬 Mobile Notifications 구현 (야간푸쉬 체크) (0) | 2023.07.18 |
[Unity] XLua 연동해보기 (0) | 2023.03.26 |
[Unity] 오브젝트 풀링 (Object pooling) (10) | 2023.03.18 |
[Unity] 코루틴 최적화 (0) | 2023.02.18 |