Skip to content

Instantly share code, notes, and snippets.

@Adjuvant
Forked from mathhun/Unity Bezier Curve Script
Last active December 3, 2018 22:57
Show Gist options
  • Select an option

  • Save Adjuvant/06104c5b28369ca1420bfb6fd4e9f88b to your computer and use it in GitHub Desktop.

Select an option

Save Adjuvant/06104c5b28369ca1420bfb6fd4e9f88b to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
// TODO: currently abit wrong.
// Update to configure points-path-segment issue.
// Enforce some rules?
[RequireComponent(typeof(LineRenderer))]
public class LineRendererBezierCurve : MonoBehaviour
{
public Shader shader;
[Range(3,100)]
public int pointCount = 100;
BezierPath path;
public Transform[] objects;
Vector3[] storedObjects;
LineRenderer lines;
private void Awake()
{
path = new BezierPath(pointCount);
}
private bool ObjectsChanged(){
if (objects.Length != storedObjects.Length)
{
return true;
}
for (int i = 0; i < objects.Length; i++)
{
if (storedObjects[i] != objects[i].position)
return true;
}
return false;
}
private void SetStoredObjects(){
storedObjects = new Vector3[objects.Length];
for (int i = 0; i < objects.Length; i++){
storedObjects[i] = objects[i].position;
}
}
private void CreateLine(float lineSize, Color c)
{
lines = GetComponent<LineRenderer>();
lines.material = new Material(shader);
lines.material.color = c;
lines.useWorldSpace = false;
lines.startWidth = lineSize;
lines.endWidth = lineSize;
lines.positionCount=path.pointCount;
}
private void UpdatePath()
{
List<Vector3> pathPoints = new List<Vector3>();
for (int o = 0; o < objects.Length; o++)
{
if (objects[o] != null)
{
Vector3 p = objects[o].transform.position;
pathPoints.Add(p);
}
}
path.DeletePath();
path.CreateCurve(pathPoints);
}
private void DrawLine(){
lines.SetPositions(path.pathPoints.ToArray());
}
private void SetupLine(){
SetStoredObjects();
UpdatePath();
CreateLine(0.25f, Color.blue);
DrawLine();
}
private void RedrawLine(){
SetStoredObjects();
UpdatePath();
DrawLine();
}
// Use this for initialization
void Start()
{
SetupLine();
}
// Update is called once per frame
void Update()
{
if (ObjectsChanged())
{
RedrawLine();
}
}
void OnDrawGizmos()
{
if (objects.Length < 4) return;
UpdatePath();
for (int i = 1; i < (path.pointCount); i++)
{
Vector3 startv = path.pathPoints[i - 1];
Vector3 endv = path.pathPoints[i];
Gizmos.color = Color.blue;
Gizmos.DrawLine(startv, endv);
}
}
}
public class BezierPath
{
public List<Vector3> pathPoints;
private int segments;
public int pointCount;
public BezierPath()
{
pathPoints = new List<Vector3>();
pointCount = 100;
}
public BezierPath(int points){
pathPoints = new List<Vector3>();
pointCount = points;
}
public void DeletePath()
{
pathPoints.Clear();
}
Vector3 BezierPathCalculation(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
float tt = t * t;
float ttt = t * tt;
float u = 1.0f - t;
float uu = u * u;
float uuu = u * uu;
Vector3 B = new Vector3();
B = uuu * p0;
B += 3.0f * uu * t * p1;
B += 3.0f * u * tt * p2;
B += ttt * p3;
return B;
}
public void CreateCurve(List<Vector3> controlPoints)
{
segments = controlPoints.Count / 3;
for (int s = 0; s < controlPoints.Count - 3; s += 3)
{
Vector3 p0 = controlPoints[s];
Vector3 p1 = controlPoints[s + 1];
Vector3 p2 = controlPoints[s + 2];
Vector3 p3 = controlPoints[s + 3];
if (s == 0)
{
pathPoints.Add(BezierPathCalculation(p0, p1, p2, p3, 0.0f));
}
for (int p = 0; p < (pointCount / segments); p++)
{
float t = (1.0f / (pointCount / segments)) * p;
Vector3 point = new Vector3();
point = BezierPathCalculation(p0, p1, p2, p3, t);
pathPoints.Add(point);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment