-1
for(int i = 0; i < gos.Length; i++)
        {
float randomspeed = (float)Math.Round (UnityEngine.Random.Range (1.0f, 15.0f));
    floats.Add (randomspeed);
    _animator [i].SetFloat ("Speed", randomspeed);
        }

Now what i get is only round numbers between 1 and 15. I mean i'm not getting numbers like 1.0 or 5.4 or 9.8 or 14.5 is it logical to have speed values like this ? If so how can i make that the random numbers will include also floats ?

Second how can i make sure that there will be no the same numbers ?

gos Length is 15

TheLost Lostit
  • 505
  • 6
  • 28

3 Answers3

4

As noted in the other answer, you aren't getting fractional values, because you call Math.Round(), which has the express purpose of rounding to the nearest whole number (when called the way you do).

As for preventing duplicates, I question the need to ensure against duplicates. First, the number of possible values within the range you're selecting is large enough that the chances of getting duplicates is very small. Second, it appears you are selecting random speeds for some game object, and it seems to me that in that scenario, it's entirely plausible that once in a while you would find a pair of game objects with the same speed.

That said, if you still want to do that, I would advise against the linear searches recommended by the other answers. Game logic should be reasonably efficient, and in this scenario that would mean using a hash set. For example:

HashSet<float> values = new HashSet<float>();

while (values.Count < gos.Length)
{
    float randomSpeed = UnityEngine.Random.Range(1.0f, 15.0f);

    // The Add() method returns "true" if the value _wasn't_ already in the set
    if (values.Add(randomSpeed))
    {
        _animator[values.Count - 1].SetFloat("Speed, randomSpeed);
    }
}

// it's not clear from your question whether you really need the list of
// floats at the end, but if you do, this is a way to convert the hash set
// to a list
floats = values.ToList();
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • 1
    The op needs to define what he would consider to be the "same number" - that's not necessarily obvious for floats. They might need to specify an application specific `IEqualityComparer`. The other answers suffer from the same problem. Whether a HashSet is indeed helpful would depend on the number of required float values. 15 might not be large enough. – JeffRSon Jul 31 '16 at 08:41
  • @JeffRSon: yes, we've all assumed that for the purpose of this question, "same number" means literally the exact same floating point value. As for using `HashSet`, I think at 15 elements it's likely to produce a real benefit; the compiler threshold for turning a `switch` into a dictionary is much less than that (six or seven, IIRC). But even if the performance advantage isn't there, IMHO the code is far more readable and simple when using a hash set than one of the proposed linear-search solutions. Compare e.g. to the accepted answer, which has 50% more statements, and twice as many loops. – Peter Duniho Jul 31 '16 at 18:59
  • @PeterDuniho: Thanks for your opinion on my answer, the reason I did this while loop was because I knew the while would finish instantly if it got a new number so I didn't consider it bad. And even though I think your answer is highly indept and probably better than mine, you never bothered to explain what your GenerateRandomSpeed function is which makes your answer, imho incomplete. – spatbord Jul 31 '16 at 21:10
  • @spatbord: you're right, I did not copy the method from the other answer that used it. I thought it was obvious, based on the original question, what the method did. But if you feel the answer is better showing how the random number is generated, I don't have any problem changing the answer to suit that opinion. – Peter Duniho Aug 01 '16 at 01:04
3

Your first problem: if you use Math.Round(), you'll never get numbers like 5.4...

Second question: you can check for existance of the number before you add the number:

private float GenerateRandomSpeed()
{ return (float)UnityEngine.Random.Range (1.0f, 15.0f);}


for(int i = 0; i < gos.Length; i++)
    {
     float randomspeed= GenerateRandomSpeed();
     while (floats.any(x=>x==randomspeed)) 
         randomspeed=GenerateRandomSpeed();

     floats.Add (randomspeed);
     _animator [i].SetFloat ("Speed", randomspeed);
    }

I didn't test it but i hope it can direct you to the answer.

Stef Geysels
  • 1,023
  • 11
  • 27
3

The reason you're not getting any decimals is because you're using Math.Round, this will either raise the float to the next whole number or lower it.

As for if it's logical, it depends.As for your case animation speed is usually done by floats because it can smoothly speed up and down.

Also to answer your question on how to avoid duplicates of the same float.. which in itself is already very unlikely, try doing this instead :

for(int i = 0; i < gos.Length; i++)
{
   float randomspeed = 0f;
   // Keep repeating this until we find an unique randomspeed.
   while(randomspeed == 0f || floats.Contains(randomspeed))
   {
       // Use this is you want round numbers
       //randomspeed = Mathf.Round(Random.Range(1.0f, 15.0f));
       randomspeed = Random.Range(1.0f, 15.0f);
   }
   floats.Add (randomspeed);
   _animator [i].SetFloat ("Speed", randomspeed);
}
spatbord
  • 71
  • 6