Spline Editor

I was working on an arcade racer game (like Mario Kart) in Unity,
where I missed a built-in spline editor.
They were needed for different purposes:
for meshes and colliders, for markers (start/finish, time sections etc.),
for AI and agents and for testing physics. After looking into various tools in the asset store,
I decided to create one myself instead of using one.
Besides that the tool would be more customized and easier to use within C#,
another bonus would be to understand better how tools in Unity are build.

The Right Spline

The spline would be a list of multiple curves (segments) that share start and ending points.
For the curve type my decision felt on ,
because they are easy to implement and give great flexibility.
They are very similar to normal bezier curves but with one extension:
Every control point gets additionally a weight, allowing editing as if the points control their "gravity" (influence on the curve).

Two cubic rational bezier curves rendered with different weights:

The similarities to a normal bezier curve can be seen in the weights.
If all weights are

1

, it behaves like an bezier curve.
But if the weights are higher

, the curve morphs into an linear, sharp-corner style.
On the opposite lower

weights allow just a touch of influence.
Math: Cubic Rational Bezier

Points on a
This function can be used for multidimensional curves by calculating every dimension separately.

cubic rational bezier curve

can be computed like below.
The start point is on
t = 0

and the end on
t = 1

.
For a complete curve multiple points are connected.
float getPointOnCubicRationalBezier
(
// point on curve
float t,
// values
float p0, float p1, float p2, float p3,
// weights
float w0, float w1, float w2, float w3
)
{
var bp0 = (1-t)*(1-t)*(1-t)*w0;
var bp1 = 3*(1-t)*(1-t)*t*w1;
var bp2 = 3*(1-t)*t*t*w2;
var bp3 = t*t*t*w3;
var weighted =
(
p0 * bp0 +
p1 * bp1 +
p2 * bp2 +
p3 * bp3
);
var projection =
(
bp0 +
bp1 +
bp2 +
bp3
);
return weighted / projection;
}

First Spline

With the help of some tutorials I built my custom tool.
After editing my first spline it became clear that the points have a lot of parameters (two 3D tangents plus weights).
Since I also wanted to add a twist (up rotation around the curve), I searched a way to reduce the amount of parameters for faster editing.
To achieve this, I created an

point edit mode

for every point.
It allowed to switch between a FREE

and ALIGNED

mode.
Whereas FREE

allows tweaking of every detail, ALIGNED

mode automatically aligns the (opposite) tangents for smooth transitions of the segments.
Curvature

Another way to reduce the parameters is interpolating points to curves,
where curves are created by looking at their neighbor points.
After researching several models, I found the Kochanek-Bartels spline a very interesting approach.
From this spline type, the tension parameter was the inspiration
for adding a

(For completeness: It has more parameters, but they are used rather in edge cases: e.g. bias and overshoot prevention)

TRACK

mode - a point edit mode specialized on building splines for tracks.
TRACK

mode also calculates tangents automatically, but in relationship to its neighbor points.
Also a new parameter - named curvature

- replaces all tangent related parameters
and adjusts them all at once.
(For completeness: It has more parameters, but they are used rather in edge cases: e.g. bias and overshoot prevention)

Below two settings of the curvature, the first one with a low and the second one with a high value:

TRACK

mode reduces greatly the amount of parameters from 8 to 1 and allows quick top-to-bottom editing.
First the whole idea can be outlined and later the details can be tweaked.
Mesh generation

Now we can edit the spline nicely. But the spline alone doesn't create meshes.
For the mesh generation, several center points and their directions on one curve segment are computed.
From those we create 2 border points: one to the left and one to the right.
2 rows of border points result in quads building the whole track.

First image: One curve segment (dotted gray) with centers and directions(red), borders(yellow/pink) and the quads(solid gray).

Second image: A whole track build up by multiple segments.

Second image: A whole track build up by multiple segments.

Where's Up?

But one thing is missing now: the textures.
No information of the normal is present right now and you can't say whether a quad is front or back-facing.
Although you could just use both sides, you need it for various things - e.g. for gravity in physics.
To solve this, a

normal orientation

mode was added for every curve segment.
In can be either DIRECTION

mode, in which any point on the segment faces along a direction.
Or it can be POINT

mode, in which any point faces towards a point.
First: The problem of the possible normals.

Second: The two modes and the normal directions (red: direction, green: point, yellow: same on both):

Second: The two modes and the normal directions (red: direction, green: point, yellow: same on both):

Auto-Orientation

Although the ability to set the orientation freely is important,
I found it not helpful doing it for every segment.

Since the spline is used for creating tracks, a fair assumption are normals in the world up direction. I added it as

Then, another observation led to the 4th mode:

But since there is for all

Since the spline is used for creating tracks, a fair assumption are normals in the world up direction. I added it as

Y-SLOPE

mode and assigned it as default orientation

.
Basically, it is the DIRECTION

mode hard-wired to Y.
Then, another observation led to the 4th mode:

HULL-CENTER

.
This mode is similar to POINT

mode, but hard-wired to the center of the curve hull.
It makes sense whenever the normals face inside its own center (e.g. in loops).
But since there is for all

orientation

modes a use case to do the opposite, I added an FLIP

flag.
This allows to "invert" the intention and flip the normals (e.g. facing world down or facing against its center).
First: Visualization of the hull center. Second: FLIP flag on in POINT mode.

The Twist

Now everything is there to assign UVs to the (triangulated) quads including the normal information.
The twist parameter is then, after the orientation is clear straight forward.
It allows a rotation (of any point on the segment) after the orientation mode and can now be used for subtle or extreme twists.
With this (and the auto-orientation) approach the need of an second orientation spline or implicit up orientations indicators is eliminated.

First: Subtle twist, second: extreme twists

Hint: the see-through parts are the back-facing triangles.

Hint: the see-through parts are the back-facing triangles.

Summary

Creating custom tools in Unity is very useful.
The spline editing helps in various situations, that would be otherwise time-consuming.
The mesh generation works also well, and can be seamlessly built in the normal work-flow.
Unfortunately, I couldn't go into all the details, but maybe another time.
Send me feedback, if you are curious about one or another thing.

This site uses cookies. Read more.