뭐 ㅈ도 없긴한데 그래도 혹시 쓸사람 있을까봐 올려봄 ㅇㅇ 16차까지 지원함
이건 시연 링크
소스코드
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace RPG.Utility{
public class BezierDebugger : MonoBehaviour
{
[SerializeField]
private GameObject gameObject;
// 시점 t
[Range(0, 1)]
[SerializeField]
private float t;
public List<Vector3> vectors;
// 16!까지 팩토리얼 미리계산 팩토리얼은 계산비용이 비싸고 15~16차 이상으로 베지어함수가 가는 경우는
// 비용문제도있고 그렇게까지 복잡한 곡선이 필요한 경우가 거의 없기때문에 미리 상수로 계산해도 문제 없을듯?
private float[] factorial = new float[]
{
1.0f,
1.0f,
2.0f,
6.0f,
24.0f,
120.0f,
720.0f,
5040.0f,
40320.0f,
362880.0f,
3628800.0f,
39916800.0f,
479001600.0f,
6227020800.0f,
87178291200.0f,
1307674368000.0f,
20922789888000.0f,
};
// n차 베지어 함수 구현에 필요한 이항계수 구현함수
private float Binomial(int n, int i)
{
float ni;
float a1 = factorial[n];
float a2 = factorial[i];
float a3 = factorial[n - i];
ni = a1 / (a2 * a3);
return ni;
}
// 번스타인 함수 고닥교땐가 배웟던 이항계수가 앞에 붙은 형태의 함수인듯?
private float Bernstein(int n, int i, float t)
{
float t_i = Mathf.Pow(t, i);
float t_n_minus_i = Mathf.Pow((1 - t), (n - i));
float basis = Binomial(n, i) * t_i * t_n_minus_i;
return basis;
}
// 제어점들이 주어져있을때 시점 t에서의 베지어 곡선의 위치
public Vector3 Point3(float t, List<Vector3> controlPoints)
{
int N = controlPoints.Count - 1;
if (N > 16)
{
Debug.Log("You have used more than 16 control points. The maximum control points allowed is 16.");
controlPoints.RemoveRange(16, controlPoints.Count - 16);
}
if (t <= 0) return controlPoints[0];
if (t >= 1) return controlPoints[controlPoints.Count - 1];
Vector3 p = new Vector3();
for (int i = 0; i < controlPoints.Count; ++i)
{
Vector3 bn = Bernstein(N, i, t) * controlPoints[i];
p += bn;
}
return p;
}
public List<Vector3> PointList3(List<Vector3> controlPoints, float interval = 0.01f){
int n = controlPoints.Count -1;
if (n > 16){
Debug.Log("16차 이상은 지원하지 않습니다");
controlPoints.RemoveRange(16, controlPoints.Count - 16);
}
List<Vector3> points = new List<Vector3>();
for (float t = 0.0f; t <= 1.0f + interval - 0.0001f; t += interval)
{
Vector3 p = new Vector3();
for (int i = 0; i < controlPoints.Count; ++i)
{
Vector3 bn = Bernstein(n, i, t) * controlPoints[i];
p += bn;
}
points.Add(p);
}
return points;
}
}
[CanEditMultipleObjects]
[CustomEditor(typeof(BezierDebugger))]
public class BezierDebuggerEditor : Editor{
private void OnSceneGUI() {
BezierDebugger generator = (BezierDebugger)target;
for (int i = 0; i < generator.vectors.Count; i++){
generator.vectors[i] = Handles.PositionHandle(generator.vectors[i], Quaternion.identity);
}
for (float i = 0; i < 100; i++){
float value_before = i / 10;
Vector3 before = generator.Point3(value_before, generator.vectors);
float value_after = (i + 1) / 10;
Vector3 after = generator.Point3(value_after, generator.vectors);
Handles.DrawLine(before, after);
}
}
}
}
레퍼런스
https://www.youtube.com/watch?v=KTEX2L4T4zE&t=0s
https://faramira.com/implement-bezier-curve-using-csharp-in-unity/
https://blog.naver.com/PostView.naver?blogId=kyuniitale&logNo=40022945907&redirect=Dlog&widgetTypeCall=true&directAccess=false
굇수 ㄷㄷㄷ