Tuesday, April 22, 2014

Unity In Game Level Editor for VXT

I decided to create a level editor for my Senior Production game VXT. VXT is a side scrolling 2.5D racer where players compete to finish levels with the fastest time by using a polarity shield to attach or repel to objects a navigate the world. Example video shown below.

Because this game is based off of very short 1 - 2 minute experiences I figured how else to encourage players to really compete against one another the hand the very tools of world creation to them and let them go to work and see if their friends can beat their creations. As one of the creators of VXT I tried to make interesting and action packed levels but as I can see from other games with player level creator tool, there are some really talented people out there that will put in the time to make some really amazing levels.

So I with all of this in mind I set out to accomplish the follow goals:

1. Create a in game level editor to allow player to use a Gamepad to build a world.

2. Make a dynamic menu system to allow world pieces to be easily categorized for streamlined building

3. Allow the ability to save local and test the levels in game at the touch of a button.

4. Give players the ability to push their levels to our server.

5. Make it so other players can pull down levels from out server and play them locally.

6. Save high scores and "Ghost" characters for all custom levels to enhance competitive play.

Creating a level editor in itself is the easy part, making it usable is the challenge especially when the player is working on a game pad, even things like navigating menus becomes a challenge without access to a mouse and keyboard.

Since our world is basically created in a 2D space, it made this whole navigation to build thing a little easier. I put the player on rails setting them on a specific axis a set amount back and limiting the player to only be able to move up down left and right using basic translation. This way the world and the player is always lined up at least in the Z axis. The pieces for manipulation are set much further back but since the player can't move in the Z axis the pieces are spawns a set distance away and will always be on the correct Z axis. About halfway between the player and the pieces spawn location I added a transparent plane as sort of a aiming sight so the player can more easily line up pieces. More so on the movement set I added in the ability to drastically reduce the speed in which the player moves the builder, upon holding down the left shoulder button the player moves at 1/8th speed. This allows the player to quickly move from section of his or her creation to another section, but then give precises precision when placing the pieces.

Next logical step would be to worry about how we actually spawn the objects we want to build with, but in my case this goes hand in hand with our dynamic menu system. In VXT we have many different types of objects we have ramps, pipes, walls, blocks, and any of our intractable objects such as speed bad and colored walls. As such I wanted to created at nested menu system to allow players to know exactly where each piece is located. Unity has a resources folder inside that folder I created a bunch of prefabs that the player will use to build the world. These prefabs are named and prefixed with a tag of what they actually are So for example Pipe_Half Pipe. The pipe prefix causes the pipe object to be placed in a sub grid. To create these grids I used Unity's GUI_SelectionGrid. The grid takes in the parameters height and width of the buttons, the number of rows and columns for the grid, the current selected item and an array of the names of the items in grid. These work out so well for my implementation, the selected variable allows me to use the grid with the xbox controller, I increment the variable based on the direction of the left joy stick, I also add in a delay timer so that it I only move up or down 1 ever so often. Even better when the player selects an object I can use the display name to directly look up the object they want from the resource folder and instantiate it.

Once it is instantiated I place it on the spawn point and it is now attached to the builders movement. Upon hitting A the builder will let go of the object and set it in place. This is where a lot of design and quality of life decision come into play. In order to make this world truly customizable I granted the player the ability to scale and rotate the objects they are holding. If they hold the left trigger they can change the scale of the object with the right joystick, the X scale left and right, and the Y scale with up and down. We simply change the Euler angles directly in the object. The rotation is similar, If the player hold the right trigger the right stick changes the rotation in the same way as scale. More importantly I needed to add a slow effect to it much like the movement. If they player holds the left bumper it slows down the rate of change that way the player can scale and rotate things perfectly. These are the basic building blocks of the level editor with everything I mentioned above they are able to fully create a world to play in, next comes the real challenges, testing these world, and sharing them.

Testing the world quickly is actually quite an easy task, when the player selects save from the start menu (being implemented the same way as the menu system) I save out all relative data to the world, so item names, their position, rotation, scale, and any special properties if they have them to a xml file. I also prompt the user for a name of the level which I then name the xml file accordingly. I then remove the builder object add in the player. At this point the level is fully playable. Once the player reaches the end of the level or quits, I remove the player object add in the builder and then they are ready to continue creation. It's quick easy and allows for fast iteration and testing of sections.

With the level file already saved out in an XML format sharing the level is easy as pie. When the player saves and uploads the object. I make a call out to our php server, in there I have a script to add files onto our server, I call the script and hand it the xml file. The server takes the file and prefixes it with the players username from the game, this allows people to name their levels whatever they want and not worry about them being overwritten as the account name keeps them unique.

Once they are up there having a someone else pull them down and play them is super easy. I have another php script that will pull down all levels on our server. I make an empty scene that the player can view the list of player made levels in. I pull down the names of all the levels and display them in a selection grid. When the player selects one, I use another php script to get the xml file from our server based on the name. I download the file and then build out the level line by line add in a player and just like that they get the ability to play the level. Furthermore a ghost file is brought down as well which shows the exact movements of whatever person has the best time on a given level, so you can directly compete with your friends play.

All six of my goals were completed and it was quite an interesting experiences that I feel good about taking the time to complete.