|
|
- using UnityEngine;
- using System;
-
- public class BezierSpline : MonoBehaviour {
-
- [SerializeField]
- private Vector3[] points;
-
- [SerializeField]
- private BezierControlPointMode[] modes;
-
- [SerializeField]
- private bool loop;
-
- public bool Loop {
- get {
- return loop;
- }
- set {
- loop = value;
- if (value == true) {
- modes[modes.Length - 1] = modes[0];
- SetControlPoint(0, points[0]);
- }
- }
- }
-
- public int ControlPointCount {
- get {
- return points.Length;
- }
- }
-
- public Vector3 GetControlPoint (int index) {
- return points[index];
- }
-
- public void SetControlPoint (int index, Vector3 point) {
- if (index % 3 == 0) {
- Vector3 delta = point - points[index];
- if (loop) {
- if (index == 0) {
- points[1] += delta;
- points[points.Length - 2] += delta;
- points[points.Length - 1] = point;
- }
- else if (index == points.Length - 1) {
- points[0] = point;
- points[1] += delta;
- points[index - 1] += delta;
- }
- else {
- points[index - 1] += delta;
- points[index + 1] += delta;
- }
- }
- else {
- if (index > 0) {
- points[index - 1] += delta;
- }
- if (index + 1 < points.Length) {
- points[index + 1] += delta;
- }
- }
- }
- points[index] = point;
- EnforceMode(index);
- }
-
- public BezierControlPointMode GetControlPointMode (int index) {
- return modes[(index + 1) / 3];
- }
-
- public void SetControlPointMode (int index, BezierControlPointMode mode) {
- int modeIndex = (index + 1) / 3;
- modes[modeIndex] = mode;
- if (loop) {
- if (modeIndex == 0) {
- modes[modes.Length - 1] = mode;
- }
- else if (modeIndex == modes.Length - 1) {
- modes[0] = mode;
- }
- }
- EnforceMode(index);
- }
-
- private void EnforceMode (int index) {
- int modeIndex = (index + 1) / 3;
- BezierControlPointMode mode = modes[modeIndex];
- if (mode == BezierControlPointMode.Free || !loop && (modeIndex == 0 || modeIndex == modes.Length - 1)) {
- return;
- }
-
- int middleIndex = modeIndex * 3;
- int fixedIndex, enforcedIndex;
- if (index <= middleIndex) {
- fixedIndex = middleIndex - 1;
- if (fixedIndex < 0) {
- fixedIndex = points.Length - 2;
- }
- enforcedIndex = middleIndex + 1;
- if (enforcedIndex >= points.Length) {
- enforcedIndex = 1;
- }
- }
- else {
- fixedIndex = middleIndex + 1;
- if (fixedIndex >= points.Length) {
- fixedIndex = 1;
- }
- enforcedIndex = middleIndex - 1;
- if (enforcedIndex < 0) {
- enforcedIndex = points.Length - 2;
- }
- }
-
- Vector3 middle = points[middleIndex];
- Vector3 enforcedTangent = middle - points[fixedIndex];
- if (mode == BezierControlPointMode.Aligned) {
- enforcedTangent = enforcedTangent.normalized * Vector3.Distance(middle, points[enforcedIndex]);
- }
- points[enforcedIndex] = middle + enforcedTangent;
- }
-
- 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;
- }
-
- public Vector3 GetDirection (float t) {
- return GetVelocity(t).normalized;
- }
-
- 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;
-
- Array.Resize(ref modes, modes.Length + 1);
- modes[modes.Length - 1] = modes[modes.Length - 2];
- EnforceMode(points.Length - 4);
-
- if (loop) {
- points[points.Length - 1] = points[0];
- modes[modes.Length - 1] = modes[0];
- EnforceMode(0);
- }
- }
-
- 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)
- };
- modes = new BezierControlPointMode[] {
- BezierControlPointMode.Free,
- BezierControlPointMode.Free
- };
- }
- }
|