Framing the Level

At GDC we noticed the game was visually lagging when you moved across the screen so, this week's task was to fix that issue.  We were looking to reduce the number of models in our scenes and create a better design for the foreground.  Originally, I had the Unpack Level script instantiate floor cubes below each of the lowest floor pieces until they reached out of sight of the camera. This resulted in a lot of models being created at run time which unnecessarily slows down our game during play mode. So I wrote a program that would find the positions of the lowest floors and create a texture(s) below all of them.  You can see the result in the picture below.

To start with this script, I wanted needed it to know what floor was the lowest in each column.  So I wrote a simple series of for loops that take the DataLocations from Unpack Level and populate an array.

//Go through each column(mLevelSize.x) and findthe lowest place a 17(Floor) appears
//The values fill horizontally so for a level 10 long you need to check data point 0, 10, 20 ,30 ,40...
void FindLowestFloors(List<int> mDataLocations){

int currentLowestFloorDataPoint = 0;
for(int i = 0; i < CameraMovement.mLevelSize.x/2; i++){
for(int j = 0; j < mDataLocations.Count; j = j + (int)CameraMovement.mLevelSize.x/2){

if(mDataLocations[i + j] == 17){
currentLowestFloorDataPoint = i + j;
}
}
mLowestFloors[i] = ConvertToPosition((currentLowestFloorDataPoint));
}
}

Once I had the list of lowest floors, I searched through each one to check if they were higher or lower or at the same height as the current floor.  Once I found a floor that was higher or lower, I would stop the search and run my function CreateFloorTile.  This function, shown below, creates a Plane in Unity, changes the Scale and Position so the texture will cover all of the area underneath the floors, then adds a new material.  All of this is not done in just one function, that would be horribly hard to read.

void CreateFloorTile(Vector3 startPosition, Vector3 endPosition){

GameObject newTile = CreatePlaneObject();

newTile.transform.localPosition = SetTilePosition(startPosition, endPosition);

newTile.transform.localScale = SetTileScale(startPosition, endPosition);

Vector2 textureScale = new Vector2(1,1);
textureScale.x = newTile.transform.localScale.x;
textureScale.y = newTile.transform.localScale.z;

SetupShaderAndMaterial(newTile.renderer.material, textureScale);

this.gameObject.GetComponent<BuildWall>().NewWallLocation(newTile.transform);
}

Unity does something dumb (and so do I)

Once I had all of this working, I had textures spawning in the correct place under each of my floor sections. The textures were also scaling to the lengths of the tile and they all looked sorta good.  The problem was, the tiles were not lining up. So after playing around in scene view I wrote down where all of the textures needed to be based on their scale and offset.  I knew the offset moved the texture to the right.  So I tried to use math to find the equation that would allow me to determine what the offset should be so all of the textures looks like one seamless texture.  After 2ish hours or working on it and a day or two to let it stir in my brain at work, I thought, " What if my assumption that the scale will fill by adding the new parts on the right and is fixed on the left, was wrong?"  So I made a test texture, which you can see below, to test this theory.

It turns out, even though the offset moves the texture to the right, the scale will fill in new section on the left.  I definitely need to watch my assumptions from now on because that cost me  a fair amount of time, but in my opinion, Unity's texture system is not intuitive and that was frustrating.  With that new knowledge, I was easily able to create a system that tracked the previous tile's offset and allowed me to line all of the textures up again so they for one beautiful connected texture.


I applied these same techniques to create the three panels that surround the scene that you saw in the first picture of this post.  Most of the time was spent creating readable code and doing tweaks that would make sure the textures on the side and top panel would line up nicely with the previously created floor.