Hard to grasp the code in this lecture

Well, i’ve been staring at this for a day now and I can’t say that I understood how it works.

I understand that it basically gives the enemies a chance to spawn and it set the fox to 10% and the lizard to 20%, but how exactly does it work? how many times does the Random.value produce a value? every frame? and beyond that, I think that I generally don’t really get how Time.deltaTime works now that I think about it.

I presume that your main issue is with the IsTimeToSpawn function:

bool IsTimeToSpawn(GameObject attackerGameObject)
    {
        Attacker attacker = attackerGameObject.GetComponent<Attacker>();
        float meanSpawnDelay = attacker.seenEverySeconds;
        float spawnsPerSecond = 1 / meanSpawnDelay;

        if (Time.deltaTime > meanSpawnDelay)
        {
            Debug.LogWarning("Spawn rate capped by frame rate");
        }

        float threshold = spawnsPerSecond * Time.deltaTime / 5;

        if (Random.value < threshold)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

So let’s break it down.
First we get the Attacker component of the prefab we passed in as a public variable:

Attacker attacker = attackerGameObject.GetComponent<Attacker>();

This allows us to get to its public seenEverySeconds variable, for which we make a new local variable called meanSpawnDelay:

float meanSpawnDelay = attacker.seenEverySeconds;

But what we want is the spawn rate, or the number of times this attacker spawns per second, which is just the inverse of the spawn delay:

float spawnsPerSecond = 1 / meanSpawnDelay;

Now the interesting part. We define a threshold

float threshold = spawnsPerSecond * Time.deltaTime / 5;

Time.deltaTime gives us the time since the last frame (so at 60 fps, it is 1/60th of a second). Multiply that by the times we spawn an attacker every second (let’s say 1/10 for an attacker every 10 seconds), and we get the probability that an attacker will be spawned this frame (1/600). Then we divide that probability by the number of spawners in our scene, so that 1 of those attackers spawns on average every 10 seconds overall.

Finally, we compare that probability to a random value. If the probability is 0.5, there is a 0.5 chance that a random value will be lower than it. If it is 1/3000, there is a 1 in 3000 chance that a random value will be lower than it, etc. So we simply say, at every frame, if that random value is lower than our calculated probability, spawn an attacker.

if (Random.value < threshold)
{
     return true;
}
else
{
    return false;
}
6 Likes

@Sebastian_Martens you have done a great job of breaking it down, but i find myself one more example away from really getting this. Where i get really confused right at the

float meanSpawnDelay = attacker.seenEverySeconds;
doesn’t this mean we are setting this new float variable to equal the public variable (let’s say 7). How is that possible when a float can only equal a number between 0 and 1? but moving on

float spawnsPerSecond = 1 / meanSpawnDelay;
this would mean spawnsPerSecond equals 1/7 or 0.14285714285 yes?

float threshold = spawnsPerSecond * Time.deltaTime / 5;
ok so the math i’m getting here is threshold equals 0.14285714285 * (1/60) = 0.00238095238 / 5 = 0.00047619047 for the threshold

if (Random.value < threshold)
{
     return true;
}
else
{
    return false;
}

now this random.value just pumps out a number between 0 and 1 every frame? then we compare to 0.00047619047 (threshold) and so now there is a big chance for the number to return false (because the current threshold is very close to 0). I’m more confused because it seems like higher seenEverySeconds would yield a lower threshold. Meaning that it would spawn less (unless i flipped Random.value < threshold)

would appreciate any help i could get. really didn’t want to be tripped up on the math here and wanted to make improvements once i can wrap my mind about what is going on currently

1 Like

Hi William,

A float variable can take any decimal value between -3.4 x 10^38 and +3.4 x 10^38, with a precision of 7 digits (see this link for reference).

But yes, you’re correct on the math. The value of the threshold is very low because we are doing the Random.value < threshold test very frequently (60 times per second at 60fps, and we only want 1 spawn every 7 seconds). And if we want a lower spawn rate, let’s say a meanSpawnDelay of 14 seconds, then our threshold will have to be twice as low.

The basic idea to understand here is that Random.value will give any value between 0 and 1 with equal probability. Our test simply puts a cut-off point where the ratio of values that are below it to the total values equals the probability we want.

If we stick with our 1 spawn every 7 seconds, 60 fps, 5 spawners example, the probability that an enemy will spawn at any spawner during any given frame is 1/(7 x 60 x 5) = 1/2100. So our cut-off point is where there are 2100 times as many values in total as there are below it. That point, conveniently, is 1/2100, or 0.00047619047.

Let me know if I’m still not clear, I confused myself typing this, hence the number of edits I had to do :slight_smile:

2 Likes

Hi there,

I am also having a lot of trouble trying to understand the code from this lecture. I run into trouble with the meanSpawnDelay. We do not declare what the meanSpawnDelay is and it is also not in the inspector. I thus have no idea what this value even equates to or how it is used in the equation. Also if I do not understand meanSpawnDelay I now also do not understand spawnsPerSecond = 1 / meanSpawnDelay.

Please any clarification into this code and specifically the meanSpawnDelay would be greatly appreciated.

Tim

I kind of understand what the code is saying, however, it most definitely has no impact on what happens for me! it doesnt matter what value I add into the “seen every seconds” variable in the inspector, the same number are spawned, i.e. ridiculous numbers of.

Anyway, if this helps:

We set the variable Float meanSpawnDelay to be the value in the inspector, seen every seconds.
float meanSpawnDelay = attacker.seenEverySeconds;

We then create another float, of spawnsPerSeconds as 1/meanSpawnDelay, so if we put some numbers in there: spawnsPerSeconds = 1 / 5 (1 over the number in the inspector) so spawnsPerSeconds = 0.2

We then want to check if the spawnsPerSeconds is more than the frame rate, and the frame rate is set by Time.deltaTime, hence the next if statement.

However, on the whole, I am a little lost as to why we would even do that If statement, given that the meanSpawnDelay is Set as the variable in the inspector. This makes no sense to me.

Privacy & Terms