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.