Instantiating a world from memory

I’m currently working on a C# script to instantiate the land immediately around the player. I’m having a couple of problems with it.

The first problem is relatively minor. When the player moves in two of the 4 cardinal directions, when the player moves from the first tile to the second tile xOffset and zOffset don’t detect a change causing no new tiles to be created leaving a gap. After that tiles instantiate fine.

xOffset = (Mathf.RoundToInt(player.transform.position.x/10));
zOffset = (Mathf.RoundToInt(player.transform.position.z/10));

The second issue isn’t with the code itself. I need a way to shift the entire worldTiles array in each of the 4 cardinal directions and destroy the furthest row. I haven’t come up with a way to do this yet, without it my world will quickly get polluted with duplicate tiles.
I believe the third problem I’ve found is related to my checks on whether or not a tile is inside of the boundaries. When I approach the edge of the world it stops instantiating tiles entirely, it should simply skip tiles that are outside of the worlds boundaries until the for loop runs out.
Finally my script is messy, any tips on cleaning it up and making it easier for myself and others to understand would be greatly appreciated. I would greatly appreciate it if you could point me in the right direction on any of these. Thanks for your time!

The complete script.

using UnityEngine;
using System.Collections;

/// <summary>
/// Instantiate world. 
/// Instantiate world builds the world immediately around the player and keeps it updated.
/// 
/// Accesses LevelGenerator for worldGrid; 
/// </summary>

public class InstantiateWorld : MonoBehaviour 
{	
	//Variables
	
		//The size of the world we want to be instantiated;
		public int worldSize;  
		
	
		//How many tiles off from the center we are.
		private int xOffset;
		private int zOffset;
		
		//The offsets from the last frame. We use this to see if we've moved enough to warrant a new row.
		private int oldxOffset;
		private int oldzOffset;
		
		public GameObject player;  //We'll need to grab the players position to determine where to instantiate the tiles. 
	
		public GameObject landTile; //The object we want to instantiate as the ground.
		public GameObject cliffTile; //The object we want to use for raised ground.
	
		private int tilesize = 10; //The size of the tiles.
	
