게임플레이를 하다 보면 캐릭터 이동이 부자연스럽거나 캐릭터가 회전하는데 끊기는 것 처럼 보이는 등 어색한 움직임 때문에 질이 떨어져 보이는 게임들이 꽤 있습니다. 만약 Mathf.Lerp를 알고 활용 예시들을 많이 접하다 보면 이러한 문제들은 자연스럽게 해결이 됩니다. 이번 시간은 Mathf.Lerp의 사용법을 알아보고, 캐릭터의 이동 보간, 회전 보간, UI 페이드인 아웃, 체력 바, 카메라 흔들림 효과, 배경음악 볼륨 조절 등 주로 보간이 사용되는 곳의 코드를 작성해 보겠습니다.

[Mathf.Lerp의 개념]

선형 보간을 수행하는 함수이며, 이는 두개의 값 사이에서 특정 비율에 따라서 보간하는 과정을 말합니다. 총 3개의 매개 변수를 사용합니다.

  1. a: 시작 값(시작 지점)
  2. b: 목표 값(끝 지점)
  3. t: 비율 값(시작과 끝사이의 비율)
lerp = a + (b - a) * t

해당 공식을 사용하는 것이 바로 Lerp 함수 입니다.

만약 t값이 0일때는 a를 반환하고 1일때는 b를 반환 하는 구조 입니다. 이제 사용법과 개념을 알아 봤으니 실제로 사용되는 코드들을 살펴보겠습니다.


[캐릭터의 이동에 따른 애니메이션 보간]

캐릭터가 이동할 때 방향에 따라서 애니메이션을 블렌딩 하는 코드입니다.

using UnityEngine;

public class CharacterAnimator : MonoBehaviour
{
    public Animator animator;
    public Transform target;

    private float minDistance = 0.1f;
    private float moveSpeed = 5f;

    void Update()
    {
        // 캐릭터가 목표 지점으로 이동
        transform.position = Vector3.Lerp(transform.position, target. Position, Time.deltaTime * moveSpeed);

        // 캐릭터가 목표 지점을 향해 회전
        Vector3 direction = (target. Position - transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
        transform. Rotation = Quaternion.Lerp(transform. Rotation, lookRotation, Time.deltaTime * moveSpeed);

        // 캐릭터의 이동 속도에 따라 애니메이션 블렌딩
        float moveSpeedNormalized = Mathf.Clamp01(Vector3.Distance(transform.position, target.position) / minDistance);
        animator.SetFloat("MoveSpeed", moveSpeedNormalized);
    }
}

목표 지점을 향해 회전할 때 Quaternion.Lerp를 이용하여 회전을 자연스럽게 한 뒤, 이동속도에 다라서 캐릭터의 걷기 애니메이션을 블렌딩 해주는 코드 입니다.

[UI 페이드 인 아웃]

UI가 부드럽게 나타나거나 사라지는 효과를 주는 코드 입니다.

using UnityEngine;
using UnityEngine.UI;

public class UIFadeInOut : MonoBehaviour
{
    public CanvasGroup canvasGroup;
    public float fadeInDuration = 1f;
    public float fadeOutDuration = 1f;

    private float fadeInStartTime;
    private float fadeOutStartTime;
    private bool isFadingIn = false;
    private bool isFadingOut = false;

    void Update()
    {
        // 키 입력 등의 트리거로 페이드 인/아웃을 시작할 수 있습니다.

        // 페이드 인 시작
        if (Input.GetKeyDown(KeyCode.I))
        {
            isFadingIn = true;
            fadeInStartTime = Time.time;
        }

        // 페이드 아웃 시작
        if (Input.GetKeyDown(KeyCode.O))
        {
            isFadingOut = true;
            fadeOutStartTime = Time.time;
        }

        // 페이드 인 진행
        if (isFadingIn)
        {
            float elapsedTime = Time.time - fadeInStartTime;
            float t = Mathf.Clamp01(elapsedTime / fadeInDuration);
            canvasGroup.alpha = Mathf.Lerp(0f, 1f, t); // 투명에서 불투명으로 보간
            if (t >= 1f)
            {
                isFadingIn = false;
            }
        }

        // 페이드 아웃 진행
        if (isFadingOut)
        {
            float elapsedTime = Time.time - fadeOutStartTime;
            float t = Mathf.Clamp01(elapsedTime / fadeOutDuration);
            canvasGroup.alpha = Mathf.Lerp(1f, 0f, t); // 불투명에서 투명으로 보간
            if (t >= 1f)
            {
                isFadingOut = false;
            }
        }
    }
}

알파값을 조정하는 코드 입니다.

[체력 바의 부드러운 감소]

using UnityEngine;
using UnityEngine.UI;

public class HealthBar : MonoBehaviour
{
    public Slider slider;
    public float decreaseSpeed = 0.5f;

    private float currentHealth = 100f;

    void Update()
    {
        // 캐릭터의 체력 감소
        currentHealth -= Time.deltaTime * decreaseSpeed;
        currentHealth = Mathf.Clamp(currentHealth, 0f, 100f);

        // 체력 바의 값 부드럽게 변경
        float t = currentHealth / 100f;
        slider.value = Mathf.Lerp(slider.value, t, Time.deltaTime * 5f);
    }
}

캐릭터의 체력이 줄어들 때 보간 함수를 이용하여 부드럽게 변경해 주는 함수 입니다.

[배경 음악의 볼륨 조절]

using UnityEngine;

public class BackgroundMusic : MonoBehaviour
{
    public AudioSource audioSource;
    public float minVolume = 0.1f;
    public float maxVolume = 1f;
    public float fadeInDuration = 3f;
    public float fadeOutDuration = 2f;

    private bool isFadingIn = false;
    private bool isFadingOut = false;

    void Start()
    {
        audioSource.volume = minVolume;
        isFadingIn = true;
    }

    void Update()
    {
        // 배경 음악을 부드럽게 페이드 인
        if (isFadingIn)
        {
            audioSource.volume = Mathf.Lerp(audioSource.volume, maxVolume, Time.deltaTime / fadeInDuration);
            if (audioSource.volume >= maxVolume * 0.99f)
            {
                isFadingIn = false;
            }
        }

        // 배경 음악을 부드럽게 페이드 아웃
        if (isFadingOut)
        {
            audioSource.volume = Mathf.Lerp(audioSource.volume, minVolume, Time.deltaTime / fadeOutDuration);
            if (audioSource.volume <= minVolume * 1.01f)
            {
                isFadingOut = false;
                audioSource.Stop();
            }
        }
    }

    // 배경 음악을 페이드 아웃하고 정지하는 메서드
    public void FadeOutMusic()
    {
        isFadingOut = true;
    }
}

배경음악이 갑작스럽게 줄거나 늘게 하는 것이 아닌 서서히 줄도록 조정하는 예시 코드 입니다.

[카메라 흔들림 효과]

using UnityEngine;

public class CameraShake : MonoBehaviour
{
    public Transform camTransform;
    public float shakeDuration = 0.5f;
    public float shakeAmount = 0.7f;
    public float decreaseFactor = 1.0f;

    private Vector3 originalPosition;
    private float shakeTimer = 0f;

    void Update()
    {
        if (shakeTimer > 0)
        {
            // 카메라의 원래 위치 저장
            originalPosition = camTransform.localPosition;

            // 랜덤한 벡터를 생성하여 흔들림 효과를 부여
            Vector3 shakeOffset = Random.insideUnitSphere * shakeAmount;

            // 생성된 흔들림 벡터를 카메라의 원래 위치에 더하여 새로운 위치 설정
            camTransform.localPosition = Vector3.Lerp(originalPosition, originalPosition + shakeOffset, shakeTimer / shakeDuration);

            shakeTimer -= Time.deltaTime * decreaseFactor;
        }
        else
        {
            shakeTimer = 0f;
            camTransform.localPosition = originalPosition; // 흔들림 효과 종료 후 원래 위치로 되돌림
        }
    }

    // 흔들림 효과 시작 메서드
    public void ShakeCamera()
    {
        shakeTimer = shakeDuration;
    }
}

위의 코드에서 Mathf.Lerp() 함수는 카메라의 현재 위치와 흔들림 효과가 적용된 새로운 위치를 보간하는 데 사용됩니다. originalPosition은 카메라의 원래 위치를 저장하고, 흔들림 효과가 적용된 새로운 위치는 이 원래 위치에 랜덤한 벡터를 더하여 생성됩니다. 그리고 Mathf.Lerp() 함수를 사용하여 이 두 위치 사이를 부드럽게 이동하도록 설정됩니다. 이를 통해 흔들림 효과가 부드럽게 적용되어 카메라가 자연스럽게 흔들리는 효과를 얻을 수 있습니다.

[마무리 글]

개념만 이해하고 넘어가다 보면 금방 까먹는 함수이지만 사용 예시들을 보면 어디에 사용해야 할지 감이 오기 때문에 활용되는 코드들을 눈에 익히시는 것이 좋습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다