I’ve been working on a script that will instantiate a small portion of a much larger world. It should clean up an old row whenever it instantiates a new one but my script has been leaving behind a single tile near the edges and the center when I move in two directions. It seems to happen the worst when I travel South east and never happens when I travel north east. I can’t seem to find the cause of this, any assistance would be greatly appreciated.
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;
private int halfWorldSize;
//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;
//The players old position.
private float oldxPos;
private float oldzPos;
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;
oldxPos = player.transform.position.x;
oldzPos = player.transform.position.z;
halfWorldSize = Mathf.RoundToInt(worldSize/2);
worldGrid = GetComponent<LevelGenerator>().worldGrid;
worldTiles = new GameObject [worldSize + 1000 , worldSize + 1000]; //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 + xOffset x + xOffset > 0 worldGrid.GetLength(1) > z + zOffset z + zOffset > 0)
{
if(worldGrid[x + xOffset,z + zOffset] == 1)
{
worldTiles[x + xOffset - halfWorldSize,z + zOffset - halfWorldSize] = Instantiate(landTile, new Vector3((x + xOffset- (worldSize/2))*tilesize,landTile.transform.position.y, (z + zOffset- (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
}
else
if(worldGrid[x + xOffset,z + zOffset] == 0)
{
worldTiles[x + xOffset - halfWorldSize,z + zOffset - halfWorldSize] = Instantiate(cliffTile, new Vector3((x + xOffset- (worldSize/2))*tilesize, cliffTile.transform.position.y , (z + zOffset- (worldSize/2))*tilesize), cliffTile.transform.rotation) as GameObject;
}
}
}
}
}
void Update()
{
if(xOffset != oldxOffset || zOffset != oldzOffset)//The player has moved to a new tile.
{
//Check if we've moved north.
if( zOffset > oldzOffset)
{
for(int x = 1; x <= worldSize; x++)
{
//Check to make sure we're not instantiating outside of the worlds bounds.
if(worldGrid.GetLength(0) > x + xOffset - halfWorldSize x + xOffset - halfWorldSize >= 0 worldGrid.GetLength(1) > zOffset + halfWorldSize zOffset + halfWorldSize > 0)
{
if (worldGrid[x + xOffset - halfWorldSize,zOffset + halfWorldSize] == 1)
{
//Instantiate a grass tile.
worldTiles[x + xOffset - halfWorldSize, zOffset + halfWorldSize] = Instantiate(landTile, new Vector3((x + xOffset- (worldSize/2))*tilesize,landTile.transform.position.y, (zOffset + (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
}
else
if (worldGrid[x + xOffset - halfWorldSize , zOffset + halfWorldSize] == 0)
{
//Instantiate a cliff tile.
worldTiles[x + xOffset - halfWorldSize, zOffset + halfWorldSize] = Instantiate(cliffTile, new Vector3((x + xOffset- (worldSize/2))*tilesize,cliffTile.transform.position.y , (zOffset + (worldSize/2))*tilesize), cliffTile.transform.rotation) as GameObject;
}
}
if(worldGrid.GetLength(0) > x + xOffset - halfWorldSize x + xOffset - halfWorldSize >= 0 worldGrid.GetLength(1) > zOffset - halfWorldSize zOffset - halfWorldSize >= 0)
{
//Destroy the row of tiles we just moved away from.
Destroy (worldTiles[x + xOffset - halfWorldSize,zOffset - halfWorldSize]);
}
}
//Make sure it doesn't make the same tile more than once.
oldzOffset = zOffset;
}
//Check if we've moved south.
if( zOffset < oldzOffset)
{
for(int x = 1; x <= worldSize; x++)
{
//Check to make sure we're no instantiating outside of the worlds bounds.
if(worldGrid.GetLength(0) > x + xOffset - halfWorldSize x + xOffset - halfWorldSize > 0 worldGrid.GetLength(1) > zOffset - halfWorldSize zOffset - halfWorldSize > 0)
{
if (worldGrid[x + xOffset - halfWorldSize,zOffset - halfWorldSize] == 1)
{
//Instantiate a grass tile.
worldTiles[x + xOffset - halfWorldSize,zOffset - halfWorldSize] = Instantiate(landTile, new Vector3((x+xOffset - (worldSize/2))*tilesize,landTile.transform.position.y , (oldzOffset - (worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
}
else
if (worldGrid[x + xOffset - halfWorldSize, zOffset - halfWorldSize] == 0)
{
//Instantiate a cliff tile.
worldTiles[x + xOffset - halfWorldSize,zOffset - halfWorldSize] = Instantiate(cliffTile, new Vector3((x+xOffset - (worldSize/2))*tilesize, cliffTile.transform.position.y , (oldzOffset - (worldSize/2))*tilesize), cliffTile.transform.rotation) as GameObject;
}
}
if(worldGrid.GetLength(0) > x + xOffset - halfWorldSize x + xOffset - halfWorldSize >= 0 worldGrid.GetLength(1) > zOffset + 1 + halfWorldSize zOffset + 1 + halfWorldSize >= 0)
{
//Destroy the row of tiles we just moved away from.
Destroy (worldTiles[x + xOffset - halfWorldSize, oldzOffset + halfWorldSize]);
}
}
//Make sure it doesn't make the same tile more than once.
oldzOffset = zOffset;
}
//Check to see if we've moved east.
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 + halfWorldSize xOffset + halfWorldSize > 0 worldGrid.GetLength(1) > zOffset - halfWorldSize + x zOffset - halfWorldSize + x > 0)
{
if (worldGrid[xOffset+ halfWorldSize,x + zOffset - halfWorldSize] == 1)
{
//Instantiate a grass tile.
worldTiles[xOffset + halfWorldSize, x + zOffset - halfWorldSize] = Instantiate(landTile, new Vector3((xOffset + (worldSize/2))*tilesize,landTile.transform.position.y , (x + zOffset -(worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
}
else
if (worldGrid[xOffset + halfWorldSize,x + zOffset - halfWorldSize] == 0)
{
//Instantiate a wall.
worldTiles[xOffset + halfWorldSize, x + zOffset - halfWorldSize] = Instantiate(cliffTile, new Vector3((xOffset + (worldSize/2))*tilesize,cliffTile.transform.position.y , (x + zOffset -(worldSize/2))*tilesize), cliffTile.transform.rotation) as GameObject;
}
}
if(worldGrid.GetLength(0) > xOffset - halfWorldSize xOffset - halfWorldSize >= 0 worldGrid.GetLength(1) > x + zOffset - halfWorldSize x + zOffset - halfWorldSize >= 0)
{
//Destroy the row of tiles we just moved away from.
Destroy (worldTiles[xOffset - halfWorldSize, x + zOffset - halfWorldSize] );
}
}
//Make sure it doesn't make the same tile more than once.
oldxOffset = xOffset;
}
//Check if we've moved west
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 - halfWorldSize xOffset - halfWorldSize > 0 worldGrid.GetLength(1) > x + zOffset - halfWorldSize x + zOffset - halfWorldSize > 0)
{
if (worldGrid[xOffset - halfWorldSize ,x + zOffset - halfWorldSize] == 1)
{
//Insantiate a grass tile;
worldTiles[xOffset - halfWorldSize, x + zOffset - halfWorldSize] = Instantiate(landTile, new Vector3((oldxOffset - (worldSize/2))*tilesize,0, (x + zOffset -(worldSize/2))*tilesize), landTile.transform.rotation) as GameObject;
}
else
if (worldGrid[xOffset - halfWorldSize,x + zOffset - halfWorldSize] == 0)
{
//Instantiate a wall.
worldTiles[xOffset - halfWorldSize, x + zOffset - halfWorldSize] = Instantiate(cliffTile, new Vector3((oldxOffset - (worldSize/2))*tilesize,cliffTile.transform.position.y , (x + zOffset -(worldSize/2))*tilesize), cliffTile.transform.rotation) as GameObject;
}
}
if(worldGrid.GetLength(0) > xOffset + halfWorldSize xOffset + halfWorldSize >= 0 worldGrid.GetLength(1) > zOffset - halfWorldSize + x zOffset - halfWorldSize + x >= 0)
{
//Destroy the row of tiles we just moved away from.
Destroy (worldTiles[oldxOffset + halfWorldSize, x + zOffset - halfWorldSize]);
}
}
//Make sure it doesn't make the same tile more than once.
oldxOffset = xOffset;
}
}
//See if we've moved more than a tilesize in any direction, if so update the offsets.
if(player.transform.position.x > (oldxPos + tilesize))
{
oldxPos = player.transform.position.x;
xOffset++;
}
if(player.transform.position.x < (oldxPos - tilesize))
{
oldxPos = player.transform.position.x;
xOffset--;
}
if(player.transform.position.z > (oldzPos + tilesize))
{
oldzPos = player.transform.position.z;
zOffset++;
}
if(player.transform.position.z < (oldzPos - tilesize))
{
oldzPos = player.transform.position.z;
zOffset--;
}
}
}
Edit: Added in an image to make it easier to understand what it’s leaving behind.