For example i have a grid that it's size is 10x10 But the script should be working for any size of grid but to explain let's say the size is 10x10. So i have a grid of 100 GameObject.
12345678910
11121314151617181920
212223242526........
100
So if i take the left side of the grid it will be: 0,11,21,31,41,51,61,71,81,91 The right side: 10,20,30,40,50,60,70,80,90,100 The top 1,2,3,4,5,6,7,8,9,10 The bottom 91,92,93,94,95,96,97,98,99,100
Now i want in the code in the script that each time i will running the game it will pick a random number from each side of the grid. For example:
21,30,1,98
Then i want to destroy this 4 numbers to destroy this 4 GameObjects from the grid.
What i tried first to do considering the grid size is 10x10:
private void GenerateRandom()
{
var arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int mynum = arr[Random.Range(0, arr.Length)];
GameObject Top = objects[mynum];
int[] arr1 = new int[] { 1, 11, 21, 31, 41, 51, 61, 71, 81, 91 };
int mynum1 = arr1[Random.Range(0, arr1.Length)];
GameObject Left = objects[mynum1];
int[] arr2 = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
int mynum2 = arr2[Random.Range(0, arr2.Length)];
GameObject Right = objects[mynum2];
int[] arr3 = new int[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 };
int mynum3 = arr3[Random.Range(0, arr3.Length)];
GameObject Bottom = objects[mynum3];
}
And this is how i create the Grid it self:
for (int x = 0; x < mapWidth; x++)
{
float positionWidth = Spacing * (float)x;
for (int z = 0; z < mapHeight; z++)
{
float positionWidth1 = Spacing * (float)z;
GameObject block = Instantiate(Node, Vector3.zero, Node.transform.rotation) as GameObject;
block.transform.parent = transform;
block.transform.localPosition = new Vector3(positionWidth, 0, positionWidth1);
block.transform.localScale = new Vector3(nodeScale.x, nodeScale.y, nodeScale.z);
block.tag = "NodeDestroyable";
objects.Add(block);
}
}
But in this way i have some problems.
First in the two loops i start them from 0:
int x = 0; x < mapWidth; x++
int z = 0; z < mapHeight; z++
So when i make arrays to get random numbers from should i start them from 0 or maybe from 1 ?
var arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Should the array start from 0 or 1 ? 0 to 9 or 1 to 10 ?
The second problem it didn't work fine didn't destroyed objects like i wanted and sometimes gave me exception/s out of range index.
This is the completed code:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
public class GeneratorTesting : MonoBehaviour
{
public GameObject Node;
public Vector3 nodeScale = new Vector3(4, 1, 4);
public int mapWidth = 10;
public int mapHeight = 10;
public float Spacing = 2.0f;
public float spawnSpeed = 5;
private List<GameObject> objects = new List<GameObject>();
private void Start()
{
Generate();
GenerateRandom();
}
private void Generate()
{
if (objects.Count > 0)
objects = new List<GameObject>();
if (Node == null)
Node = GameObject.FindGameObjectWithTag("Main Node");
for (int x = 0; x < mapWidth; x++)
{
float positionWidth = Spacing * (float)x;
for (int z = 0; z < mapHeight; z++)
{
float positionWidth1 = Spacing * (float)z;
GameObject block = Instantiate(Node, Vector3.zero, Node.transform.rotation) as GameObject;
block.transform.parent = transform;
block.transform.localPosition = new Vector3(positionWidth, 0, positionWidth1);
block.transform.localScale = new Vector3(nodeScale.x, nodeScale.y, nodeScale.z);
block.tag = "NodeDestroyable";
objects.Add(block);
}
}
}
private void GenerateRandom()
{
var arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int mynum = arr[Random.Range(0, arr.Length)];
GameObject Top = objects[mynum];
int[] arr1 = new int[] { 1, 11, 21, 31, 41, 51, 61, 71, 81, 91 };
int mynum1 = arr1[Random.Range(0, arr1.Length)];
GameObject Left = objects[mynum1];
int[] arr2 = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
int mynum2 = arr2[Random.Range(0, arr2.Length)];
GameObject Right = objects[mynum2];
int[] arr3 = new int[] { 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 };
int mynum3 = arr3[Random.Range(0, arr3.Length)];
GameObject Bottom = objects[mynum3];
DestroyImmediate(Bottom);
DestroyImmediate(Left);
}
public void GenerateNew()
{
for (int i = 0; i < objects.Count; i++)
{
DestroyImmediate(objects[i]);
}
Node = GameObject.FindGameObjectWithTag("Main Node");
Generate();
GenerateRoute();
}
public void DestroyNodes()
{
GameObject[] nodes = GameObject.FindGameObjectsWithTag("NodeDestroyable");
if (nodes.Length == 0)
{
Debug.Log("No nodes to destroy found");
}
else
{
for (int i = 0; i < nodes.Length; i++)
{
DestroyImmediate(nodes[i]);
}
}
}
private void Update()
{
Erase();
}
private void Erase()
{
if (Input.GetMouseButton(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "NodeDestroyable")
{
Destroy(hit.collider.gameObject);
}
}
}
}
}
So the first thing is to fix the arrays and getting random number from each side of the grid.
Second to make it for any size of grid not only 10x10 the grid might be in size 3x4 or 40x2 or 9x9
Since this is not working fine i thought maybe adding a helper class but not sure if it's right idea and how to use it:
public static class ArrayExtensions
{
public static T SelectRandomElement<T> ( this T[] source )
{
if (source.Length == 0)
return default(T);
var index = s_random.Next(0, source.Length - 1);
return source[index];
}
private static readonly Random s_random = new Random();
}
And inside the ArrayExtensions i should also use this two methods:
//Extension methods in the class given earlier
public static T SelectRandomElementFromLeft<T> ( this IEnumerable<T[]> source )
{
//First select a random array
var totalArrays = source.Count();
var arrayIndex = s_random.Next(0, totalArrays - 1);
//Now select the first element from that row
var arr = source.Skip(arrayIndex).Take(1).FirstOrDefault();
return arr.FirstOrDefault();
}
public static T SelectRandomElementFromRight<T> ( this IEnumerable<T[]> source )
{
//First select a random array
var totalArrays = source.Count();
var arrayIndex = s_random.Next(0, totalArrays - 1);
//Now select the last element from that row
var arr = source.Skip(arrayIndex).Take(1).FirstOrDefault();
return arr.LastOrDefault();
}
But not sure how to use it with the arrays in GenerateRandom()
The goal the main idea is each time running the game to get 4 random numbers each from each side of the grid. And i think there might be two cases that there can be same numbers so if there is such a case to automatic generate new random numbers or to check and make sure there will be no same numbers like 1 and 1 or 91 and 91 or 100 and 100.