I'm working my way through this voxel tutorial in Unity. I'm on part 3, and it's showing me how to create a chunk within the world.
I've copied the code, but I think I am missing something. The error that shows up is:
NullReferenceException: Object reference not set to an instance of an object
Chunk.UpdateChunk () (at Assets/scripts/Chunk.cs:76)
Chunk.Update () (at Assets/scripts/Chunk.cs:34)
The offending code is at this line:
meshData = blocks[x, y, z].Blockdata(this, x, y, z, meshData);
Chunk.cs
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class Chunk : MonoBehaviour
{
private Block[,,] blocks = new Block[chunkSize, chunkSize, chunkSize];
public static int chunkSize = 16;
public bool update = true;
MeshFilter filter;
MeshCollider coll;
public World world;
public WorldPos pos;
void Start()
{
filter = gameObject.GetComponent<MeshFilter>();
coll = gameObject.GetComponent<MeshCollider>();
}
//Update is called once per frame
void Update()
{
if (update)
{
update = false;
UpdateChunk();
}
}
public Block GetBlock(int x, int y, int z)
{
if (InRange(x) && InRange(y) && InRange(z))
return blocks[x, y, z];
return world.GetBlock(pos.x + x, pos.y + y, pos.z + z);
}
public static bool InRange(int index)
{
if (index < 0 || index >= chunkSize)
return false;
return true;
}
public void SetBlock(int x, int y, int z, Block block)
{
if (InRange(x) && InRange(y) && InRange(z))
{
blocks[x, y, z] = block;
}
else
{
world.SetBlock(pos.x + x, pos.y + y, pos.z + z, block);
}
}
// Updates the chunk based on its contents
void UpdateChunk()
{
MeshData meshData = new MeshData();
for (int x = 0; x < chunkSize; x++)
{
for (int y = 0; y < chunkSize; y++)
{
for (int z = 0; z < chunkSize; z++)
{
// **NullReferenceException occurs on this line:**
meshData = blocks[x, y, z].Blockdata(this, x, y, z, meshData);
}
}
}
RenderMesh(meshData);
}
// Sends the calculated mesh information
// to the mesh and collision components
void RenderMesh(MeshData meshData)
{
filter.mesh.Clear();
filter.mesh.vertices = meshData.vertices.ToArray();
filter.mesh.triangles = meshData.triangles.ToArray();
filter.mesh.uv = meshData.uv.ToArray();
filter.mesh.RecalculateNormals();
coll.sharedMesh = null;
Mesh mesh = new Mesh();
mesh.vertices = meshData.colVertices.ToArray();
mesh.triangles = meshData.colTriangles.ToArray();
mesh.RecalculateNormals();
coll.sharedMesh = mesh;
}
}
However, I think it's maybe not the code that's the problem. Rather, I am missing a step. There is a section of the tutorial that says:
Let's start with a function to create new chunks, since chunks are game objects we'll need to use the instantiate method with a prefab to create the chunks so create a variable chunkPrefab:
public GameObject chunkPrefab;
And also create a prefab of a chunk. Use the chunk object we've been using or create a new one. It just needs to be a game object with the material applied and chunk script which automatically includes the mesh renderer, mesh filter and mesh collide . By the way make sure your mesh collider has convex set to false or your colliders wont work. Make a prefab of it by dragging it from the hierarchy to the project view. Then delete it from the scene and make a new object with the world script on it and set the chunkPrefab variable to the one we just made.
How do I create a prefab of a chunk
? Do I go to:
Assets->Create->Prefab
and then assign my chunk.cs
script to it? Or do I assign my current gameobject to it (which has chunk.cs and the tileset material attached)? Or am I misreading this entirely?
Here is what my scene looks like so far:
Pictures would really help!
blocks[x, y, z]
returns null. You have not included its definition in your post, so I am unable to diagnose further. See also stackoverflow.com/questions/4660142/… \$\endgroup\$World.cs
, and it generates the blocks at (x,y,z) in hisStart()
method. I think the code is valid, it's just for some reason I have not done some step in Unity that calls World.cs Start() method, so the blocks are all null. I'm not sure what step I'm missing, but I am guessing it has to do with the Prefab step I listed. I don't understand what that missing step is exactly though. \$\endgroup\$World
script attached to a GameObject in the scene hierarchy? \$\endgroup\$