Random.Next() Not Working? What am I doing wrong?

Hey guys. I’m trying to randomly spawn enemies on the screen. To do so I’m using System.Random’s Next() method.

Basically what’s happening is that whenever I start up the game in the editor the enemies always spawn in the same position (for me it’s x: 850, y and z: 0). I want the enemies to spawn in different positions. I know creating an instance of System.Random() in the for loop can cause issues like this, but I have my System.Random() instance created in the Start() method. How can I get this to work as intended? Or is it something other than the Random() that might not be working? Obviously there’s some other issues that this code might present, but right now I just want my enemies not all in the same position.

Thanks a ton! Code’s below.

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

[System.Serializable]
public class Enemy {
	public Transform eType;
	public int maxOnScreen;
	[HideInInspector]
	public int onScreen;
	
	public Enemy(){
		 
	}
};

public class SpawnController : MonoBehaviour {
	
	public List<Enemy> enemies;
	tk2dCamera cam;
	
	System.Random rangeCalc;
	
	// Use this for initialization
	void Start () {
		cam = tk2dCamera.inst;
		rangeCalc = new System.Random();
	}
	
	// Update is called once per frame
	void Update () {
		foreach(Enemy enemy in enemies)
		{
			EnemyController eScript = enemy.eType.GetComponent<EnemyController>();
			
			if (enemy.onScreen < enemy.maxOnScreen
				 WhaleController.distance >= eScript.distanceStart)
			{
				Debug.Log("Spawn!");
				spawn ();
			}
		}
	}
	
	void spawn() {
		
		foreach (Enemy enemy in enemies)
		{
			EnemyController eScript = enemy.eType.GetComponent<EnemyController>();
			if (WhaleController.distance >= eScript.distanceStart)
			{
				for (int i = 0; i < enemy.maxOnScreen; i++)
				{		
					int ePosX = rangeCalc.Next(eScript.minX, eScript.maxX);
					ePosX += (int) cam.ScreenExtents.xMax;
					int ePosY = rangeCalc.Next(eScript.minY, eScript.maxY);	
					if (enemy.onScreen < enemy.maxOnScreen)
					{
						Transform newEnemy = (Transform) Instantiate(enemy.eType, new Vector3(ePosX, ePosY, enemy.eType.position.z), enemy.eType.localRotation);
						newEnemy.parent = this.gameObject.transform;
						enemy.onScreen++;
					}
				}
			}
		}	
	}
	
}

Why not just use Random.Range (Unity’s built in Random) ?

I tried that, but it didn’t produce any different results. =S
I figure that’s because it’s a random number generator, and they don’t tend to work well in for… loops, unless instantiated outside the loop which you can’t appear to do with the UnityEngine.Random class.

Someone correct me if I’m wrong though!

There’s nothing special about random number generators, including Random.Range, that would prevent them from working in for loops. There’s no difference at all between using Random.Range in a loop or anywhere else.

–Eric

http://stackoverflow.com/questions/767999/random-number-generator-only-generating-one-random-number

Am I misunderstanding something here then? Also, why do I get the same numbers from the code above then? I’ve had an issue with for… loops doing this to me before and the solution was to move the instantiation of the System.Random() out of the for…loop.

Also does anyone have any solutions for my issue?

One possible problem. new Random() uses a default seed. I know it depends on system’s time but I don’t know what is the precision (seed is an int32). It is possible that you maybe getting the same seed? Try to use a second Random constructor that lets you specify a seed. Maybe try to use GetHashCode of the current object as a seed?

Just use Random.Range, and don’t set the seed.

–Eric

for (int i = 0; i < Slot.Length; i++)
Slot[i].Quantity = Random.Range(0,100);

Gives the value of 23 or 86 for each number.

Nope. (As discussed in your other thread; there wasn’t really any need to necro this one.)

–Eric