Everytime the Player comes to the end of a level i load random a new terrain. The problem is sometimes it loads the same terrain again. Can someone tell me how i can stop this repeating?
var TerrainArray = new Array("Terrain1","Terrain2","Terrain3","Terrain4","Terrain5","Terrain6");
function LoadStuff(){
var newTerrain : GameObject = Instantiate(Resources.Load(TerrainArray[Random.Range(0, TerrainArray.length)]));
newTerrain.transform.position = Vector3(0, 0, 0);
}
var terrain;
var currentlyLoadedTerrain;
while ((terrain = TerrainArray[Random.Range(0, TerrainArray.length)] )== currentlyLoadedTerrain);
//loadmap(terrain);
static function RandomDifferent( var lastChoice : int, var length : int ) : int {
if( lastChoice == -1 ) return Random.Range(0, length );
else if( length > 1 ) {
var choice :int = Random.Range(0, length - 1);
if( choice >= lastChoice )
return choice + 1;
else
return choice;
}else { return lastChoice; }
}
then you just want to use that function like this.
var TerrainArray = new Array("Terrain1","Terrain2","Terrain3","Terrain4","Terrain5","Terrain6");
var lastPick : int = -1;
function LoadStuff(){
lastPick = RandomDifferent( lastPick, TerrainArray.length );
var newTerrain : GameObject = Instantiate(Resources.Load(TerrainArray[lastPick]));
newTerrain.transform.position = Vector3(0, 0, 0);
}
while the while statement works, its bad because you could end up looping through it a ton if your array is small. This does a random range - 1 and if the values greater than the last pick it adds one, so it wlll not output the same value twice
Not really - even if you’ve only got two elements you’ve got a 50% chance of picking the right one. After 10 attempts that is: 0.0009765625 probability of NOT picking the odd one Given it’s just simple string comparisons (or if you wanted to optimize you could easily just use the int index as you did) you should be able to do tens or hundreds of millions of these a second.
(Just noticed a small error forgetting to -1 from the length of the array… fixing…)
And of course, mine has a far more even distribution than yours does
Of course… if you give me an array of only one element…
Anywho - I’d recommend OP to go with yours - it’s much more explicit about what it’s doing, which is good for a newbie.
Hey, Actually you’ve got alot better chances of hitting the same element if your array is smaller. Sure its unlikely to get it ten times though, but with a 2 sized array, if your updating it 10 times seperately, it could loop like 5 times if you go with 50 percent. Its just unstable though.
But i mainly wanted to say you do not want to do -1 off of yours. This is one thing thats very annoying about the poisonous int and float overload of Random.Range, when both parameters are ints the second parameter is exclusive, and when any parameter is a float the second parameter is inclusive. So you had your code right.
With that said though, my approach when were talking about even distribution its more solid in that case too. If your under the impression that numbers you get out of Random are evenly distributed, calling Random functions multiple times where its not needed would result in un-even distribution. But the argument here is really not valid with the Random class in general, mainly because its not something you can use and expect even distribution because in most cases a ton of things are going to use it at the same time and not in the same context.
If you look at what i’m doing, i’m basically treating the array as if it lost the index. so if i first picked throguh a array of 8 elements, picked the 5th one the next time i would pick from 7 indexes ( 0-6 ) and if i hit the 5th one or 6th above i would add one turning the 5th into the 6th and the 6th into the 7th. in the case of first picking the last element index theres no chance of picking it again because i’m doing the length -1.
With all that said though, Random is a really bad feature of unity in general not just because of the poisonous overload on Range, but also its got no context. So while its a horrible thing to rely on context sensitive things, it still does its job for things you wouldnt really care about. But for other stuff you should really use System.Random and make a instance of it where you need to context wise
Great to see activity though, and i dont want to come off as a know it all i’m just defending what i posted which you can understand i’m sure. Its not just for newbs, its the way you would go about doing it properly, without wasting recursion/looping.
Which is why I explicitly gave a length = 2 example as well as stating length =1 will be bad
It’s not ‘unstable’ just a tad bit random. Once again, put it into context. This is an even that will occur once a level - say 5 minutes between calls? My code should not take more that a few ns to execute. Speed isn’t an issue in fact it could be faster than yours :P)
Bah - explains why I didn’t do it originally.
Err… by design the random class should be evenly random no matters what you do with it - other than deliberate filtering etc.
Reread your code with my mind refreshed about Random.Range - yep, perfect.
Especially after the whole Random.Range thing has cleared up I’m very much in favor with your method. I might be lazy and use mine, but that’s because I know the risks
Yea theres definitely places where its okay to be less efficient but its never ‘good’. Like in a Start or Awake of something thats generally not used more than a couple of times per level load or less.
Maybe unstable was a little much ( other than the case of 1 sized array ) but my main beef with it is that it calls something more than it should and it has weird constraints with given data. But yea its stable the way you have it but, something i would avoid in order to maintain control of at least my script, as i have only ideas of whats going on internally on any unity functions.
The only way to have the random class evenly random would be if you only used it in one spot of your code for one thing. But i mean it not being even works most of the time, and you’d use System.Random for cases where you needed (somewhat) evenly random things. Like seeded level generation.
In all reality its probably fine for you to continue using it ( as long as you have no array size 1s ) and this really isn’t probably a common issue to run into, though if you were making a game entirely based off picking something randomly but skipping one and doing it often thats a different story
Look at it from the stand point of a deck of cards.
var deck : Array;
var cards : Array;
function Start(){
Reset();
}
funciton Reset(){
deck = new Array();
// fill the deck
for(var i=0; i<52; i++){
deck.Add(i);
}
cards = new Array();
// get a random order
for(i=0; i<52; i++){
var r : int=Random.value * deck.length;
cards.Add(deck[r]);
deck.RemoveAt(r);
}
// show the results
for(i=0; i<52; i++){
Debug.Log(cards[i]);
}
}
The basics are that you fill an array normally, then one at a time, pick one out of that array, and add it to another array. This works with Arrays, ArrayLists and Lists. Unfortunately, it does not work with object arrays.
Yea didn’t think to use a shuffler. That would probably be the fastest at runtime for sure. Though, if he wants to reselect things except for the last selection its not super ideal