Making sure enemies spawn at a point that isn't one of the last 2

Hello! Back again with what (I hope) is another simple question that I’m just struggling to wrap my head around.

I’ve set up a system so that when the level starts, there’s a short delay and an enemy spawns. Once that enemy dies, it calls a custom event to spawn more enemies. The basics all work fine (enemies spawn as anticipated), but I’m trying to implement logic so that I can store the locations of the last 2 spawn points used and make sure the next spawn used isn’t either of those spawn points. At the same time, I’ll need to replace one of the values to continuously reflect only the most recent two spawn point locations.

I’ve attached the spawning portion of the BP (same basic script is duplicated for the continued spawn) and hoping someone can point in the right direction as to where to go from here. Pretty sure I’m missing something easy in flow control, but open to suggestions.

In my experimentation, this is where I’ve landed for now, but I have yet to test it and looks as though it’s missing something. Will update post if I succeed.

There are many ways to do this, but here’s a robust one and how I would do it.

  1. Create your own SpawnPoint BP and use that instead of Target Points.

  2. Get all your spawn points.

  3. Pick a random one that is not on cooldown and spawn your dude, and then set that spawnpoint on cooldown

  4. Lower the cooldown of all spawn points

Here’s how you accomplish this.

Step 1:
Create your own spawn point blueprint by creating an Actor blueprint, and add a “Cooldown” int variable to it (with a default value of 0). You can add a Billboard to it if you want and customize the image so its easier to see in your level.

Step 2: In your Level BP, create 3 variables of the type of your new SpawnPoint BP. Make two of them arrays. Here’s an overview of the full thing. It may look more complex than what you had, but it’s a lot more versatile and solid.

Step 2a: Get all your SpawnPoints and store them in AllSpawnPoints.

Step 3: First we clear the ValidSpawnPoints array since you will be calling this function more than once and you want to start clean. ValidSpawnPoints will hold the spawn points that are currently not on cooldown. We discard points that have a cooldown value higher than 0, and put the “valid” ones in ValidSpawnPoints. We then get a random one from the Valid array and spawn our dude from there. Lastly, we trigger that spawnpoint’s cooldown and trigger the cooldown lowering on all the spawnpoints.

The highlighted node there is crucial, since we need to access the randomly-picked item more than once (once to get its transform, once to trigger its cooldown). Every time you “pull” from the Get node in this setup, it will re-run everything that is attached to its inputs. That means the Random Int In Range return value will change (it’ll re-roll the dice) and there’s a high chance it will actually return a different spawnpoint the second time you access it. Hope that makes sense. This is a common mistake when using the Random Int/Float/Bool nodes. By saving it to a variable and then using that variable after that, we make sure we are always accessing the same item.

Step 4: Lower the cooldown on all your spawnpoints.

At this point, when you want to spawn more dudes, just call the SpawnStuff function again. There’s no need to duplicate functionality and it’s a bad practice in general.

Wow! Did NOT expect that concise and informative an answer! I’m away from the project for tonight, but that certainly looks like a very elegant and robust solution indeed. Will implement and verify tomorrow and mark the answer if I don’t manage to come up with anew issue along the way.

Either way, THANK YOU JParent!

OK, so I might have gotten anxious and implemented that tonight LOL. Thus far, it looks like I’ll have to tweak a little bit to accommodate a continuous spawn cycle, but that I can manage.

The only question I had is about the cooldown reduction. If I’m reading this right, the cooldown value is reduced by 1 on all of the spawn points (within clamped range) each time the lower cooldown event gets called. This is actually perfect for a continuous spawn sort of situation like I’m planning on setting up tomorrow, I’m just asking to make sure that I’m understanding the function of the ForEachLoop properly.

Thanks so much for your time and assistance, this is a massive help for me, JParent!

Yeah that’s what it’s doing. I’m clamping it so that it doesn’t reduce the cooldown of spawnpoints that are already at 0.