EGONE: Level Generator

When creating EGONE, my team had problems when it came to creating levels. The problem was that there was no Generator that laid out a Base Level for the designers to edit. All that we had was a base level that had everything required from a stock, empty level where designers dragged and dropped items into the scene. This worked but it was a slow and unpredictable way of creating and recreating levels. The perfect solution for this problem would have been a simple Random Level Generator.

What Does A Level Generator Do?

Basically, a level generator should create a level for your game with all the required objects populating it. This level should be playable from what the level generator creates but should be able to be edited by someone for better play ability.

My Test Level Generator

For my test generator, I started creating it how I would have gone about creating a level generator for EGONE.

First up I set up the main LevelGen script. This would be where the majority of work is done. This is also sort of the center of the code in a way. Everything goes through this script.

Since we will be making a generator of sorts, sometimes a level designer won’t like something that the generator pumps out so it would be a nice idea if it could be cleaned up easily. With this in mind, code was written to make sure that everything was created in the scene as a child of another empty game object. This Empty game object is destroyed at the start of the function and then the parent object is created then everything is then created on this parent so that when it is deleted, everything is deleted as well.

void SpawnLevel()
{
//Clear the previous Level
DestroyImmediate(parentOfLevel);
//Create new parent for the level to be created on
parentOfLevel = new GameObject();

After this we set up the starting point to the point of a game object in the scene (currently mine is set to the position of the game object my script is on). After this we set up our prevHeight float variable just before out while loop and assign the value to 0. We make sure to put it outside the while loop so this isn’t changing to 0 every time it loops otherwise things won’t work how we want it to. This prevHeight variable helps us get a better range of heights on our obstacles.

//set up the current possition at where ever startinglos's .position is
 Vector3 curPos = startingLoc.position;
 //To help with keeping track of where things need to go.
 float prevHeight = 0;

Now we start work on the ‘while’ loop. It starts with the while condition of the while loop. This basically says that if the objects have not filled the level yet than the while loop will continue to run and place objects into the scene.

while (curPos.x < levelLength - startingLoc.position.x)
 {

The while loop then creates a random height that receives the players input for the max .y value it can have. It then takes this random value and makes sure that it isn’t too much bigger or smaller than the last one to give your level a better flow. It does this by using the maxStepHeight variable as well. After the positioning is done, a random obstacle is grabbed from the obstacle array and placed into the scene with all the recent data.

 var randH = Random.Range(0, maxLevelHeight);
 randH = Mathf.Clamp(randH, prevHeight - maxStepHeight, prevHeight + maxStepHeight);
 GameObject newObsGO = Instantiate(obstaclePrefabs[Random.Range(0, obstaclePrefabs.Length)], curPos + Vector3.up * randH, Quaternion.identity);
 newObsGO.transform.parent = parentOfLevel.transform;

Next we bring in 2 functions from another script. This script will be on every obstacle in the scene. The Obstacle script. The first function is RandomizeYourSize. This function is set up to actual size of the obstacles based on information passed into it through it’s parameters. It also calculates how the obstacle needs to be re positioned based on their size so it is placed at ground level.

 public virtual void RandomiseYourSize(Vector3 max, LevelGen.Diff dif)
 {
 //this also needs to make sure it's height hits the ground.
 //given that the pivot is in the middle
 transform.localScale = Vector3.Lerp(defaultSize, max, Random.value);

 //calcutale how this object will size and reposition to look like its touching the groumd
 var top = transform.position.y + GetObstacleSize().y / 2;
 var curPos = transform.position;
 curPos.y = top / 2;
 transform.position = curPos;
 var curScale = transform.localScale;
 curScale.y = top;
 transform.localScale = curScale;

The second function is a lot smaller. The GetObstacleSize function. This just sets the default size of the obstacle (sets the scale).

 public virtual Vector3 GetObstacleSize()
 {
 var tmp = defaultSize;
 tmp.Scale(transform.localScale);
 return tmp;
 } 

Both of these functions are called by the LevelGen script when placing everything into the scene because their information is needed for it to properly function as intended.

The first one we will be getting is the RandomizeYourSize function. This will be used by calling it and feeding it’s parameters 2 pieces of information; the maxObsSize and the dif Diff. This then runs the function now taking into account our new data.

We then use the second functioned mentioned, the GetObstacleSize function. All this is used for increasing the curPos.x by the size of the object. The curPos variable is being used to keep track of how much level we have take up and how much we have remaining.

 Obstacle newObs = newObsGO.GetComponent<Obstacle>();
 newObs.RandomiseYourSize(maxObsSize, dif);
 curPos.x += newObs.GetObstacleSize().x;

The final step that is taken is to create a gap between each of the obstacles as they are being placed. Generates a random number and adds it to the curPos.x.

 stepSize = Random.Range(distBetweenObst.x, distBetweenObst.y);
curPos.x += stepSize;

And that will have a nice little generator for levels!

RandomGeneratedLevel

Unfortunately at the moment, this doesn’t include creating ramps but rather just makes different sized objects. It does have a lot of variables that can be manually changed by a designer if they w anted to change how the level generated.

DesignerVariablesList

In the future, I would like to turn these random objects into ramps by adding little bits to the code to help ramps calculate angles when they are generated. This would create a whole lot more edit ability for the designers to use when creating levels.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s