I am randomly setting game objects active and inactive in my scene.
How ever sometimes i get the same objects to turn on because random.range gets the same number.
How can I save the previous value so that I can make it full random without repeating the previous combinations of game objects active?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class randomx : MonoBehaviour {
public GameObject[] assets;
public GameObject[] assets2;
public GameObject[] assets3;
private int currentIndex;
private int current2;
private int current3;
void Start(){
//
}
void Randomize() {
// Random range
int newIndex = Random.Range (0, assets.Length);
int newIndex2 = Random.Range (0, assets2.Length);
int newIndex3 = Random.Range (0, assets3.Length);
Debug.Log (newIndex);
//int previous;
//previous = newIndex = Random.Range (0, assets.Length);
// Deactivate old gameobject
assets [currentIndex].SetActive (false);
assets2 [current2].SetActive (false);
assets3 [current3].SetActive (false);
// Activate new gameobject
currentIndex = newIndex;
current2 = newIndex2;
current3 = newIndex3;
foreach (GameObject shapes in assets) {
if (shapes.activeInHierarchy == true)
shapes.SetActive (false);
assets [currentIndex].SetActive (true);
}
foreach (GameObject shapes2 in assets2) {
if (shapes2.activeInHierarchy == true)
shapes2.SetActive (false);
assets2 [current2].SetActive (true);
}
foreach (GameObject shapes3 in assets3) {
if (shapes3.activeInHierarchy == true)
shapes3.SetActive (false);
assets3 [current3].SetActive (true);
}
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.Space)) {
Randomize ();
}
}
}
int newIndex;
do
{
newIndex = Random.Range(0,assets.Length);
}while (newIndex == currentIndex);
Just do the above for all 3 indices. Note because your started with currentIndex,current2, and current 3 as uninitialzied and thus set to 0, the first time through the loop you can never pick Object 0 for any of the 3 things to turn on.
If this is a problem you can fix it in 2 ways:
In Start randomly turn on 3 objects and set currentIndex, current2 and current3 to these objects.
If you need them all to be off to start do something like this:
void Start()
{
currentIndex = -1;
current2 = -1;
current3 = -1;
}
void Randomize()
{
// Code to get New indexes
if (currentIndex >=0)
{
assets[currentIndex].SetActive(false);
assets[current2].SetActive(false);
assets[current3].SetActive(false);
}
// rest of the Randomize code
}
might try 3 million times because of sheer bad luck
smells unpredictable und unstable
Better: ShuffleBag
Create a collection from your source data and shuffle it. Then take out each piece until it is empty. Then handle the special case of refilling, refshuffling and making sure that the first on in the collection is not the last picked one from the previous one. Check out different implementations on the web.
Well its because the idea was to have 3 separate while loops. In your case you only repicking if all 3 indexes happen to hit the last one (which is highly unlikely). You’d need to change those to || (ors). However that is still bad because if even currentIndex == oldIndex then you’d pick all 3 again needlessly. Your best bet if you implement the while implementation is to have 3 separate ones.
That being said we can implement a better solution with something like a ShuffleBag. I’m assuming you don’t actually want to iterate every object at least once before doing it again. That is: 1 4, 2,5,0,3 then start over. Its ok to go : 3,5,2,1,5,3 etc. A ShuffleBag would pick each item once and then restart.
What we can do is this:
void Randomize()
{
int newIndex;
int newIndex2;
int newIndex3;
if (currentIndex < 0)
{
newIndex = Random.Range(0, assets.Length);
newIndex2 = Random.Range(0, assets2.Length);
newIndex3 = Random.Range(0, assets3.Length);
}
else
{
assets[currentIndex].SetActive(false);
assets[current2].SetActive(false);
assets[current3].SetActive(false);
newIndex = Random.Range(0, assets.Length-1);
newIndex2 = Random.Range(0, assets2.Length-1);
newIndex3 = Random.Range(0, assets3.Length-1);
if (newIndex >= currentIndex)
newIndex++;
if (newIndex2 >= current2)
newIndex++;
if (newIndex3 >= current3)
newIndex++;
}
The idea here is say there are 10 objects (0->9). If last time around we picked 5, then currentIndex = 5. So we only choose a number from 0-8. if its 0-4 then we keep that number if its 5-8 we add one to it so we get 6-9. This gives us numbers from 0-4,6-9 skipping 5 which was our last object and we don’t want it.