I am making a voxel world that generates an unlimited world but my problem is that I am getting a null reference on returning the type of Block. I started getting this error after i started turning the gameobjects.setActive(false). I dont know how to get the return that i need.
WorldScript:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class WorldScript : MonoBehaviour
{
public int[,,] data;
public List<BlockData> blocks;
[System.Serializable]
public class BlockData
{
public string name;
public Vector2 texture;
}
public int chunksAcross = 4;
public int chunksUp = 1;
private int worldX=16;
private int worldY=16;
private int worldZ=16;
public GameObject chunk;
public GameObject[,,] chunks;
public int chunkSize=16;
public float texturesAcross = 4;
public float textureUnit;
// GUI Variables
private float smoothGrass;
private float smoothStone;
private float grassHeightScale;
private float stoneHeightScale;
private float grassExponent;
private float stoneExponent;
private float grassAddition;
private float stoneAddition;
private float waterHeight;
public GameObject player;
public int renderDistance = 50;
void Start ()
{
textureUnit = 1/texturesAcross;
worldX = chunksAcross * chunkSize;
worldY = chunksUp * chunkSize;
worldZ = chunksAcross * chunkSize;
player.transform.position = new Vector3 (chunkSize*chunksAcross/2, 300, chunkSize*chunksAcross/2);
CreateChunks ();
}
void Update ()
{
DistanceToChunk ();
}
void OnGUI ()
{
GUI.Window(0, new Rect(10, 10, 200, 500), OptionsWindow, "Options");
}
void OptionsWindow (int id)
{
GUI.Label(new Rect(10, 30, 1000, 1000), "Grass_Smooth:");
smoothGrass = GUI.HorizontalSlider(new Rect(10, 50, 100, 20), smoothGrass, 1, 100);
GUI.Label(new Rect(10, 70, 1000, 1000), "Grass_HeightScale:");
grassHeightScale = GUI.HorizontalSlider(new Rect(10, 90, 100, 20), grassHeightScale, 1, 100);
GUI.Label(new Rect(10, 110, 1000, 1000), "Grass_Exponent:");
grassExponent = GUI.HorizontalSlider(new Rect(10, 130, 100, 20), grassExponent, 1, 2);
GUI.Label(new Rect(10, 150, 1000, 1000), "Stone_Smooth:");
smoothStone = GUI.HorizontalSlider(new Rect(10, 170, 100, 20), smoothStone, 1, 100);
GUI.Label(new Rect(10, 190, 1000, 1000), "Stone_HeightScale:");
stoneHeightScale = GUI.HorizontalSlider(new Rect(10, 210, 100, 20), stoneHeightScale, 1, 100);
GUI.Label(new Rect(10, 230, 1000, 1000), "Stone_Exponent:");
stoneExponent = GUI.HorizontalSlider(new Rect(10, 250, 100, 20), stoneExponent, 1, 2);
GUI.Label(new Rect(10, 270, 1000, 1000), "Grass_Addition:");
grassAddition = GUI.HorizontalSlider(new Rect(10, 290, 100, 20), grassAddition, 1, 100);
GUI.Label(new Rect(10, 310, 1000, 1000), "Stone_Addition:");
stoneAddition = GUI.HorizontalSlider(new Rect(10, 330, 100, 20), stoneAddition, 1, 100);
GUI.Label(new Rect(10, 350, 1000, 1000), "Water_Height:");
waterHeight = GUI.HorizontalSlider(new Rect(10, 370, 100, 20), waterHeight, 1, 100);
if (GUI.Button(new Rect(20, 400, 160, 80), "Generate Terrain"))
{
GenerateTerrain ();
}
}
void DistanceToChunk ()
{
float distance;
for (int x=0; x<chunks.GetLength(0); x++)
{
for (int z=0; z<chunks.GetLength(2); z++)
{
for (int y=0; y<chunks.GetLength(1); y++)
{
distance = Vector3.Distance(chunks[x, y, z].transform.position,player.transform.position);
if (distance <= renderDistance)
{
if (!chunks[x, y, z].GetComponent<ChunkScript>().isRendered)
{
chunks[x, y, z].SetActive(true);
chunks[x, y, z].GetComponent<ChunkScript>().GenerateMesh();
}
}else{
if (chunks[x, y, z].GetComponent<ChunkScript>().isRendered)
{
chunks[x, y, z].GetComponent<ChunkScript>().ClearMesh();
chunks[x, y, z].SetActive(false);
}
}
}
}
}
}
void GenerateTerrain () // ***** WHERE TO ALTER TERRAIN ***** \\
{ // Noise(x,z, smoothness, height, exponent);
data = new int[worldX,worldY,worldZ];
for (int x=0; x<worldX; x++)
{
for (int z=0; z<worldZ; z++)
{
int dirt = Noise(x,z, smoothStone,stoneHeightScale,stoneExponent);
dirt += Mathf.RoundToInt(stoneAddition);
int grass = Noise(x,z, smoothGrass,grassHeightScale,grassExponent);
grass += Mathf.RoundToInt(grassAddition);
for (int y=0; y<worldY; y++)
{
if (y == grass)
{
data[x, y, z] = 1;
}
if(y < grass)
{
data[x, y, z] = 2;
}
if(y < dirt)
{
data[x, y, z] = 3;
}
}
}
}
SpecialGeneration ();
}
void SpecialGeneration ()
{
for (int x=0; x<worldX; x++)
{
for (int z=0; z<worldZ; z++)
{
for (int y=0; y<worldY; y++)
{
// Create Water
if (Block(x, y, z) == 0)
{
if (y < waterHeight)
{
data[x, y, z] = 5;
}
}
// Create Sand
if (Block (x, y, z) == 1)
{
if (y < waterHeight)
{
data[x, y, z] = 4;
}
}
}
}
}
}
int Noise (int x, int z, float scale, float mag, float exp)
{
return (int) (Mathf.Pow ((Mathf.PerlinNoise(x/scale,z/scale)*mag),(exp) ));
}
void CreateChunks ()
{
chunks=new GameObject[Mathf.FloorToInt(worldX/chunkSize),
Mathf.FloorToInt(worldY/chunkSize),
Mathf.FloorToInt(worldZ/chunkSize)];
for (int x=0; x<chunks.GetLength(0); x++)
{
for (int y=0; y<chunks.GetLength(1); y++)
{
for (int z=0; z<chunks.GetLength(2); z++)
{
chunks[x,y,z] = Instantiate(chunk,new Vector3(x*chunkSize,y*chunkSize,z*chunkSize),new Quaternion(0,0,0,0)) as GameObject;
chunks[x,y,z].transform.parent = transform;
ChunkScript newChunkScript= chunks[x,y,z].GetComponent<ChunkScript>();
newChunkScript.worldGO=gameObject;
newChunkScript.chunkSize=chunkSize;
newChunkScript.chunkX=x*chunkSize;
newChunkScript.chunkY=y*chunkSize;
newChunkScript.chunkZ=z*chunkSize;
chunks[x, y, z].SetActive(false);
}
}
}
}
public int Block(int x, int y, int z)
{
if( x>=worldX || x<0 || y>=worldY || y<0 || z>=worldZ || z<0){
return (int) 1;
}
return data[x,y,z];
}
}
Then my ChunkScript is:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ChunkScript : MonoBehaviour
{
private List<Vector3> newVertices = new List<Vector3>();
private List<int> newTriangles = new List<int>();
private List<Vector2> newUV = new List<Vector2>();
private Mesh mesh;
private MeshCollider col;
private int faceCount;
public float textureUnit;
public float texturesAcross = 4;
public GameObject worldGO;
private WorldScript world;
public int chunkSize=16;
public int chunkX;
public int chunkY;
public int chunkZ;
public bool isRendered = false;
void Start ()
{
worldGO = GameObject.Find("_World");
world = worldGO.GetComponent<WorldScript>();
chunkSize = world.chunkSize;
mesh = GetComponent<MeshFilter> ().mesh;
col = GetComponent<MeshCollider> ();
textureUnit = world.textureUnit;
}
public void ClearMesh()
{
isRendered = false;
newVertices.Clear();
newTriangles.Clear ();
newUV.Clear();
mesh.Clear();
}
public void GenerateMesh()
{
isRendered = true;
newVertices.Clear();
newTriangles.Clear ();
newUV.Clear();
for (int x=0; x<chunkSize; x++)
{
for (int y=0; y<chunkSize; y++)
{
for (int z=0; z<chunkSize; z++)
{
if(Block(x,y,z)!=0)
{
if(Block(x,y+1,z) == 0)
{
CubeTop(x,y,z,Block(x,y,z));
}
if(Block(x,y-1,z) == 0)
{
CubeBottom(x,y,z,Block(x,y,z));
}
if(Block(x+1,y,z) == 0)
{
CubeEast(x,y,z,Block(x,y,z));
}
if(Block(x-1,y,z)==0)
{
CubeWest(x,y,z,Block(x,y,z));
}
if(Block(x,y,z+1)==0)
{
CubeNorth(x,y,z,Block(x,y,z));
}
if(Block(x,y,z-1)==0)
{
CubeSouth(x,y,z,Block(x,y,z));
}
}
}
}
}
UpdateMesh ();
}
int Block(int x, int y, int z)
{
return world.Block(x+chunkX,y+chunkY,z+chunkZ);
}
void UpdateMesh ()
{
mesh.Clear();
mesh.vertices = newVertices.ToArray();
mesh.uv = newUV.ToArray();
mesh.triangles = newTriangles.ToArray();
mesh.Optimize();
mesh.RecalculateNormals();
col.sharedMesh = null;
col.sharedMesh = mesh;
faceCount = 0;
}
void CubeTop (int x, int y, int z, int blockType)
{
newVertices.Add(new Vector3(x, y, z+1));
newVertices.Add(new Vector3(x+1, y, z+1));
newVertices.Add(new Vector3(x+1, y, z));
newVertices.Add(new Vector3(x, y, z));
Vector2 texturePos = world.blocks[blockType].texture;
TextureCube (texturePos);
}
void CubeBottom (int x, int y, int z, int blockType)
{
newVertices.Add(new Vector3(x, y-1, z));
newVertices.Add(new Vector3(x+1, y-1, z));
newVertices.Add(new Vector3(x+1, y-1, z+1));
newVertices.Add(new Vector3(x, y-1, z+1));
Vector2 texturePos = world.blocks[blockType].texture;
TextureCube (texturePos);
}
void CubeNorth (int x, int y, int z, int blockType)
{
newVertices.Add(new Vector3(x+1, y-1, z+1));
newVertices.Add(new Vector3(x+1, y, z+1));
newVertices.Add(new Vector3(x, y, z+1));
newVertices.Add(new Vector3(x, y-1, z+1));
Vector2 texturePos = world.blocks[blockType].texture;
TextureCube (texturePos);
}
void CubeSouth (int x, int y, int z, int blockType)
{
newVertices.Add(new Vector3(x, y-1, z));
newVertices.Add(new Vector3(x, y, z));
newVertices.Add(new Vector3(x+1, y, z));
newVertices.Add(new Vector3(x+1, y-1, z));
Vector2 texturePos = world.blocks[blockType].texture;
TextureCube (texturePos);
}
void CubeEast (int x, int y, int z, int blockType)
{
newVertices.Add(new Vector3(x+1, y-1, z));
newVertices.Add(new Vector3(x+1, y, z));
newVertices.Add(new Vector3(x+1, y, z+1));
newVertices.Add(new Vector3(x+1, y-1, z+1));
Vector2 texturePos = world.blocks[blockType].texture;
TextureCube (texturePos);
}
void CubeWest (int x, int y, int z, int blockType)
{
newVertices.Add(new Vector3(x, y-1, z+1));
newVertices.Add(new Vector3(x, y, z+1));
newVertices.Add(new Vector3(x, y, z));
newVertices.Add(new Vector3(x, y-1, z));
Vector2 texturePos = world.blocks[blockType].texture;
TextureCube (texturePos);
}
void TextureCube (Vector2 texturePos)
{
newTriangles.Add(faceCount*4);
newTriangles.Add(faceCount*4+1);
newTriangles.Add(faceCount*4+2);
newTriangles.Add(faceCount*4);
newTriangles.Add(faceCount*4+2);
newTriangles.Add(faceCount*4+3);
newUV.Add(new Vector2(textureUnit * texturePos.x+textureUnit, textureUnit*texturePos.y));
newUV.Add(new Vector2(textureUnit * texturePos.x+textureUnit, textureUnit*texturePos.y + textureUnit));
newUV.Add(new Vector2(textureUnit * texturePos.x, textureUnit*texturePos.y + textureUnit));
newUV.Add(new Vector2(textureUnit * texturePos.x, textureUnit*texturePos.y));
faceCount ++;
}
}
The null reference is occurring on the ChunkScript in the part that says:
int Block(int x, int y, int z)
{
return world.Block(x+chunkX,y+chunkY,z+chunkZ); *** This is the line that has the error ***
}
I know it is a ton of code to read but I dont know what else to do. Thank you for helping