頭一回寫這個文章,也是就分享一點自己的學習心得,并且記錄下自己做過的這個功能,
事實上我這也是借鑒了大佬的代碼,統籌琢磨出來的,比較初級,但是有用,
話不多說,上效果圖:

如圖所見,展現出來的功能組件很簡單,就是一個繼承了Image并且多加了幾個變數的自定義組件 ,實作的就是右邊將圖片作為元素繪制成一條貝塞爾曲線,
控制點串列中的點資料我做的還不夠智能,暫時用第一個和最后一個表示這條線的起點和終點,而其他的點都是這條貝塞爾曲線的極點了,
“密集度 mesh數量”可以看成是要生成多少個圖片元素
“mesh寬度”可以看成你要生成圖片元素的大小
反正就那個意思,很簡單,我就不多啰嗦了,看見這篇文章的朋友完全可以直接下來用,大家也可以根據我的代碼進行拓展的,看懂原來的垃圾代碼就好了嘿嘿~(手都滑稽)
public static class Bezier
{
/// <summary>
/// 獲取繪制點
/// </summary>
/// <param name="controlPoints">控制點串列</param>
/// <param name="density">密度</param>
/// <returns></returns>
public static Vector3[] GetPointList(List<Vector2> controlPoints, int density)
{
List<Vector3> points = new List<Vector3>();
for(int i = 0; i <= density; i++)
{
points.Add(BezierMath(i / (float)density, controlPoints.Count - 1, controlPoints));
}
return points.ToArray();
}
/// <summary>
/// 貝塞爾曲線的函式
/// </summary>
/// <param name="t">分段引數</param>
/// <param name="lineNum">線段數量</param>
/// <param name="controlPoints">錨點串列</param>
/// <returns></returns>
public static Vector2 BezierMath(float t, int lineNum, List<Vector2> controlPoints)
{
Vector2 result = new Vector2();
for (int i = 0; i <= lineNum; i++)
{
float temp = BaseBezier(t, i, lineNum);
result.x += controlPoints[i].x * temp;
result.y += controlPoints[i].y * temp;
}
return result;
}
/// <summary>
/// 貝塞爾基函式
/// </summary>
/// <param name="t">引數</param>
/// <param name="index">線段序號</param>
/// <param name="lineNum">線段數量</param>
/// <returns></returns>
public static float BaseBezier(float t, int index, int lineNum)
{
float result = Factorial(lineNum) * Mathf.Pow(t, index) * Mathf.Pow(1 - t, lineNum - index) / (Factorial(index) * Factorial(lineNum - index));
return result;
}
/// <summary>
/// Factorial 階乘
/// </summary>
/// <param name="step"></param>
/// <returns></returns>
public static int Factorial(int step)
{
int result = 1;
for (int j = step; j > 1; j--)
{
result *= j;
}
return result;
}
}
public class BezierMeshImage : Image
{
/// <summary> 密集度 mesh數量 </summary>
public int density = 50;
/// <summary> mesh 寬度 </summary>
public float width;
/// <summary> 控制點串列 </summary>
public List<Vector2> controlList = new List<Vector2>();
/// <summary> 貝塞爾點陣列 </summary>
Vector3[] bezierPoints;
protected override void OnPopulateMesh(VertexHelper vh)
{
bezierPoints = Bezier.GetPointList(controlList, density);
vh.Clear();
for (int index = 0; index < bezierPoints.Length; index++)
{
Vector3 baseVector = bezierPoints[index];
var i = index * 4;
vh.AddVert(baseVector + new Vector3(-width/2, -width/2, 1), color, new Vector2(0f, 0f));
vh.AddVert(baseVector + new Vector3(-width/2, width/2, 1), color, new Vector2(0f, 1f));
vh.AddVert(baseVector + new Vector3(width/2, width/2, 1), color, new Vector2(1f, 1f));
vh.AddVert(baseVector + new Vector3(width/2, -width/2, 1), color, new Vector2(1f, 0f));
vh.AddTriangle(i, i + 1, i + 2);
vh.AddTriangle(i + 2, i + 3, i);
}
}
}
[CustomEditor(typeof(BezierMeshImage))] // 定義子類的編輯器擴展
public class BezierMeshImageEditor : ImageEditor
{
private BezierMeshImage be;
public List<Vector2> pointList;
public static bool isOpenList;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
be = (BezierMeshImage)base.target;
//be.controlV2 = EditorGUILayout.Vector2Field("控制點坐標", be.controlV2);
be.density = EditorGUILayout.IntField("密集度 mesh數量", be.density);
be.width = EditorGUILayout.FloatField("mesh 寬度 ", be.width);
pointList = be.controlList;
isOpenList = EditorGUILayout.Foldout(isOpenList, "控制點串列");
if(isOpenList)
{
for(int i = 0; i < pointList.Count; i++)
{
pointList[i] = EditorGUILayout.Vector2Field(name, pointList[i]);
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("+"))
{
Vector2 point = new Vector2();
point = EditorGUILayout.Vector2Field(name, point);
pointList.Add(point);
}
if (GUILayout.Button("-"))
{
if (pointList.Count > 0)
pointList.RemoveAt(pointList.Count - 1);
}
EditorGUILayout.EndHorizontal();
}
be.controlList = pointList;
if (HasPreviewGUI())
{
be.enabled = false;
be.enabled = true;
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/384421.html
標籤:其他
上一篇:二、計算機就是數學
下一篇:每日寫題分享--優先佇列
