store instantiated in Array. c#

so, i am trying to add instatiated gameobjects position x,y,z to an array, so i can get a random from the list to generate a “Ore” or well, it doesent really matter what, just so i can get a random from the list and get that objects position.
But it is really bugging me, this is how far ive comen yet

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TerrainPerlinNoise : MonoBehaviour {
	int chunkheightmapWidth = 100;
	int chunkheightmapHeight = 100;
	public float EpicGenerator;
	private Quaternion rot;
	
	public GameObject cubePrefab;

	public GameObject Cubes = null;	
  	public Vector3[,,] CubeCount = new Vector3[100,20,100];
	public int _Xpos;
	public int _Ypos;
	public int _Zpos;
	
	OreGen oregen;
	
	int posI = 0;
	int posK = 0;
	
	
    public float Tiling = 10.0f; 
    void Start()
    {

		EpicGenerator = Random.Range(0.8f, 1.9f);
		rot.eulerAngles = new Vector3(0,0,0);
		GenerateHeights(Tiling);

    }
 
	void Update()
	{
		if(Input.GetKeyDown(KeyCode.I)){
		Debug.Log(Random.Range(0,(CubeCount.Length - 1)));
		
		oregen.generate(CubeCount[3,3,3 ]);	
		}
	}
	
	
    public void GenerateHeights(float tileSize)
    {
        float[,] heights = new float[chunkheightmapWidth, chunkheightmapHeight];

		
        for (int i = posI; i < chunkheightmapWidth; i++)
        {
			
            for (int k = posK; k < chunkheightmapHeight; k++)
            {
                heights[i, k] = Mathf.PerlinNoise(((float)i / (float)chunkheightmapWidth) * tileSize, ((float)k / (float)chunkheightmapHeight) * tileSize)/EpicGenerator;
 				Cubes = Instantiate(cubePrefab, new Vector3(i, heights[i, k], k), Quaternion.identity) as GameObject;
				Cubes.name ="Cube place: " + i + heights[i, k] + k;
				
				CubeCount[_Xpos, _Ypos, _Zpos] = (i + heights[i, k] + k);

			}
        }
		
    }
}

and i literraly have no idea wtf is going on, i give them new names, and i add them to cubecount, but when i ask to debug log CubeCount, it gives me ONE Integer, with 6 digits in it.

Length property returns number of elements in the array. If you create one-dimensional array, e.g. someArray[10], then length of dimension 0 (zero) is 10, and it is equal to Length of the whole array. If you create two-dimensional array, e.g. someArray[10,5], then length of dimension 0 is 10, length of dimension 1 is 5, and Length will return 50. You can get the length of given dimension by using GetLength(dimension) method.

In your case, you have three dimensional array, so Length is returning 10020100, so your random ranges from 0 to 199999. You have to do:

var randomX = Random.Range(0, CubeCount.GetLength(0) - 1);
var randomY = Random.Range(0, CubeCount.GetLength(1) - 1);
var randomZ = Random.Range(0, CubeCount.GetLength(2) - 1);

var randomElement = CubeCount[randomX, randomY, randomZ];

EDIT:

Ok - after all the comments, I think I now get the gist of your problem, although I have to admit it would be hard without image :slight_smile:

You want to have a terrain 32x32 tiles with random heights, and then you want to generate ore (or anything else) on top of random tile. Correct me if I’m wrong :slight_smile:

If the above is ok, then I’d do it that way:

using UnityEngine;

public class TileGen : MonoBehaviour {
	
	public GameObject cubePrefab;
	int chunkheightmapWidth = 32;
	int chunkheightmapHeight = 32;
	public float EpicGenerator;
	public float Tiling = 10.0f; 
	
	// two dimensional array of items - storing in one dimensional is also possible, but not the way you did
	public GameObject[,] items;
    // small addition, to check if given coordinates was already used
	private bool[,] alreadyGenerated;
	
	void Start()
	{
	    EpicGenerator = Random.Range(0.8f, 1.9f);
	    GenerateItems(Tiling);
	}
	 
	void Update()
	{
	    if(Input.GetKeyDown(KeyCode.I))
		{
		    var randomX = Random.Range(0, items.GetLength(0) - 1);
		    var randomZ = Random.Range(0, items.GetLength(1) - 1);
		    print("x: " + randomX + ", z: " + randomZ);
			GenerateOre(randomX, randomZ);
	    }
	}
	
	private void GenerateOre(int x, int z)
	{
		if(alreadyGenerated[x, z])
		{
			Debug.Log ("already generated at this location");
			return;
		}
		
		// get item on top of which you want to create ore
		var item = items[x,z];
		var ore = GameObject.CreatePrimitive(PrimitiveType.Sphere);
		ore.transform.position = item.transform.position + new Vector3(0, item.transform.localScale.y, 0);
		alreadyGenerated[x, z] = true;
	}
	
	public void GenerateItems(float tileSize)
	{
		items = new GameObject[chunkheightmapWidth, chunkheightmapHeight];
		alreadyGenerated = new bool[chunkheightmapWidth, chunkheightmapHeight];
		
	    for (int x = 0; x < chunkheightmapWidth; x++)
	    {
		    for (int z = 0; z < chunkheightmapHeight; z++)
		    {
	            var height = Mathf.PerlinNoise(((float)x / (float)chunkheightmapWidth) * tileSize, ((float)z / (float)chunkheightmapHeight) * tileSize)/EpicGenerator;
				var item = (GameObject)Instantiate(cubePrefab, new Vector3(x, height, z), Quaternion.identity);
				item.transform.parent = transform;
				items[x,z] = item;
       		}
		}
    }
}

If it’s ok, but you don’t have a clue why some part of it works, please let me know, as I want you to understand this.