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;
}
}