- Home /
New Object Instantiation from Array working in Start() but not Update()
Hello there! I'm fairly new to unity and C# in general, so I'm hoping one of you fine people can help me out. I'm trying to dynamically load chunks of map data as my player walks around. The initial load works in the start() function, but when I run the exact same function in update() as my player nears the edge of the map it throws this error:
NullReferenceException: A null value was found where an object instance was required.
World.NewChunk (Int32 x, Int32 y, Int32 z) (at Assets/World.cs:61)
World.ChunkUpdate () (at Assets/World.cs:100)
World.Update () (at Assets/World.cs:55)
The error points at my NewChunk() function, specifically the reference to "chunks[x,y,z]= Instantiate(chunk,". I'm very confused because from what I understand the Update() function seems to be unable to access the chunks array I've setup. Any idea why this is? I've included the full World script below.
using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
public class World : MonoBehaviour {
public byte[,,] data;
public int worldX=511;
public int worldY=126;
public int worldZ=510;
public int cullDist = 4;
public GameObject chunk;
public GameObject[,,] chunks;
public bool[,,] chunkTest;
public int chunkSize=32;
public int playerChunkX = -1;
public int playerChunkz = -1;
public int timerChunkUpdate = 5;
void Start () {
data = new byte[worldX,worldY,worldZ];
TextAsset World = Resources.Load("NewPompeii") as TextAsset;
MemoryStream s = new MemoryStream (World.bytes);
var b = new BinaryReader(s);
for (int y=0; y<worldY; y++){
for (int z=0; z<worldZ; z++){
for (int x=0; x<worldX; x++) {
data[x,y,z] = b.ReadByte();
}
}
}
chunks=new GameObject[Mathf.FloorToInt(worldX/chunkSize),
Mathf.FloorToInt(worldY/chunkSize),
Mathf.FloorToInt(worldZ/chunkSize)];
ChunkUpdate ();
}
void Awake() {
//Application.targetFrameRate = 30;
}
void Update () {
ChunkUpdate ();
}
void NewChunk(int x, int y, int z){
chunks[x,y,z]= Instantiate(chunk,
new Vector3((x)*chunkSize,(y)*chunkSize,(z)*chunkSize),
new Quaternion(0,0,0,0)) as GameObject;
Chunk newChunkScript = chunks[x,y,z].GetComponent("Chunk") as Chunk;
newChunkScript.name = "chunk " + x + "," + y + "," + z;
newChunkScript.worldGO=gameObject;
newChunkScript.chunkSize=chunkSize;
newChunkScript.chunkX=(x)*chunkSize;
newChunkScript.chunkY=(y)*chunkSize;
newChunkScript.chunkZ=(z)*chunkSize;
//newChunkScript.cullDist=cullDist;
//newChunkScript.rend = newChunkScript.GetComponent<Renderer> ();
//chunkTest [x, y, z] = true;
return;
}
void ChunkUpdate(){
GameObject player = GameObject.FindWithTag("MainCamera");
Transform target = player.transform;
var targetX = (int) target.position.x/chunkSize;
//var targetY = (int) target.position.y/chunkSize;
var targetZ = (int) target.position.z/chunkSize;
if (targetX != playerChunkX || targetZ != playerChunkz) {
playerChunkX = targetX;
playerChunkz = targetZ;
for (int y = 0; y < worldY/chunkSize; y++) {
for (int z = 0; z < 2*cullDist; z++) {
for (int x = 0; x < 2*cullDist; x++) {
if (GameObject.Find ("chunk " + (targetX + x-cullDist) + "," + y + "," + (targetZ + z-cullDist))) {
//if (chunkTest[targetX + x - cullDist, y, targetZ + z - cullDist]){
} else if (targetX+x-cullDist < Mathf.FloorToInt(worldX/chunkSize) && targetZ+z-cullDist < Mathf.FloorToInt(worldZ/chunkSize)){
NewChunk (targetX+x-cullDist, y, targetZ+z-cullDist);
}
}
}
}
}
}
public byte Block(int x, int y, int z){
if( x>=worldX || x<0 || y>=worldY || y<0 || z>=worldZ || z<0){
return (byte) 1;
}
return data[x,y,z];
}
}
The best way to debug this is by using a breakpoint and attach $$anonymous$$onoDevelop / VS to Unity. If you are not sure how to do this, I recommend looking it up.
$$anonymous$$y first guess would be that it's chunk that becomes null. Are you sure that it's pointing to a prefab, not an object in your scene that maybe gets destroyed?