Need help with a Random Number Generator in Unity C#

Started by
21 comments, last by Lactose 7 years, 5 months ago

Greetings and Salutations!

I am hard at work on a mobile game project for IOS and have come to a crucial portion of development. The procedurally generated levels. My code is functional at the moment but it seems no matter what I try, I cannot get the Level layouts to vary from stage to stage. Ideally I would seed the RNG with the build index number(or another variable that varies stage to stage but is unique to each stage.) I want each stage's layout to appear random upon first encounter, and be the same each time the stage is entered. Below is the code I am using. I am new to RNGs and am in my first year of programming, so definitely a novice. I have read up a bit about seeding, cryptographic RNG and various other techniques but everything I find online is outdated information that no longer works or at least I cannot get it to work in the current version of unity. Oh and as the title says I am using C#. Thank you for your help!

public GameObject asteroid10hp;
public GameObject asteroid20hp;
public GameObject asteroid30hp;

public int chance10hp;
public int chance20hp;
public int chance30hp;
private GameObject chosenGameObject;

void Start()

{
n = UnityEngine.Random.Range(1, 100);
}
void SpawnUntilFull()
{
Transform freePosition = NextFreePosition();
if (freePosition)
{
MoveRandomly();
RandomAngleGen();
if (n <= chance30hp) { chosenGameObject = asteroid30hp; }
else if (n <= chance20hp) { chosenGameObject = asteroid20hp; }
else if (n <= chance10hp) { chosenGameObject = asteroid10hp; }
if (n <= spawnChance)
{
LevelManager.breakableCount += 1;
GameObject destructible = Instantiate(chosenGameObject, (freePosition.position + moved), Quaternion.Euler(0, 0, angle)) as GameObject;
destructible.transform.parent = freePosition;
}
if (NextFreePosition())
{
Invoke("SpawnUntilFull", spawnDelay);
}
}
}
Transform NextFreePosition()
{
foreach (Transform childPositionGameObject in transform)
{
if ((childPositionGameObject.childCount == 0) & (!childPositionGameObject.CompareTag("Attempted")))
{
childPositionGameObject.tag = "Attempted";
return childPositionGameObject;
}
}
return null;
}

Advertisement

I don't know very much about Unity, but I came across some difficulties with random numbers in C# too. Sometimes it generates the same numbers because you create a ton of random numbers during the same millisecond (with time-dependent random generators), or because you use the same seed over and over again, which leads to the same list of numbers.

When do you invoke Start()? When you start the game or when you start the level?

The script in question is attached to the parent of the positional game objects I use to spawn the relevant gameObjects. So it Start() is called at the beginning of each level.

Probably UnityEngine.Random needs seeding with the system time at the start of the game. It might be seeding to a default value which is the same every execution. (The docs are surprisingly vague about this.)

Probably UnityEngine.Random needs seeding with the system time at the start of the game. It might be seeding to a default value which is the same every execution. (The docs are surprisingly vague about this.)

This is my confusion. The docs seem to suggest that it seeds it to the system time but I am getting the same level layout at every level no matter when I load the levels. So it clearly is not doing that in the editor.Thank you, I will see if I can get it seeded with system time.(I'll be back if I can't figure it out)

n isn't global, is it?

EDIT: I haven't seen Kylotan answer. Forget me

I wonder if it's something silly like it using the Editor's start time, as opposed to the time at which you hit Play in the editor. I'd see if setting it yourself somewhere manually would be enough.

There's a seeding function: https://docs.unity3d.com/ScriptReference/Random.InitState.html

Maybe I'm not understanding the question?

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

There's a seeding function: https://docs.unity3d.com/ScriptReference/Random.InitState.html

Maybe I'm not understanding the question?

I actually tried seeding it using that function, no luck yet with that. I'll try setting the seed as the time and see how that goes.

There's a seeding function: https://docs.unity3d.com/ScriptReference/Random.InitState.html

Maybe I'm not understanding the question?

From the documentation it somewhat implies that it already does this: Random.InitState(startupTime) as a default somewhere*. But it doesn't appear to be so, at least according to the OP. I haven't tested it myself.

Even the documentation is kind of hazy:

The seed is normally set from some arbitrary value like the system clock before the random number functions are used.

This topic is closed to new replies.

Advertisement