Need help/pointers with enemy spawn/activation system for a scrolling shooter

Hello,
I’m currently making a scrolling topdown shooter (think Gunksmoke, Ikari warriors, Commando etc.) and got most of my code working, so now it’s time to start worrying about putting together a prototype level to see how well it all plays together, and that’s where I’ve run into a problem I would like some advice on.

Background: My programming skills are at an happy amateur level, but I manage to solve most problems I’ve encounter. But when it comes to taking the performance of the code into account I’m a complete beginner, hence this post.

The issue is how to handle the spawning/activation of all the enemy’s, which there will be several hundreds of, in an efficient way. At first I thought that I’d just have each enemy check the distance to camera then activate all it’s components (AI, Pathfinding etc.) but that would be like (lets assume I have 300 enemies per level) 300 function calls per frame. Ok I don’t have to check every frame so I could probably do a timebased solution and check ~4 times per second instead, which would give 1200 calls per second. From my point of view this seems like a lot of unnecessary calls and not to efficient.

So just to muck about I wrote a EnemySpawnManager script that does
enemyList = GameObject.FindGameObjectsWithTag("Enemy"); on level load, then loops through it like

foreach (GameObject enemy in enemyList){
            if (enemy != null) {
                objectPosition = mainCamera.camera.WorldToViewportPoint(enemy.transform.position);
                if (objectPosition.y < 1  objectPosition.y > 0)
                    enemy.gameObject.active = true;
                if (objectPosition.y > 1 || objectPosition.y < 0)
                    enemy.gameObject.active = false;
            }
        }

So now instead of having 1200 function calls per second, I just loop through an array with size 300 every 250ms and enable/disable all enemies depending if they are on screen or not.

But as I really have no idea about how to write efficient code I can only assume that the second solution is better.

This is one of them problems that probably have been solved 1000’s of times, but I’ll be damn if I could find any code examples or unity specific code on how other people solved it (also in a weird state of mind since it’s 6:30 in the morning and I’m running out of energy drinks).

So to anyone that have experience in this, how would you do it? Do I even need to worry about this? I’m familiar with the expression “premature optimization is the devil!!” but as this code will be running a lot in the background I want to be sure that I get it right or get some advice on best practices.

Would appreciate any pointers/advice

Regards,
Arne, one of the most happy elf’s you’ve ever seen!

My suggestion is instead of having 300 objects placed in the scene, you just spawn the ones you need at a particular time, therefore the only check is to find out when to spawn the certain object. An example would be that you want X enemy to spawn every 5 seconds, then you have a check to Instantiate that prefab (ahead of the player I would guess). Saves having to place 300 objects in the scene (especially if you want more than one scene) and then check.

Hopefully that helps.

Perhaps I misunderstand, but wouldn’t I just be checking every spawn position against the timing value and instansiating a gameobject instead of comparing a gameobjects position to camera position then activating it as needed? Seems like this also would be a nightmare from a gamedesign/Balancing perspective as any tweaks to the cameras speed/position you would have to redo every single enemy spawn?

Also:
Enemies, even of the same type, have to be initialized differently depending on stuff like if they are using waypoints before the A* pathfinding kicks in, the trigger sphere radius for getting into attack mode depending on where on map they are placed, number of bullets to fire, time between bullets, distance to keep from player or chase player etc.

The different enemy classes also have to be positioned precisely depending on their intended gamedesign purpose, General cannon fodder for Swarming the player, Dynamite throwers and Shotgun baddies for Area of denial or forcing player to move a certain direction, Snipers with faster bullets for making larger areas more dangerous and keep the player at toes via long range etc.

Okay I should of explained more, or better than what I did above. Right now you are placing a large amount of objects on the scene and deactivating each one then activating once you get near them. This is bad like you mentioned because you have to constantly check when to activate them. So a better solution would be to spawn the ones you want when you want ahead of the player, that means much less objects in the scene, you dont have to place those objects as well and it uses much less processing as well.

You will have to figure out all the different combinations you have there. My tip would be to have the player in a fixed position (say 0,0,0), then have you set locations on where you want to spawn your different enemy types recorded and stored in an array or separate variables. Then you have all your conditions on when you want to spawn your enemy (the hardest part but experimentation will do) then you spawn your enemy at your set position. The changes you have to make is that all your enemies must be moving (if you have fixed one they have to move as well). Having the player fixed save having to move the player and the camera. With speeds and stuff you have variables for that like a global speed variable attached to all moving objects that increase over time. If you want different enemies to spawn at different locations then have all the positions then each time randomly select a position.

Also you say that this would be night mare form a gamedesign and balancing persepctive. well its better than placing hundreds of objects then finding out a whole heap are in the wrong position then having to restart the lot, over and over again compared to changing a few numbers there and then.

Anyways good luck with that.

Had a good nights sleep on it and came up with a simple solution, posting in case this thread pops up in a search sometime in the future.

I’ll just have two box colliders, set to trigger, placed just in front and back of the camera view handle all activation/deletion of enemies via OnTriggerEnter().

Edit I would still love to hear how any one with experience would solve this issue, the box collider solution works fine for my top down shooter but wouldn’t work in a open world /FPS setting where enemy activation is based on line of sight/ camera frustrum or proximity to the player.

Or is it one of them “There is no generally accepted good solution” type problems where one simply has to make one depending on the game your working on?

That’s a nice solution. I was going to suggest triggers, but in a different way. Yours is much cleaner and easier!