圈住的为生成的坐标点,改变控制点的位置后,坐标点也会跟着变。
点击1后,生成2号文件,即为unity可以使用的asset文件。
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using UnityEditor;
public class BezierPointSpawn : MonoBehaviour
{
[Range(1, 3000)]
public int count = 1;
public List<Transform> controlTransList = new List<Transform>();//控制点
public List<Vector3> bezierPosList = new List<Vector3>();
public float interval = 0.3f;//球的间隔
public List<Vector3> finallyPosList = new List<Vector3>();//最后输出的小球的位置
private void OnDrawGizmos()
{
controlTransList.Clear();
bezierPosList.Clear();
foreach (Transform trans in transform)//取得transform下的所有物体的transform
{
controlTransList.Add(trans);
}
List<Vector3> controlPosList = controlTransList.Select(pos => pos.position).ToList<Vector3>();
bezierPosList = GetBezierPos(controlPosList);
finallyPosList = GetFinallyPosList(bezierPosList);
Gizmos.color = Color.blue;
foreach (var pos in finallyPosList)
{
Gizmos.DrawSphere(pos, 0.16f);
}
Gizmos.color = Color.red;
for (int i = 0; i < controlPosList.Count-1; i++)
{
Gizmos.DrawLine(controlPosList[i], controlPosList[i + 1]);
}
Gizmos.color = Color.green;
for (int i = 0; i < finallyPosList.Count-1; i++)
{
Gizmos.DrawLine(finallyPosList[i], finallyPosList[i + 1]);
}
}
/// <summary>
/// 根据传入的位置获得所有的贝塞尔点
/// </summary>
/// <param name="controlPosList"></param>
/// <returns></returns>
public List<Vector3> GetBezierPos(List<Vector3> controlPosList)
{
List<Vector3> posList = new List<Vector3>();
for (int i = 0; i < controlPosList.Count-3; i+=3)
{
Vector3 p0 = controlPosList[i];
Vector3 p1 = controlPosList[i + 1];
Vector3 p2 = controlPosList[i + 2];
Vector3 p3 = controlPosList[i + 3];
for (int j = 0; j <= count; j++)
{
float t = j / (float)count;
Vector3 pos = CalculateBezierPoint(p0, p1, p2, p3, t);
posList.Add(pos);
}
}
return posList;
}
/// <summary>
/// 四个点 t是0-1之间的值
/// </summary>
public Vector3 CalculateBezierPoint(Vector3 p0,Vector3 p1,Vector3 p2,Vector3 p3,float t)
{
return p0 * (1 - t) * (1 - t) * (1 - t) + 3 * p1 * t * (1 - t) * (1 - t) + 3 * p2 * t * t * (1 - t) + p3 * t * t * t;
}
/// <summary>
/// 只取合适位置的点
/// </summary>
/// <param name="posList"></param>
/// <returns></returns>
public List<Vector3> GetFinallyPosList(List<Vector3> posList)
{
if(posList.Count<=0)
{
return null;
}
List<Vector3> canUseList = new List<Vector3>();
Vector3 startPos = posList[0];
canUseList.Add(startPos);
for (int i = 1; i < posList.Count; i++)
{
if(Vector3.Distance(startPos,posList[i])>= interval)
{
startPos = posList[i];
canUseList.Add(startPos);
}
}
return canUseList;
}
/// <summary>
/// 在"Assets/Map"下创建地图文件
/// </summary>
public void CreateMapAsset()
{
string path = "Assets/Map/map.asset";
MapConfig mapConfig = new MapConfig();
foreach (Vector3 pos in finallyPosList)
{
mapConfig.posList.Add(pos);
}
AssetDatabase.CreateAsset(mapConfig, path);
AssetDatabase.SaveAssets();
}
}
[CustomEditor(typeof(BezierPointSpawn))]
public class BezierEditor:Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if(GUILayout.Button("生成地图文件"))
{
(target as BezierPointSpawn).CreateMapAsset();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapConfig : ScriptableObject
{
public List<Vector3> posList = new List<Vector3>();
}