Hey, I made this small demo to test out an idea for my game. Thought I would share it. I plan on posting the code on the wiki once I add some more flexibility to it ![]()
Looking forward to this! Could see lots of excellent uses.
Hi, the link given there has expired so i request u to pls upload the latest and make it accessible.
thanks in advance
If it can help…
class Bezier extends System.Object {
var p0 : Vector3;
var p1 : Vector3;
var p2 : Vector3;
var p3 : Vector3;
var ti : float = 0.0;
private var b0 : Vector3 = Vector3.zero;
private var b1 : Vector3 = Vector3.zero;
private var b2 : Vector3 = Vector3.zero;
private var b3 : Vector3 = Vector3.zero;
private var Ax : float;
private var Ay : float;
private var Az : float;
private var Bx : float;
private var By : float;
private var Bz : float;
private var Cx : float;
private var Cy : float;
private var Cz : float;
// Init function v0 = 1st point, v1 = handle of the 1st point , v2 = handle of the 2nd point, v3 = 2nd point
// handle1 = v0 + v1
// handle2 = v3 + v2
function Bezier(v0 : Vector3, v1 : Vector3, v2 : Vector3, v3 : Vector3) {
this.p0 = v0;
this.p1 = v1;
this.p2 = v2;
this.p3 = v3;
}
// 0.0 >= t <= 1.0
function GetPointAtTime(t : float) : Vector3 {
this.CheckConstant();
var t2 : float = t * t;
var t3 : float = t * t * t;
var x : float = this.Ax * t3 + this.Bx * t2 + this.Cx * t + p0.x;
var y : float = this.Ay * t3 + this.By * t2 + this.Cy * t + p0.y;
var z : float = this.Az * t3 + this.Bz * t2 + this.Cz * t + p0.z;
return(Vector3(x,y,z));
}
private function SetConstant() {
this.Cx = 3 * ((this.p0.x + this.p1.x) - this.p0.x);
this.Bx = 3 * ((this.p3.x + this.p2.x) - (this.p0.x + this.p1.x)) - this.Cx;
this.Ax = this.p3.x - this.p0.x - this.Cx - this.Bx;
this.Cy = 3 * ((this.p0.y + this.p1.y) - this.p0.y);
this.By = 3 * ((this.p3.y + this.p2.y) - (this.p0.y + this.p1.y)) - this.Cy;
this.Ay = this.p3.y - this.p0.y - this.Cy - this.By;
this.Cz = 3 * ((this.p0.z + this.p1.z) - this.p0.z);
this.Bz = 3 * ((this.p3.z + this.p2.z) - (this.p0.z + this.p1.z)) - this.Cz;
this.Az = this.p3.z - this.p0.z - this.Cz - this.Bz;
}
// Check if p0, p1, p2 or p3 have changed
private function CheckConstant() {
if (this.p0 != this.b0 || this.p1 != this.b1 || this.p2 != this.b2 || this.p3 != this.b3) {
this.SetConstant();
this.b0 = this.p0;
this.b1 = this.p1;
this.b2 = this.p2;
this.b3 = this.p3;
}
}
}
Usage:
var myBezier : Bezier;
private var t : float = 0.0;
function Start() {
myBezier = new Bezier(Vector3(-5,0,0), Random.insideUnitSphere * 2.0, Random.insideUnitSphere * 2.0, Vector3(5,0,0));
}
function Update () {
var vec : Vector3 = myBezier.GetPointAtTime(t);
transform.position = vec;
t+= 0.001;
if (t > 1.0)
t = 0.0;
}
Thanks a lot Loran…
![]()
hi
i like to thank u again for that help. I hav been able to complete that task of a rope very fin. Its an cool and proper Rope that i was able to make.
thanks a lot… ![]()
why the hell do i keep getting parsing error on that Bezier class? :S
It’s Javascript; maybe you’re trying to use it as a C# file?
–Eric
Reup the link if u want please
so people can see what they are using as script.
Thank you loran, Good job. it is work.
So I was looking for a unity bezier curve implementation and found this thread! Loran, your code awesome in every aspect, except it is not C#. So I ported it for myself and for the lazy:
Bezier main class in Bezier.cs:
using UnityEngine;
[System.Serializable]
public class Bezier : System.Object
{
public Vector3 p0;
public Vector3 p1;
public Vector3 p2;
public Vector3 p3;
public float ti = 0f;
private Vector3 b0 = Vector3.zero;
private Vector3 b1 = Vector3.zero;
private Vector3 b2 = Vector3.zero;
private Vector3 b3 = Vector3.zero;
private float Ax;
private float Ay;
private float Az;
private float Bx;
private float By;
private float Bz;
private float Cx;
private float Cy;
private float Cz;
// Init function v0 = 1st point, v1 = handle of the 1st point , v2 = handle of the 2nd point, v3 = 2nd point
// handle1 = v0 + v1
// handle2 = v3 + v2
public Bezier( Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3 )
{
this.p0 = v0;
this.p1 = v1;
this.p2 = v2;
this.p3 = v3;
}
// 0.0 >= t <= 1.0
public Vector3 GetPointAtTime( float t )
{
this.CheckConstant();
float t2 = t * t;
float t3 = t * t * t;
float x = this.Ax * t3 + this.Bx * t2 + this.Cx * t + p0.x;
float y = this.Ay * t3 + this.By * t2 + this.Cy * t + p0.y;
float z = this.Az * t3 + this.Bz * t2 + this.Cz * t + p0.z;
return new Vector3( x, y, z );
}
private void SetConstant()
{
this.Cx = 3f * ( ( this.p0.x + this.p1.x ) - this.p0.x );
this.Bx = 3f * ( ( this.p3.x + this.p2.x ) - ( this.p0.x + this.p1.x ) ) - this.Cx;
this.Ax = this.p3.x - this.p0.x - this.Cx - this.Bx;
this.Cy = 3f * ( ( this.p0.y + this.p1.y ) - this.p0.y );
this.By = 3f * ( ( this.p3.y + this.p2.y ) - ( this.p0.y + this.p1.y ) ) - this.Cy;
this.Ay = this.p3.y - this.p0.y - this.Cy - this.By;
this.Cz = 3f * ( ( this.p0.z + this.p1.z ) - this.p0.z );
this.Bz = 3f * ( ( this.p3.z + this.p2.z ) - ( this.p0.z + this.p1.z ) ) - this.Cz;
this.Az = this.p3.z - this.p0.z - this.Cz - this.Bz;
}
// Check if p0, p1, p2 or p3 have changed
private void CheckConstant()
{
if( this.p0 != this.b0 || this.p1 != this.b1 || this.p2 != this.b2 || this.p3 != this.b3 )
{
this.SetConstant();
this.b0 = this.p0;
this.b1 = this.p1;
this.b2 = this.p2;
this.b3 = this.p3;
}
}
}
And an example usage in MyBezier.cs:
using UnityEngine;
public class MyBezier : MonoBehaviour
{
public Bezier myBezier;
private float t = 0f;
void Start()
{
myBezier = new Bezier( new Vector3( -5f, 0f, 0f ), Random.insideUnitSphere * 2f, Random.insideUnitSphere * 2f, new Vector3( 5f, 0f, 0f ) );
}
void Update()
{
Vector3 vec = myBezier.GetPointAtTime( t );
transform.position = vec;
t += 0.001f;
if( t > 1f )
t = 0f;
}
}
Thank you very much for this.
the lazy thanks you ![]()
the lazy asks (after a month lol) what values should I give the 1st and 2nd handle or the bezier curve?
thank you.
Well, that depends on the shape you want the curve to be…
If you’ve ever used Illustrator and modified curves using those little handlebar things, that is a bezier curve, and the ends of the handlebars are the P1 P2.
The farther those middle points are from a straight line, the more drastic the curvature.
I also mean no disrespect to Loran and Fivedollar, but I do have a really bare-bones implementation of the Bezier function, for anyone who wants to take it way down to basics.
function CalculateBezierPoint(t : float,
p0 : Vector3, p1 : Vector3 , p2 : Vector3 , p3 : Vector3)
{
var u : float = 1.0 - t;
var tt : float = t * t;
var uu : float = u * u;
var uuu : float = uu * u;
var ttt : float = tt * t;
var p : Vector3 = uuu * p0; //first term
p += 3 * uu * t * p1; //second term
p += 3 * u * tt * p2; //third term
p += ttt * p3; //fourth term
return p;
}
Feed it ‘t’ as a 0-1 float representing the point along the curve that you want to get, and the other four points, and it will spit back the point on the curve at that t value.
No, I have never used Illustrator
I opened up Blender and created a bezier curve but there was two points on each of the handle bars. The diagram I found in Wikipedia sort of explains it though ![]()
Thank you for your bare-bones version
Will try using that ![]()
i hope u have free time to explane me about Bezier Curve in unity3d,i’m waiting ur reply
can u explaine me clear me about Bezier Curve in unity 3d clearly then now?
I’ll give it a shot…
A Bezier Curve is a curved line that is defined by four points.
The first and last points are the ends of the curve, and the two points in the middle distort and define the curvature.
Here’s a picture that might help explain it.
In this picture, you can see three Bezier Curves of different shapes.
The P0-P3 points’ coordinates are called out, the gray lines are just to help point them out.
To use my function above, define the curve you want in 3D space, enter in those four points, and a time value ‘t’.
‘t’ represents the amount along the curve you want to generate the point for. 0 will return P0, 1 will return P3, .5 will give you the point in the center of the curve.
The intended use is to use this multiple times in a loop, and either use those points to move or draw something, or store those point in an array for later use…
Thanks for all this, very helpful =)
You’re welcome, I’m glad it is useful!
And one thing I forgot to mention is that even though my example info there is only 2-D, this function works in 3-D.
I’m using it right now for flight paths for missiles…
I start with the beginning and end known, then add an offset to both those points to move P1 P2 up in the +Y direction, run a loop with as many points as I need for precision, and fill an array for my path.
I also add a small random number to P1 P2, so the missiles don’t always fly in a plane between the gun and the target.
I make sure that I move them both in the same direction, by the same amount, and the effect is basically as if the flight path rotated to the side a few degrees.
If I applied different numbers, or they were in opposite directions, or the offsets were extreme, the curve could be a really funky 3-D S-curve.
You can get some pretty interesting curves, even only with four points…
Edit: added
And if you want to think about the next level, you can chain multiple bezier curves together to make more complicated paths.
If you make sure that your P2 from the first curve, the shared P3/P0, and P1 of the second curve are all on the same line (in 3D), the join will be smooth.
If they are not co-linear, there will be a ‘corner’ at the join.
Which I suppose could be a desired outcome in some cases…
