Vertigun

About the game

Vertigun is a game I worked on during my internship at Excamedia. It is a mixture of 3D shoot 'em up and F-Zero style gameplay. The player controls a gunship racing on a cylindrical track at high speeds. The game was developed as a demo for the AntVR virtual reality headset. The objective of the game was to shoot as many targets as possible within the time limit.

Bezier Splines

I'll be honest, I wasn't exactly thrilled to be working on this game. When I was assigned to the project I found it to be a messy pile of assets with no clear structure. However, the reason I want to show it here is because I did enjoy working on one problem in particular. At the onset, the tracks used by the player to navigate through the levels consisted of a 3D model with about 300 triggers per track (2700 triggers in the entire level). These triggers were used to move the player from one trigger to the next, to make it appear as if the player was moving over the tracks. I had several problems with this solution. Firstly, it was buggy, as the player would sometimes get stuck on a trigger and not move on the the next. Second, it would occasionally cause the player to clip through the tracks due to the way these triggers were positioned on the track. Lastly, it was incredibly resource intensive in the Unity editor, slowing my Unity down to single digit FPS whenever I had a single track selected. With permission, I decided to spend my time on a new implementation that would hopefully solve these problems, effectively using it as my research subject for that internship.

I started off looking into raycasting. I'd hoped that by casting a ray down from the ship would allow me to detect whether or not the ship was correctly positioned on the track and make adjustments where needed. This turned out to be a bit too fiddly, so I looked for something else. During a networklunch at the Dutch Game Garden in Utrecht, Joost van Dongen (developer of Proun) was kind enough to give me some pointers in the right direction. I looked up bezier splines and found a useful tutorial explaining how to create and use them in Unity.

Mesh Generation

Not long after finding the tutorial about splines, I had a working prototype of the new track movement system. However, I still had to find a way to either link these splines to the existing tracks, or to somehow generate a track mesh from the spline. I decided to look up how to procedurally generate a mesh, using this tutorial. By looping through the points in the spline and generating vector3 positions in a circle around the spline's point, I can create the vertices of the mesh.


for (int step = 0; step <= spline.GetSmoothness(); step++)
{
    float t = step / (float)spline.GetSmoothness();
    Vector3 point = spline.GetPoint(t);
    Vector3 dir = spline.GetVelocity(t);
    CreateVertices(point - transform.position, Quaternion.LookRotation(dir, dir), t, step > 0);
} ... private void CreateVertices(Vector3 point, Quaternion rotation, float v, bool buildTriangles)
{
    for (int i = 0; i <= segmentCount; i++)
    {
        float a = (i * 1.0f) / segmentCount;
        float angle = a * Mathf.PI * 2;

        Vector3 vertexPos = Vector3.zero;
        vertexPos.x = Mathf.Cos(angle) * radius;
        vertexPos.y = Mathf.Sin(angle) * radius;

        vertexPos = rotation * vertexPos;
        meshBuilder.GetNormals().Add(vertexPos);

        vertexPos += point;
        meshBuilder.GetVertices().Add(vertexPos);

        float u = (float)i / segmentCount;
        meshBuilder.GetUVs().Add(new Vector2(u, v));

        if (i > 0 && buildTriangles)
        {
            int baseIndex = meshBuilder.GetVertices().Count - 1;
            int vertsPerRow = segmentCount + 1;

            int index0 = baseIndex;
            int index1 = baseIndex - 1;
            int index2 = baseIndex - vertsPerRow;
            int index3 = baseIndex - vertsPerRow - 1;

            meshBuilder.AddTriangle(index1, index2, index0);
            meshBuilder.AddTriangle(index1, index3, index2);
        }
    }
}