Unity Bezier Curve

오늘은 베지어 커브에 대해 공부해 보았다

이론은 이러하다

3개의 네모 박스가 존재하고

첫 번째 파란색 동그라미는 Point 1에서 Point 2로 향하고

두 번째 파란색 동그라미는 Point 2에서 Point 3으로 향한다

향할때는 Lerp(보간)식을 이용해서 간다

targets[0].position = Vector3.Lerp(points[0].position, points[1].position, t / s);
targets[1].position = Vector3.Lerp(points[1].position, points[2].position, t / s);

이때 보라색 하트는 첫 번째 파란색 동그라미와 두 번째 파란색 동그라미의 위치를 Lerp의 매개변수로 받아서 사용한다

player.position = Vector3.Lerp(targets[0].position, targets[1].position, t / s);

 

그렇다면 2차원이상의 곡선은 어떻게해야하나?

위 코드로는 작성이 불가능하다

따라서 새롭게 작성해줘야 한다

 

private void Update()
    {
        player.position = new Vector3(
            FourPointBezier(point[0].x,point[1].x,point[2].x,point[3].x), 0,
            FourPointBezier(point[0].z,point[1].z,point[2].z,point[3].z)
        );

    }

  
    float FourPointBezier(float a, float b, float c, float d)
    {
        t += Time.deltaTime;
        if (t >= s) t = s;

        return Mathf.Pow((1 - t), 3) * a
               + Mathf.Pow((1 - t), 2) * 3 * t * b
               + Mathf.Pow(t, 2) * 3 * (1 - t) * c
               + Mathf.Pow(t, 3) * d;
        
    }

나는 2차원에서의 좌표를 이용했을 뿐

3차원에서도 이용가능하다

 

참고

https://www.gamedeveloper.com/business/how-to-work-with-bezier-curve-in-games-with-unity

 

How to work with Bezier Curve in Games with Unity

The main objective of this blog post is to give you a basic idea about how to work with Bezier Curve In Games.

www.gamedeveloper.com

출처 - https://blog.naver.com/PostView.nhn?blogId=ratoa&logNo=220649189397

 

using UnityEngine;
using UnityEngine.Serialization;


public class TestBezierCurve : MonoBehaviour
{
    public GameObject target;
    public Vector3[] point;
    private int x, z;
    public float t;
    public float s;
    public float _newPointDistanceFromStartTr = 6f;
    public float _newPointDistanceFromEndTr = 3f;
    
    public Transform player;

    private void Start()
    {
        s = 1f;
        point = new Vector3[4];
        // 시작 지점.
        point[0] = player.position; 

// 시작 지점을 기준으로 랜덤 포인트 지정.
        point[1] = player.position +
                   (_newPointDistanceFromStartTr * Random.Range(-1.0f, 1.0f) * player.right) + // X (좌, 우 전체)
                   (_newPointDistanceFromStartTr * Random.Range(-1.0f, 1.0f) * player.up) + // Y (위, 아래 전체)
                   (_newPointDistanceFromStartTr * Random.Range(-1.0f, 1.0f) * player.forward); // Z (앞, 뒤 전체)

// 도착 지점을 기준으로 랜덤 포인트 지정.
        point[2] = target.transform.position +      
                   (_newPointDistanceFromEndTr * Random.Range(-1.0f, 1.0f) * target.transform.right) + // X (좌, 우 전체)
                   (_newPointDistanceFromEndTr * Random.Range(-1.0f, 1.0f) * target.transform.up) + // Y (위, 아래 전체)
                   (_newPointDistanceFromEndTr * Random.Range(-1.0f, 1.0f) * target.transform.forward); // Z (앞, 뒤 전체)

// 도착 지점.
        point[3] = target.transform.position;
    }

    private void Update()
    {
        this.transform.position = new Vector3(
            FourPointBezier(point[0].x,point[1].x,point[2].x,point[3].x), FourPointBezier(point[0].y,point[1].y,point[2].y, point[3].y),
            FourPointBezier(point[0].z,point[1].z,point[2].z,point[3].z)
        );

        if (transform.position == target.transform.position)
        {
            Destroy(this.gameObject);
        }
    }

  
    float FourPointBezier(float a, float b, float c, float d)
    {
        t += Time.deltaTime;
        if (t >= s) t = s;

        return Mathf.Pow((1 - t), 3) * a
               + Mathf.Pow((1 - t), 2) * 3 * t * b
               + Mathf.Pow(t, 2) * 3 * (1 - t) * c
               + Mathf.Pow(t, 3) * d;
        
    }

}

베지어 커브를 활용해서 카이사 q 구현하는 방식이라고 한다

코드출처

https://mingyu0403.tistory.com/307

한 프레임씩 진행하느라 느리게 보이는 거