Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by WHYMEUnity · Aug 06, 2013 at 10:48 PM · c#terrainminecraft

Voxel Brush throwing Null Reference

Hello all,

 I'm currently in the midst of working on a voxel engine, using C#.

Now, I have managed to follow along with some tutorials, and I have a "world" that generates chunks, and these chunks are filled with blocktype. I am able to build/destroy on any generated chunk i wish.

 NOTE- I have not implemented any kind of Perlin noise, or "real" terrain generation. It is currently just a flat world.

 Now up to this point everything works great. The world is "randomly" generated as you "explore". But when I tried to implement a brush, it broke.

First off when using a brush, the "world" technically still generates chunks, the first problem is that only a handful of the chunks are filled with blocks. The remaining chunks are only empty prefabs. Then I get an error, Null Reference.

The Second problem is that when using the brush, the brushes don't generate at all. As mentioned the chunks still generate, most unfilled, however not a single brush generates.

and heres the code , with error- Any help is appreciated.

NullReferenceException Chunk.Regenerate () (at Assets/MyAssets/Scripts/Chunk.cs:179) Chunk.SetBrick (Int32 x, Int32 y, Int32 z, Byte block) (at Assets/MyAssets/Scripts/Chunk.cs:215) Chunk.ApplyBrush (LandBrush brush) (at Assets/MyAssets/Scripts/Chunk.cs:72) Chunk.Start () (at Assets/MyAssets/Scripts/Chunk.cs:32)

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 
 
 [RequireComponent (typeof(MeshFilter))]
 [RequireComponent (typeof(MeshCollider))]
 public class Chunk : MonoBehaviour {
     public int width = 20;
     public byte[,,] map;
     
     protected Mesh mesh;
     
     protected List<Vector3> verts = new List<Vector3>();
     protected List<int> tris = new List<int>();
     protected List<Vector2> uv = new List<Vector2>();
     
     public struct LandBrush {
     public Vector3 pos;
     public float size;
     public byte block;
     }
     
     protected MeshCollider meshCollider;
     // Use this for initialization
     void Start () {
         
         map = new byte[width, width, width];
         
         LandBrush brush = CreateBrush();
         ApplyBrush(brush);
         
         
         for (int x = 0; x < width; x++)
         {
             for (int z = 0; z < width; z++)
             {
                 map[x, 0, z] = 1;
             }
         }
         meshCollider = GetComponent<MeshCollider>();
         mesh = new Mesh();
         GetComponent<MeshFilter>().mesh = mesh;
         
         Regenerate();
     }
     
     // Update is called once per frame
     void Update () {
     
     }
     
     public void ApplyBrush(LandBrush brush) {
         
         
 
         float minY = brush.pos.y - brush.size;
         float maxY = brush.pos.y + brush.size;
         float minZ = brush.pos.z - brush.size;
         float maxZ = brush.pos.z + brush.size;
         
         for (float x = brush.pos.x - brush.size; x <= brush.pos.x + brush.size; x++)
         {
             for (float y = minY; y <= maxY; y++)
             {
                 for (float z = minZ; z<= maxZ; z++)
                 {
                     Vector3 p = new Vector3(x,y,z);
                     p -= brush.pos;
                     if (p.magnitude >= brush.size) continue;
                     SetBrick( Mathf.FloorToInt(x), Mathf.FloorToInt(y), Mathf.FloorToInt(z), brush.block);
                 }
             }
         }
     }
     
     public void DrawBrick(int x, int y, int z, byte block)
     {
         Vector3 start = new Vector3(x,y,z);
         Vector3 offset1, offset2;
         
         if (IsTransparent(x,y-1,z))
         {
             offset1 = Vector3.left;
             offset2 = Vector3.back;
             DrawFace(start + Vector3.right,offset1,offset2,block);
         }
         if (IsTransparent(x,y+1,z))
         {
             offset1 = Vector3.right;
             offset2 = Vector3.back;
             DrawFace(start + Vector3.up,offset1,offset2,block);
         }
         if (IsTransparent(x-1,y,z))
         {
             offset1 = Vector3.up;
             offset2 = Vector3.back;
             DrawFace(start,offset1,offset2,block);
         }
         if (IsTransparent(x+1,y,z))
         {
             offset1 = Vector3.down;
             offset2 = Vector3.back;
             DrawFace(start + Vector3.right + Vector3.up,offset1,offset2,block);
         }
         if (IsTransparent(x,y,z-1))
         {
             offset1 = Vector3.left;
             offset2 = Vector3.up;
             DrawFace(start + Vector3.right + Vector3.back,offset1,offset2,block);
         }
         if (IsTransparent(x,y,z+1))
         {
             offset1 = Vector3.right;
             offset2 = Vector3.up;
             DrawFace(start,offset1,offset2,block);
         }
     }
     public void DrawFace(Vector3 start, Vector3 offset1, Vector3 offset2, byte block)
     {
         int index = verts.Count;
     
         verts.Add (start);
         verts.Add (start + offset1);
         verts.Add (start + offset2);
         verts.Add (start + offset1 + offset2);
         
         Vector2 uvBase;
         switch (block)
         {
         default:
             uvBase = new Vector2(0.25f, 0.25f);
             break;
         case 2:
             uvBase = new Vector2(0.75f, 0.75f);
             break;
         case 3:
             uvBase = new Vector2(0.25f, 0.75f);
             break;
         case 4:
             uvBase = new Vector2(0.75f, 1f);
             break;
         }
         
         if ((offset1 == Vector3.right) && (offset2 == Vector3.back))
         {
             uv.Add (uvBase);
             uv.Add (uvBase + new Vector2(0.125f, 0));
             uv.Add (uvBase + new Vector2(0, 0.125f));
             uv.Add (uvBase + new Vector2(0.125f, 0.125f));
         }
         else
         {
             uv.Add (uvBase);
             uv.Add (uvBase + new Vector2(-0.125f, 0));
             uv.Add (uvBase + new Vector2(0, 0.125f));
             uv.Add (uvBase + new Vector2(-0.125f, 0.125f));
         }
         
         tris.Add(index + 0);
         tris.Add(index + 1);
         tris.Add(index + 2);
         tris.Add(index + 3);
         tris.Add(index + 2);
         tris.Add(index + 1);
     }
     
     public bool IsTransparent(int x, int y, int z)
     {
         if ((x<0) || (y<0) || (z<0) || (x>= width) || (y>=width) || (z>=width)) return true;
         return map[x,y,z] == 0;
     }
     
     public void Regenerate() {
         verts.Clear();
         tris.Clear();
         uv.Clear();
         mesh.triangles = tris.ToArray();
         for (int x = 0; x < width; x++)
         {
             for (int y = 0; y < width; y++)
             {
                 for (int z = 0; z < width; z++)
                 {
                     byte block = map[x,y,z];
                     if (block == 0) continue;
                     
                     DrawBrick(x,y,z,block);
                     
                 }
             }
         }
         
         mesh.vertices = verts.ToArray();
         mesh.triangles = tris.ToArray();
         mesh.uv = uv.ToArray();
         mesh.RecalculateNormals();
         
         meshCollider.sharedMesh = null;
         meshCollider.sharedMesh = mesh;
     
     }
     public void SetBrick(int x, int y, int z, byte block){
         
         x -= Mathf.RoundToInt(transform.position.x);
         y -= Mathf.RoundToInt(transform.position.y);
         z -= Mathf.RoundToInt(transform.position.z);
         
         if ((x<0) || (y<0) || (z<0) || (x>= width) || (y>=width) || (z>=width)) return;
         
         if (map[x,y,z] !=block)
         {
             map[x,y,z] = block;
             Regenerate();
         }
 
     }
     
     public LandBrush CreateBrush(){
         LandBrush brush = new LandBrush();
         brush.pos = new Vector3(Random.value * width + transform.position.x, 0, Random.value * width + transform.position.z);
         brush.size = Random.value * width / 2;
         brush.block = 1;
         return brush;
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Peter G · Aug 06, 2013 at 11:15 PM

First, if you don't know what a NullReferenceException is, read this.

Here's what I think is happen. Now given you have a lot of if statement wrappers and I didn't really follow them to see if they'd get called, but this is a possibility.

It would appear mesh is null. Now at first glance it doesn't appear to be used before you call Regenerate(), but following a chain of methods, you get this:

  ApplyBrush() -> calls SetBrick() -> calls Regenerate()

Again I didn't check to make sure all of the if statements would be true, but that could be it. If mesh isn't null, then your list is null.

I think the easiest way to fix that is just to initialize the mesh above ApplyBrush().

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

15625 blocks are making my game lag? Increase performance? 3 Answers

Multiple Cars not working 1 Answer

SetAlphaMaps Opacity Gradient 0 Answers

Ingame Texture Switcher 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges