[Solved] How to get non repeating random positions?

[EDITED] Have to random 16 cubes and my concern is that each should be placed at a unique position…means each cube should having (x,y,z) unique so no over placing on one position…just the way the cards shuffled in the game of poker or cube shuffled in Sliding picture puzzle…sorry for the bad English…and Thanks in advance…i am using c#,so help in C# will be much Helpful…Thanks Again…[Edited]… recently my cube’s position starts from (1,4,10),(2,4,10),(3,4,10),(4,4,10)…(1,3,10),(2,3,10),(3,3,10),(4,3,10)…so on… and i have to make the position of cubes to random…and not repeating…

using UnityEngine;
using System.Collections;

public class Random_Object : MonoBehaviour
{
	public GameObject cube1;
	public GameObject cube2;
	public GameObject cube3;
	public GameObject cube4;
	public GameObject cube5;
	public GameObject cube6;
	public GameObject cube7;
	public GameObject cube8;
	public GameObject cube9;
	public GameObject cube10;
	public GameObject cube11;
	public GameObject cube12;
	public GameObject cube13;
	public GameObject cube14;
	public GameObject cube15;
	
	
	
	
			
	void Start () 
	{
		ChangePosition();
	}	
	public void ChangePosition()
	{
	
		cube1.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
			
		cube2.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
				
		cube3.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube4.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube5.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
				
		cube6.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
				
		cube7.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube8.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
				
		cube9.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
				
		cube10.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
				
		cube11.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube12.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube13.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube14.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
		
		cube15.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
	
	}
	
}

easy… =)

public class tmp : MonoBehaviour {

	public int 	    randomLength = 10;
	public float 	min          = -10;
	public float 	max          = 10;
    public float    epsilon      = 0.1f;

	/// <summary>
	/// OnStart funct.
	/// </summary>
	void Start () 
	{
		string tmp = "";
		
		float[] randoms = new float[randomLength];
			
		int i = 0;
		
		while (i < randomLength)
		{
			float nextValue = Random.Range(min, max);
			bool contains = false;
			
			for (int j = 0; j < i; j++)
			{
				if (Mathf.Abs(randoms[j] - nextValue) < epsilon)
				{
					contains = true;
					break;
				}
			}
			
			if (!contains)
			{
				i++;	
				tmp += nextValue.ToString("g2") + "; ";
			}
		}
	
		Debug.Log(tmp);
	}
	
}

But for long range it’s better to use HashSet.Contains avoid while loop, and at the end,
HashSet.ToArray();

You can’t avoid the repetition of numbers, but you can minimize the probability of repetition. If you need Non-Repeating random number then you can use the following code:

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

public class Test : MonoBehaviour {
	

List<float> randomNumber = new List<float>();
float min = 10f;
float max = 11f;
	
void OnGUI()
{
   if(GUI.Button(new Rect(10f,10f,150f,25f),"Get random number"))
		{
			float randomNo = getRandomNumber();
			Debug.Log("---> "+randomNo);
		}
}

float getRandomNumber()
{
		float rndNo;
		//int counter = 0;
		while(true)
		{
			//counter++;
			rndNo = Random.Range(min,max);
			//print(counter);
			if(!randomNumber.Contains(rndNo))
			{
				randomNumber.Add(rndNo);
				break;
			}
		}
	
		return rndNo;
}
}

Here is another way with old school goto method (@Fattie will be happy about this one :slight_smile: )

Vector3[] cubes = new Vector3[16];
int index = 0;
void Update(){
    if(Input.GetKeyDown(KeyCode.Space)){
        RandomValue();
        print(cubes[index-1]);
    }	
}
void RandomValue(){
    Start:
        Vector3 val;
        while (true){
            val = new Vector3(Random.Range(a,b),Random.Range(a,b),Random.Range(a,b));
            for(int i = 0;i<cubes.Length;i++){
                if(val == cubes*)goto Start;*

}goto Outer;
}

  • Outer:*
  •   cubes[index++]= val;*
    

}

You can’t get a “non-repeating” random, since its randomly generating your values for each time.

What you need to do, is to make a check on the random value you are recieving.
If this value is already being used, then just do another random call until you get a valu that is not already being used.

I took the time to go through the various solutions and code for this issue and brainstormed a bit. This solution requires just one for loop and one nested for loop:

var ObjectToInstantiate : GameObject;
var ObjectToPlotOnGrid : GameObject[];
var pointThatHasBeenTaken : Vector2[];


	for(var i=0;i<6;i++) {
		ObjectToPlotOnGrid *= Instantiate(ObjectToInstantiate);*

ObjectToPlotOnGrid_.pixelInset.x = Screen.width/20Random.Range(0,20);
ObjectToPlotOnGrid.pixelInset.y = Screen.width/20Random.Range(0,20);

pointThatHasBeenTaken= Vector2(ObjectToPlotOnGrid.pixelInset.x, ObjectToPlotOnGrid*.pixelInset.y);*_

* for(var ii = 0; ii < i; ii++) {*
if(Vector2(ObjectToPlotOnGrid_.pixelInset.x,ObjectToPlotOnGrid*.pixelInset.y ) == pointThatHasBeenTaken[ii]) {
print(“Rerolling spawn”);
ObjectToPlotOnGrid.pixelInset.x = Screen.width/20Random.Range(0,20);

ObjectToPlotOnGrid.pixelInset.y = Screen.width/20Random.Range(0,20);
ii–;
}
}
}*

In this script:
1) the screen is divided into a 20x20 grid
2) a for loop is iterated from 0-19 plotting random points in that 20x20 grid
3) within that for loop, the nested for loop re-iterates all points already taken before it is plotted_

4) If the nested for loop finds that the point is already taken, it is re-rolled another random roll, and subtracts from the for’s count