본문 바로가기
게임 개발/게임 수학

베지어 곡선

by FlowTree 2020. 4. 13.
반응형

참고 링크

https://denisrizov.com/2016/06/02/bezier-curves-unity-package-included/

 

베지어 곡선은 선형보간을 이용해서 포물선을 만들 수 있다.

3차 베지어 곡선 최적화 코드

Vector3 GetPointOnBezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
    float u = 1f - t;
    float t2 = t * t;
    float u2 = u * u;
    float u3 = u2 * u;
    float t3 = t2 * t;
 
    Vector3 result =
        (u3) * p0 +
        (3f * u2 * t) * p1 +
        (3f * u * t2) * p2 +
        (t3) * p3;
 
    return result;
}

 

Vector3.Lerp를 이용한 3차 베지어 곡선

점 4개와 선형보간을 이용하여 포물선을 구현했다. 유니티로 배우는 게임 수학에서는 행렬로 구현해서 이해를 잘 못했는데 베지어 곡선이 움직이는 원리를 보고 이해하니 Vector3.Lerp로 구현할 수 있었다.

public class FireballProjectile : MonoBehaviour
{
 public Vector3 startPos; //파이어볼 시작위치
 public Vector3 endPos; //파이어볼 종료위치 = 파이어볼 범위 오브젝트 위치
 
 public Vector3 startHeightPos;
 public Vector3 endHeightPos;

 public float height = 3.5f; //포물선 높이

 float t; //베지어곡선에 사용할 시간t

   void Start()
   {
        startTime = Time.time;

        //Fireball 스크립트의 firePoint, fireballEndPos 위치 가져오기
        Fireball fireball = GameObject.Find("Player").GetComponent<Fireball>(); //다른 스크립트에 있는 변수 접근, 해당 스크립트가 있는 오브젝트 찾아서 접근

        //Fireball 스크립트의 firePoint.transform.position 시작위치로 지정한다.
        startPos = fireball.firePoint.transform.position;

        //Fireball 스크립트의 fireballEndPos를 종료위치로 지정한다.
        endPos = fireball.fireballEndPos;

        //height를 적용한 점 2개
        startHeightPos = startPos + new Vector3(0, 1, 0) * height;
        endHeightPos = endPos + new Vector3(0, 1, 0) * height;
   }

   void Update()
   {
        //t 계산해서 BezierCurve()로 전달
        t = (Time.time - startTime) / duration;

        BezierCurve();
   }


   void BezierCurve()
   {
        Vector3 a = Vector3.Lerp(startPos, startHeightPos, t); //Mathf.SmoothStep(tMin, tMax, t)값이 자연스럽게 증가하는건데 생각보다 별로다.
        Vector3 b = Vector3.Lerp(startHeightPos, endHeightPos, t);
        Vector3 c = Vector3.Lerp(endHeightPos, endPos, t);

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

        Vector3 f = Vector3.Lerp(d, e, t);

        transform.position = f;
   }
}

 

반응형

'게임 개발 > 게임 수학' 카테고리의 다른 글

포물선-탄도(Trajectory) 계산  (0) 2020.04.14

댓글