using commands
You can store the result of the execute if entity
subcommand to count how many entities there are and then execute based on that.
You will need a dummy scoreboard objective (let's say count
) and a fakeplayer to store the amount in (let's say $zombies
).
Now we can count the amount of zombies and only summon another one if there are 4 or less zombies in total:
execute store result score $zombies count if entity @e[type=zombie]
execute if score $zombies count matches ..4 run summon zombie
using a spawner block
As @FindAndTonic points out correctly, there is a block in the game that is build for this specific purpose, and we can modify said block to do what we want it to do. It's the spawner
block.
It can be set up in a number of ways, the only important limitation
to keep in mind is that all values are centered around the spawner block itself and that the spawn location is 1 block below to 1 block above the spawner.
Here is an example command that creates a zombie spawner that activates when the player gets in a 16 block radius of it, spawns one zombie every 5 seconds (100 ticks) in a 4 block (square) radius until there are 5 zombies max.
/setblock ~ ~ ~ spawner{SpawnCount:1,SpawnRange:4,MinSpawnDelay:100,MaxSpawnDelay:100,MaxNearbyEntities:5,RequiredPlayerRange:16,SpawnData:{entity:{id:"minecraft:zombie"}}} replace