오늘은 베지어 커브에 대해 공부해 보았다
이론은 이러하다
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
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