- Home /
NullReferenceError, Tilemap Array with Transforms and Raycast (C# with Demo)
hi there..
i created a tilemap(x,y) array, wich holds a bunch of transforms (child objects). The transforms are set into the array via their (int)(positions/tilesize)
1st problem: I added a Debug.LogError to the Array setting - wich only activates if an array field is != null.. wich means - this array position is already filled. And it happens here and there, that this message appears - and i´ve no clue why.. it seems like the calculation for the array field sometimes equals the result of the neightbour tile :/
2nd problem: I try to hit each tile with a raycast on the mouseposition. if i move the mouse over a tile, i get a NullreferenceError..
Map_Loader.Update () (at Assets/Scripts/Map_Loader.cs:XXX) //XXX = Line Number To make it simplier.. i created this Demo: [<< KotD Demo >>][1] Here´s the complete maploader Script with the Array thing: using UnityEngine; using System.Collections;NullReferenceException: Object reference not set to an instance of an object
public class Map_Loader : MonoBehaviour {
public int scrollspeed = 10; public int zoomspeed = 20; public int rotatespeed = 5;
public int mapsize_x = 1; public int mapsize_y = 1;
public Vector3 mouse3d; public Vector2 mouse3dtile;
public GameObject TilemapHolder; public GameObject kamera; public GameObject kamera_view; public Camera kamera_view_cam; public GameObject BasicMapPrefab; public GameObject BasicBlockForSize;
public int ;
public GameObject DirtBlock; public GameObject DirtStraight; public GameObject DirtInnerCurver; public GameObject DirtOuterCurver; public GameObject DirtRoof; public GameObject DirtGold; public GameObject DirtDitrima; public GameObject DirtFloor;
public int generateChunkSize = 64;
public int __ ;
//public BlockStats[][] tilemap; BlockStats scriptholder; public Transform[,] tilemap;
Ray mousepoint; RaycastHit hit; Vector3 size; Vector2 old_transform = new Vector2(0,0); Vector2 new_transform = new Vector2(0,0); int running_id = 0; Transform childholder;
// Use this for initialization void Start () {
MeshFilter mf = BasicBlockForSize.GetComponent(typeof(MeshFilter)) as MeshFilter; if (mf == null){return;} Mesh mesh = mf.sharedMesh; if (mesh == null){return;} size = mesh.bounds.size;
old_transform = new Vector2(0,0); new_transform = new Vector2(0,0);
StartCoroutine(createMap());
kamera.transform.position = new Vector3(((mapsize_x/2)*size.x), 0, ((mapsize_y/2)*size.x)); }
IEnumerator createMap() { if(mapsize_x > 10 || mapsize_y > 10){ Debug.LogError("Mapsize is out of Bounds. Please set a maximum size of 10*10 Prefabs."); Application.Quit(); } running_id = 1; int maprun_x = 0; int maprun_y = 0; float pos_x = 0; float pos_y = 0; int blockid = 0; int Array_index_x = 0; int Array_index_y = 0; GameObject[] created_block; created_block = new GameObject[101];
//tilemap = new BlockStats[320][]; //for(maprun_x=0; maprun_x<320; maprun_x++){ //tilemap[maprun_x] = new BlockStats[320]; //} tilemap = new Transform[321,321];
for(maprun_x=0; maprun_x<101; maprun_x++){ created_block[maprun_x] = null; }
blockid = 0;
for(maprun_y=0; maprun_y //Detach children and add them to the Block_Holder
for(maprun_x=0; maprun_x -1; maprun_y--){ childholder.GetChild(maprun_y).name = "Tile_"+running_id; childholder.GetChild(maprun_y).parent = TilemapHolder.transform; running_id ++; }
yield return 0;
//Debug.Log("PARENT_ID: " + maprun_x + " von " + (blockid-1)); childholder.DetachChildren(); Destroy(created_block[maprun_x]); } }
//Store objects in the tilemap childholder = TilemapHolder.transform; for(maprun_y=childholder.childCount-1; maprun_y>-1; maprun_y--){ Array_index_x = Mathf.FloorToInt(childholder.GetChild(maprun_y).position.x/size.x); Array_index_y = Mathf.FloorToInt(childholder.GetChild(maprun_y).position.z/size.x); Debug.Log(Array_index_x + " | " + Array_index_y); //tilemap[Array_index_x][Array_index_y] = gameObject.GetComponent(); if(tilemap[(int)Array_index_x, (int)Array_index_y] != null){ Debug.LogError("pos " + Array_index_x + "," + Array_index_y + " is not null"); } else{ tilemap[(int)Array_index_x, (int)Array_index_y] = childholder.GetChild(maprun_y); Debug.Log(tilemap[(int)Array_index_x, (int)Array_index_y]); } } Debug.Log(tilemap); //Getting the GO of a Script: GO = tilemap[x][y].GameobjectRef; } // Update is called once per frame void Update () { if(Input.mousePosition.x < 10) {kamera.transform.Translate(-scrollspeed*Time.deltaTime,0,0);} else if(Input.mousePosition.x > Screen.width-10) {kamera.transform.Translate(scrollspeed*Time.deltaTime,0,0);} if(Input.mousePosition.y < 10) {kamera.transform.Translate(0,0,-scrollspeed*Time.deltaTime);} else if(Input.mousePosition.y > Screen.height-10) {kamera.transform.Translate(0,0,scrollspeed*Time.deltaTime);} if(Input.GetKey(KeyCode.End) && kamera_view.camera.fieldOfView < 70) // back {kamera_view.camera.fieldOfView += zoomspeed*Time.deltaTime;} else if(Input.GetKey(KeyCode.Home) && kamera_view.camera.fieldOfView > 30) // forward {kamera_view.camera.fieldOfView -= zoomspeed*Time.deltaTime;} else if(Input.GetAxis("Mouse ScrollWheel") < 0 && kamera_view.camera.fieldOfView < 70) // back {kamera_view.camera.fieldOfView += zoomspeed*3*Time.deltaTime;} else if(Input.GetAxis("Mouse ScrollWheel") > 0 && kamera_view.camera.fieldOfView > 30) // forward {kamera_view.camera.fieldOfView -= zoomspeed*3*Time.deltaTime;} if(Input.GetKey(KeyCode.Delete)) {kamera.transform.Rotate(new Vector3(0,-rotatespeed*Time.deltaTime,0));} else if(Input.GetKey(KeyCode.PageDown)) {kamera.transform.Rotate(new Vector3(0,rotatespeed*Time.deltaTime,0));} kamera.transform.position = new Vector3(kamera.transform.position.x, 0, kamera.transform.position.z); //Get 3D Mouse Position //if (Input.GetMouseButton(0)) { mousepoint = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(mousepoint, out hit)) { if (hit.transform != null) { mouse3dtile = new Vector2(Mathf.FloorToInt(hit.transform.position.x/size.x), Mathf.FloorToInt(hit.transform.position.z/size.x)); new_transform = mouse3dtile; Debug.Log(" X: " + new_transform.x + "| Y: " + new_transform.y + "| INHALT: " + tilemap[(int)new_transform.x, (int)new_transform.y]); if((int)old_transform.x != (int)new_transform.x || (int)old_transform.y != (int)new_transform.y){ scriptholder = tilemap[(int)old_transform.x, (int)old_transform.y].gameObject.GetComponent(); scriptholder.highlightoff(); scriptholder = tilemap[(int)new_transform.x, (int)new_transform.y].gameObject.GetComponent(); scriptholder.highlighton(); old_transform = new Vector2((int)new_transform.x, (int)new_transform.y); } //highlight model, reset old_transform, set new old_transform } } else { //reset old_transform // if((int)old_transform.x != -1 && (int)old_transform.y != -1){ // scriptholder = tilemap[(int)old_transform.x, (int)old_transform.y].gameObject.GetComponent(); // scriptholder.highlightoff(); // old_transform = new Vector2(-1,-1); // } } //} //mouse3dtile = new Vector3((int)(mouse3d.x/size.x)*size.x, 0, (int)(mouse3d.x/size.x)*size.x); } } And here the Block-Dummy Script (wich is included in EVERY Tile): using UnityEngine; using System.Collections; public class BlockStats : MonoBehaviour { Transform _transform; GameObject SelfObject; Color32 basic_color = new Color32(150,150,150,255); Color32 highlightcolor = new Color32(250,250,150,255); //GameObject SelfObject = gameObject; // Use this for initialization void Start () { _transform = transform; SelfObject = _transform.gameObject; basic_color = SelfObject.renderer.material.color; } public void highlightoff(){ SelfObject.renderer.material.color = basic_color; } public void highlighton(){ SelfObject.renderer.material.color = highlightcolor; } } I hope someone can help me out - cause i´m waiting for help in the forum for a while now.. and got no fixing answer :'-( thanks for reading [1]: http://blackdevilcreations.de/KotD.rar
Done.. i added both Scripts into the startpost But it´s really better to see it in the demo ._.
I can't fully follow it. $$anonymous$$ostly because it's very hard to read.
What line is the null ref error? And please explain more about the LogError that sometimes happens (including marking in the code where these things occur).
It's good to see that you're using a bunch of Debug.Log statements - but perhaps right around these errors, you need to have one per line that verifies each setting of each line so that you can be sure they are doing as you expect.
the 'tilemap[x][y] is not null LogError is in the blovk at line 32-49. That's the Block where the tilemap is getting filled.
the NullReferenceError happens in the block after line 80, wich should call the block functions.
It looks like you're getting which tile was hit by it's world coordinate?
Why not use something like a tag for that?