Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by Theacesofspades · Sep 05, 2015 at 06:30 PM · arraynull reference exception

How can i fix the null reference?

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

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
1
Best Answer

Answer by robin-theilade · Sep 05, 2015 at 07:30 PM

@Theacesofspades, My guess is that WorldScript.DistanceToChunk is not waiting for the chunk's Start method to be called after setting it active before callings it's GenerateMesh method which in turn calls the Block method that throws the exception. The start method is required for the field ChunkScript.world to be assigned.

Use breakpoints or Debug.Log to verify the order of calling with the ChunkScript.Block, ChunkScript.Start and WorldScript.GenerateMesh (just after setting the chunk active) methods.

Edit: Extended answer

=== ChunkScript.cs changes ===

Replace the Start method with this.

     void Awake()
     {
         world = GameObject.FindObjectOfType<WorldScript>();
         chunkSize = world.chunkSize;
         mesh = GetComponent<MeshFilter>().mesh;
         col = GetComponent<MeshCollider>();
 
         textureUnit = world.textureUnit;
     }

Changing from Start to Awake method means it gets invoked earlier which is needed in this case.

Remove public GameObject worldGO; .

=== WorldScript.cs changes ===

Remove newChunkScript.worldGO=gameObject;

Comment
Add comment · Show 3 · 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
avatar image Theacesofspades · Sep 06, 2015 at 04:33 AM 0
Share

This can't be the solution because the chunks all get created then I move the player down from above about 5 seconds after the game is started

avatar image robin-theilade · Sep 06, 2015 at 08:40 AM 0
Share

I've updated my answer.

avatar image Theacesofspades · Sep 06, 2015 at 05:04 PM 0
Share

Thank you so so much. I changed the start function to awake and it worked perfectly. I needed to keep the worldGO though. But thank you so much.

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

28 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 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

Issues with setting values in custom class 0 Answers

NullReferenceException: Object reference not set to an instance of an object 1 Answer

Having issues with a NullReferenceException error. Code does as expected in some instances but I receive the error in others. Debugger directs me to line where if(hit.collider.tag == (DestructibleCube")). 1 Answer

[Solved] Null Reference Exception on a text variable 1 Answer

NullReferenceException after loading a new scene ? 0 Answers


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