본문 바로가기
Study

Unity, 베지에 곡선으로 포물선 만들기 (Bezier Curve)

by Client. DJ 2023. 3. 1.
반응형

4개의 정점을 통해서 포물선을 얻을 수 있다.
BezierTransform.unitypackage
0.01MB

베지에 곡선

게임 제작에 있어서, 포물선 구현이 필요한 경우가 생기는데 이는 베지에(Bezier) 곡선을 통해서 구할 수 있습니다. 이는 4개의 정점을 통해서 간단하게 구현이 가능합니다.

베지에 곡선을 구하는 원리

각 변의 0.5로 Lerp되는 구간을 구하고, 또 이어 붙인다. 그렇게 반복을 한다.

위 이미지를 예시로 들어, Value 값이 0.5의 Lerp되는 값을 구한다고 가정합시다

  1. 'P1, P2, P3, P4'를 위 그림처럼 이어 3개의 변을 만들어줍니다. 처러 각 변의 각각 0.5 구간이 되는 구간인 'a, b, c' 구해 옵니다.
  2. 이번에는 각각 구해진 'a, b, c'를 이어 새로운 2개의 변을 만들어 0.5 구간이 되는 'd, e'를 구합니다.
  3. de0.5가 되는 구간인 f를 구합니다.

Value값이 0.5에 해당하는 베지에 f를 얻을 수 있습니다. 이렇게 각 구간의 베지에 값 f를 구하여, '0.0 ~ 1.0'를 이으면 곡선을 구할 수 있게 됩니다.

스크립트

public static class BazierMath
{
    /// <summary>
    /// 4개의 정점으로 러프된 베지에 값을 가져온다
    /// </summary>
    /// <param name="p1">정점1</param>
    /// <param name="p2">정점2</param>
    /// <param name="p3">정점3</param>
    /// <param name="p4">정점4</param>
    /// <param name="value">러프값(0f ~ 1f)</param>
    /// <returns>러프된 베지에 값</returns>
    public static Vector3 Lerp(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float value)
    {
        Vector3 a = Vector3.Lerp(p1, p2, value);
        Vector3 b = Vector3.Lerp(p2, p3, value);
        Vector3 c = Vector3.Lerp(p3, p4, value);

        Vector3 d = Vector3.Lerp(a, b, value);
        Vector3 e = Vector3.Lerp(b, c, value);

        Vector3 f = Vector3.Lerp(d, e, value);
        return f;
    }
}

예제

아래의 컴포넌트로 확인할 수 있습니다.

public class BezierController : MonoBehaviour
{
    [Range(0f, 1f)]
    public float value = 0f;
    public Vector3 p1;
    public Vector3 p2;
    public Vector3 p3;
    public Vector3 p4;

    public void FixedUpdate()
    {
        this.transform.localPosition = BazierMath.Lerp(p1, p2, p3, p4, value);
    }
}

마무리

게임 개발에서 도움이 되는 스크립트로, 테스트로도 사용할 수 있도록 배포했습니다. 많은 도움되기를 바랍니다.

업데이트

- 부모 오브젝트가 있는 경우 GUI가 정상적으로 렌더링되지 않던 부분 수정

- 애니메이션 커브 추가

- Auto LookAt 기능 추가

- 비플레이 모드에서도 움직이도록 하여 애니메이션을 미리 확일할 수 있도록 수정


참고 1: https://namu.wiki/w/%EB%B2%A0%EC%A7%80%EC%97%90%20%EA%B3%A1%EC%84%A0

참고 2: https://www.youtube.com/watch?v=KTEX2L4T4zE

 

반응형

댓글