		public int[,] worldGrid; //The randomly generated world. 
		public GameObject[,] worldTiles; //A list of game objects containing the instantiated world.
		
	
	// Use this for initialization
	

	
	// Update is called once per frame
	void Start () 
	{
		//Figure out which tile the player is on.
		xOffset = (Mathf.RoundToInt(player.transform.position.x/10));
		zOffset = (Mathf.RoundToInt(player.transform.position.z/10));
		oldxOffset = xOffset;
		oldzOffset = zOffset;
		
		
		
		worldGrid = GetComponent<LevelGenerator>().worldGrid;
		worldTiles = new GameObject [worldSize + 100 , worldSize + 100];   //Set the array to be filled with the instantiated tiles.
		
		//Instantiate the world
		for(int x = 1; x <= worldSize; x++)
		{
			for(int z = 1; z <= worldSize; z++)
			{
				if(worldGrid.GetLength(0) >= x  x >= 0  worldGrid.GetLength(1) >= z  z >= 0)
				{
					if(worldGrid[x + xOffset,z + zOffset] == 1)
					{
						worldTiles[x,z] = Instantiate(landTile, new Vector3((x + xOffset- (worldSize/2))*tilesize,0,  (z + zOffset- (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
					}
					else
					if(worldGrid[x + xOffset,z + zOffset] == 0)
					{
						worldTiles[x,z] = Instantiate(cliffTile, new Vector3((x + xOffset- (worldSize/2))*tilesize, 0, (z + zOffset- (worldSize/2))*tilesize), cliffTile.transform.rotation) as GameObject;
					}
				}
			} 
		} 
	}
	
	void Update()
	{
		//Check the length of world tiles to make sure it's not 
		print("[" + worldTiles.GetLength(0) + "," + worldTiles.GetLength(1) + "]");
		
		//Figure out which tile the player is on.
		xOffset = (Mathf.FloorToInt(player.transform.position.x/10));
		zOffset = (Mathf.FloorToInt(player.transform.position.z/10));
		
		if(xOffset != oldxOffset || zOffset != oldzOffset)//The player has moved to a new tile.
		{
			//Check to see if we've moved north.
			if(xOffset > oldxOffset)
			{
				
				for(int x = 1; x <= worldSize; x++)
				{
					//Check to make sure we're not instantiating outside of the worlds bounds.
					if(worldGrid.GetLength(0) >  xOffset  xOffset > 0  worldGrid.GetLength(1) > zOffset + x  zOffset + x > 0)
					{
						if (worldGrid[xOffset,x + zOffset] == 1)
						{
							//Instantiate a grass tile.
							worldTiles[xOffset, x + zOffset] = Instantiate(landTile, new Vector3((xOffset + (worldSize/2))*tilesize,0,  (x + zOffset -(worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
						else
						if (worldGrid[xOffset,x + zOffset] == 0)
						{
							//Instantiate a wall.
							worldTiles[xOffset, x + zOffset ] = Instantiate(cliffTile, new Vector3((xOffset + (worldSize/2))*tilesize,0,  (x + zOffset -(worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
					}
				}
			}
			else
			if(xOffset < oldxOffset) //Check if we've moved west
			{
				for(int x = 1; x <= worldSize; x++)
				{
					//Check to make sure we're not instantiating outside of the worlds bounds.
					if(worldGrid.GetLength(0) > xOffset  xOffset > 0  worldGrid.GetLength(1) > x + zOffset  x + zOffset > 0)
					{
						if (worldGrid[xOffset ,x + zOffset ] == 1)
						{
							//Insantiate a grass tile;
							worldTiles[xOffset, x + zOffset ] = Instantiate(landTile, new Vector3((xOffset - (worldSize/2))*tilesize,0,  (x + zOffset -(worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
						else
						if (worldGrid[xOffset,x + zOffset ] == 0)
						{
							//Instantiate a wall.
							worldTiles[xOffset , x + zOffset] = Instantiate(cliffTile, new Vector3((xOffset - (worldSize/2))*tilesize,0,  (x + zOffset -(worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;

						}
					}
				}
			}
			//Check if we've moved east.
			if( zOffset > oldzOffset)
			{
				for(int z = 1; z <= worldSize; z++)
				{
					//Check to make sure we're not instantiating outside of the worlds bounds.
					if(worldGrid.GetLength(0) > z + xOffset  z + xOffset > 0  worldGrid.GetLength(1) > zOffset  zOffset > 0)
					{
						if (worldGrid[z+xOffset,zOffset]  == 1)
						{
							//Instantiate a grass tile.
							worldTiles[z+xOffset, zOffset] = Instantiate(landTile, new Vector3((z+xOffset- (worldSize/2))*tilesize,0,  (zOffset + (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
						else
						if (worldGrid[xOffset ,z + zOffset ] == 0)
						{
							//Instantiate a cliff tile.
							worldTiles[z+xOffset, zOffset] = Instantiate(cliffTile, new Vector3((z+xOffset- (worldSize/2))*tilesize,0,  (zOffset + (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
					}
				}
			}
			else
			if( zOffset < oldzOffset) //Check if we've moved south.
			{	
				for(int z = 1; z <= worldSize; z++)
				{
					//Check to make sure we're no instantiating outside of the worlds bounds.
					if(worldGrid.GetLength(0) > z + xOffset  z + xOffset > 0  worldGrid.GetLength(1) > zOffset  zOffset > 0)
					{
						if (worldGrid[z + xOffset,zOffset ]  == 1)
						{
							//Instantiate a grass tile.
							worldTiles[z+xOffset,zOffset ] = Instantiate(landTile, new Vector3((z+xOffset- (worldSize/2))*tilesize,0,  (zOffset - (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
						else
						if (worldGrid[xOffset ,z + zOffset ] == 0)
						{
							//Instantiate a cliff tile.
							worldTiles[z+xOffset,zOffset ] = Instantiate(cliffTile, new Vector3((z+xOffset- (worldSize/2))*tilesize,0,  (zOffset - (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
						}
					}
				}
			}
		}
		
		//Set the old offsets to the new offsets so we can check them again.
		oldxOffset = xOffset;
		oldzOffset = zOffset;
	}
}

I don’t suppose it’ll actually help here but I thought I’d post my world generator quickly just in case someone down the line wanted to toy with it. It’s really simple, all it does is fill an array with 1’s to represent the floor outlining the edges in 0’s to represent the walls. The code above steals the generated array from this script.

using UnityEngine;
using System.Collections;

/// <summary>
/// Generates the world and places it in worldGrid.
/// 
/// 
/// 0 is a cliff
/// 1 is grass
/// 
/// </summary>
/// 
public class LevelGenerator : MonoBehaviour 
{
	//Variables
	
		//The tile size of the world.
		public int worldWidth;  //X axis
		public int worldLength; //Z axis
	
		public GameObject landTile; //The object we want to instantiate as the ground.
		public GameObject cliffTile; //The object we want to use for raised ground.
	
		//The world being stored. Should give me each tile type.
		public int[,] worldGrid;
		
	
	
	// Use this for initialization
	void Start () 
	{
		worldGrid = new int [worldWidth + 1 ,worldLength + 1]; 
		
		//Run along the grid marking everything as ground.
		for(int x = 1; x <= worldWidth; x++)
		{
			for(int z = 1; z <= worldLength; z++)
			{
				//If it's the first or last in it's row make it a cliff to lock the player inside.
				if(x != 1  x != worldWidth  z != 1  z != worldLength)
				{
					worldGrid[x,z] = 1;
				}
				else
				{
					worldGrid[x,z] = 0;
				}
			}
		}
	}
}