# Unity3D教你制作Bezier和Spine曲线编辑器三

using UnityEngine;

public class BezierSpline : MonoBehaviour {

public Vector3[] points;

public Vector3 GetPoint (float t) {
return transform.TransformPoint(Bezier.GetPoint(points[0], points[1], points[2], points[3], t));
}

public Vector3 GetVelocity (float t) {
return transform.TransformPoint(
Bezier.GetFirstDerivative(points[0], points[1], points[2], points[3], t)) - transform.position;
}

public Vector3 GetDirection (float t) {
return GetVelocity(t).normalized;
}

public void Reset () {
points = new Vector3[] {
new Vector3(1f, 0f, 0f),
new Vector3(2f, 0f, 0f),
new Vector3(3f, 0f, 0f),
new Vector3(4f, 0f, 0f)
};
}
}

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(BezierSpline))]
public class BezierSplineInspector : Editor {

private const int lineSteps = 10;
private const float directionScale = 0.5f;

private BezierSpline spline;
private Transform handleTransform;
private Quaternion handleRotation;

private void OnSceneGUI () {
spline = target as BezierSpline;
handleTransform = spline.transform;
handleRotation = Tools.pivotRotation == PivotRotation.Local ?
handleTransform.rotation : Quaternion.identity;

Vector3 p0 = ShowPoint(0);
Vector3 p1 = ShowPoint(1);
Vector3 p2 = ShowPoint(2);
Vector3 p3 = ShowPoint(3);

Handles.color = Color.gray;
Handles.DrawLine(p0, p1);
Handles.DrawLine(p2, p3);

ShowDirections();
Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f);
}

private void ShowDirections () {
Handles.color = Color.green;
Vector3 point = spline.GetPoint(0f);
Handles.DrawLine(point, point + spline.GetDirection(0f) * directionScale);
for (int i = 1; i <= lineSteps; i++) {
point = spline.GetPoint(i / (float)lineSteps);
Handles.DrawLine(point, point + spline.GetDirection(i / (float)lineSteps) * 
		 directionScale);
}
}

private Vector3 ShowPoint (int index) {
Vector3 point = handleTransform.TransformPoint(spline.points[index]);
EditorGUI.BeginChangeCheck();
point = Handles.DoPositionHandle(point, handleRotation);
if (EditorGUI.EndChangeCheck()) {
Undo.RecordObject(spline, "Move Point");
EditorUtility.SetDirty(spline);
spline.points[index] = handleTransform.InverseTransformPoint(point);
}
return point;
}
}

public void AddCurve () {
Vector3 point = points[points.Length - 1];
Array.Resize(ref points, points.Length + 3);
point.x += 1f;
points[points.Length - 3] = point;
point.x += 1f;
points[points.Length - 2] = point;
point.x += 1f;
points[points.Length - 1] = point;
}

using UnityEngine;
using System;

	public override void OnInspectorGUI () {
DrawDefaultInspector();
spline = target as BezierSpline;
EditorUtility.SetDirty(spline);
}
}

private void OnSceneGUI () {
spline = target as BezierSpline;
handleTransform = spline.transform;
handleRotation = Tools.pivotRotation == PivotRotation.Local ?
handleTransform.rotation : Quaternion.identity;

Vector3 p0 = ShowPoint(0);
for (int i = 1; i < spline.points.Length; i += 3) {
Vector3 p1 = ShowPoint(i);
Vector3 p2 = ShowPoint(i + 1);
Vector3 p3 = ShowPoint(i + 2);

Handles.color = Color.gray;
Handles.DrawLine(p0, p1);
Handles.DrawLine(p2, p3);

Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f);
p0 = p3;
}
ShowDirections();
}

	public int CurveCount {
get {
return (points.Length - 1) / 3;
}
}

public Vector3 GetPoint (float t) {
int i;
if (t >= 1f) {
t = 1f;
i = points.Length - 4;
}
else {
t = Mathf.Clamp01(t) * CurveCount;
i = (int)t;
t -= i;
i *= 3;
}
return transform.TransformPoint(Bezier.GetPoint(
points[i], points[i + 1], points[i + 2], points[i + 3], t));
}

public Vector3 GetVelocity (float t) {
int i;
if (t >= 1f) {
t = 1f;
i = points.Length - 4;
}
else {
t = Mathf.Clamp01(t) * CurveCount;
i = (int)t;
t -= i;
i *= 3;
}
return transform.TransformPoint(Bezier.GetFirstDerivative(
points[i], points[i + 1], points[i + 2], points[i + 3], t)) - transform.position;
}

BezierSplineInspector，显示方向，所以它使用BezierSpline，曲率决定画多少线。

private const int stepsPerCurve = 10;

private void ShowDirections () {
Handles.color = Color.green;
Vector3 point = spline.GetPoint(0f);
Handles.DrawLine(point, point + spline.GetDirection(0f) * directionScale);
int steps = stepsPerCurve * spline.CurveCount;
for (int i = 1; i <= steps; i++) {
point = spline.GetPoint(i / (float)steps);
Handles.DrawLine(point, point + spline.GetDirection(i / (float)steps) * directionScale);
}
}

private const float handleSize = 0.04f;
private const float pickSize = 0.06f;

private int selectedIndex = -1;

private Vector3 ShowPoint (int index) {
Vector3 point = handleTransform.TransformPoint(spline.points[index]);
Handles.color = Color.white;
if (Handles.Button(point, handleRotation, handleSize, pickSize, Handles.DotCap)) {
selectedIndex = index;
}
if (selectedIndex == index) {
EditorGUI.BeginChangeCheck();
point = Handles.DoPositionHandle(point, handleRotation);
if (EditorGUI.EndChangeCheck()) {
Undo.RecordObject(spline, "Move Point");
EditorUtility.SetDirty(spline);
spline.points[index] = handleTransform.InverseTransformPoint(point);
}
}
return point;
}

		float size = HandleUtility.GetHandleSize(point);
Handles.color = Color.white;
if (Handles.Button(point, handleRotation, size * handleSize, size * pickSize, Handles.DotCap)) {
selectedIndex = index;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：Unity3D教你制作Bezier和Spine曲线编辑器三 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)