참고자료
https://docs.unity3d.com/kr/530/ScriptReference/Mathf.Lerp.html
https://starlightbox.tistory.com/91
https://gamedevbeginner.com/the-right-way-to-lerp-in-unity-with-examples/
Easing 함수 ↓
https://easings.net/
https://www.febucci.com/2018/08/easing-functions/
선형 보간(Linear Interpolation)은 선형 눈금의 한 지점에서 다른 두 값 사이의 값을 반환하는 Unity의 수학 함수입니다. 가장 일반적으로 일정 기간 동안 값을 이동하거나 변경하는 데 사용됩니다.
public static float Lerp (float a, float b, float t);
Lerp 계산은 최소값(a)과 최대값(b)을 사용하여 지정된 알려진 범위의 값을 반환합니다.
반환되는 값은 세 번째 값, 즉 a와 b 사이의 눈금에 있는 점을 반환하는 보간점(t)으로 정의됩니다.
전달된 보간점은 0과 1 사이의 부동 소수점 값이며 기본적으로 a와 b 사이의 백분율로 작동합니다.
예를들어 a가 0, b가 100일 때 t=0은 최소값(0)을 반환하고 t=0.5는 중간값(50)을 반환합니다.
다음은 몇가지 사용 예시입니다.
float a = 0;
float b = 50;
float t = 0.5f;
lerpValue = Mathf.Lerp(a, b, t);
// Returns 25
float a = 10;
float b = 50;
float t = 1;
lerpValue = Mathf.Lerp(a, b, t);
// Returns 50
Lerp의 일반적인 용도는 고정된 기간 동안 효과를 생성하는 것입니다.
예를 들어 버튼에 애니메이션을 적용하려면 화면을 검은색으로 페이드하거나 고정된 시간 내에 개체를 새 위치로 이동합니다. 이는 해당 기간 동안 보간점 값을 0에서 1로 증가시켜 수행됩니다.
수행 방법은 다음과 같습니다.
아래 스크립트는 3초 안에 0에서 10까지 값을 증가시킵니다.
float timeElapsed;
float lerpDuration = 3;
float startValue=0;
float endValue=10;
float valueToLerp;
void Update()
{
if (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
timeElapsed += Time.deltaTime;
}
}
그러나 이 방법을 시도하면 값이 10에 도달하지 않고 종종 매우 가깝지만 정확하지는 않은 값으로 끝나는 것을 알 수 있습니다. 예를 들어 9.998과 같습니다.
이는 Lerp가 완료되었는지 측정하는 데 사용되는 값이 Lerped되는 실제 값이 아니라 시간이기 때문입니다.
이 문제를 해결하려면 Lerp가 완료된 후 Lerped되는 값을 최종 목표 값으로 스냅해야 합니다.
스냅(보정)을 했을 때:
void Lerp() { if (timeElapsed < lerpDuration) { valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration); timeElapsed += Time.deltaTime; } else { valueToLerp = endValue; } }
마지막으로 Lerp 함수는 여러 프레임에 걸쳐 작업을 수행하는 데 자주 사용되므로,
Coroutine에 배치하는 것이 도움이 될 수 있습니다.
float lerpDuration = 3;
float startValue = 0;
float endValue = 10;
float valueToLerp;
void Start()
{
StartCoroutine(Lerp());
}
IEnumerator Lerp()
{
float timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
timeElapsed += Time.deltaTime;
yield return null;
}
valueToLerp = endValue;
}
Lerp를 사용해 로딩바를 만들어보겠습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Lerp : MonoBehaviour
{
public Image barImage;
public Text text;
public Text textPer;
private void Start()
{
StartCoroutine(MyLerp());
}
private IEnumerator MyLerp()
{
float delta = 0; // 경과 시간 추적을 위한 변수
float duration = 5f; // 보간에 걸리는 총 시간
int startValue = 0; // 시작 값
int endValue = 3270; // 목표 값
// 보간이 완료될 때까지 반복
while (delta <= duration)
{
// 현재 시간에 대한 보간 비율 계산
float t = delta / duration;
// 시간 흐름에 따른 매개 변수 변화율 (보간)
t = t < 0.5 ? (1 - Mathf.Sqrt(1 - Mathf.Pow(2 * t, 2))) / 2 : (Mathf.Sqrt(1 - Mathf.Pow(-2 * t + 2, 2)) + 1) / 2;
// 현재 보간된 값 계산
float currentValue = Mathf.Lerp(startValue, endValue, t);
// UI 업데이트
barImage.fillAmount = t; // 이미지의 fill을 보간 값으로 업데이트
text.text = string.Format("{0} MB", currentValue); // 텍스트 업데이트
textPer.text = string.Format("{0}%", t * 100f); // 텍스트 업데이트
// 경과 시간 업데이트
delta += Time.deltaTime;
// 다음 프레임까지 대기
yield return null;
}
// 보간이 완료된 후 마무리 작업
barImage.fillAmount = 1; // 이미지의 fill을 최대로 변경
text.text = string.Format("Complete"); // 텍스트 업데이트
textPer.text = string.Format("{0}%", 100f); // 텍스트 업데이트
}
}
while 루프를 사용하여 시간에 따라 값을 보간하고, 보간된 값을 UI에 업데이트합니다.
보간은 지정한 시간동안 startValue에서 endValue까지 진행되며, 보간값(t)의 선형적인 움직임을 원하지 않는다면 Easing 함수를 사용하여 부드러운 보간 효과를 생성할 수 있습니다.
결과: