#Wave Spawn Logic

1 messages · Page 1 of 1 (latest)

quasi igloo
#

I'm finding it difficult to put my finger on/verbalize... A lot of it is probably highly subjective and/or unnecessary optimization - if it works as it is, then it works 😁

I try to omit as much work as possible from FixedUpdate() - and none of this code is relevant to the physics step, so I probably wouldn't be doing any of it in FixedUpdate(). Basing the cooldowns on times instead of ticks would guarantee consistency (plus or minus one "update"). You could also treat cooldowns as "time at which cooldown ends" to get rid of the loop to decrement cooldowns each update.

Pulling out wave logic into coroutines would avoid a bunch of extra processing/logic/allocations when nothing's actually happening. Using coroutines to handle cooldowns would allow you to maintain a single availableSpawnPoints list instead of reallocating and recalculating it every update, and do away with setting and checking cooldown timers altogether.

availableSpawnpointsIndex is a bit counterintuitive, because you could just use a List<SpawnPoint> instead and avoid all the index accessors later.

The hard-coded switch in GetAssociatedEnemy() could probably be done away with using a Dictionary<ENEMY, Enemy> - which could even eventually be exposed through the inspector through a list, or just constructed from the Enemies array, if Enemy having a ENEMY field would make sense.

Using strings for any internal logic which isn't exposed to the player is often best to avoid, as string comparisons aren't terribly fast - I might try to avoid using Enemy.Tag as an identifier or index if possible.

But again, this is all probably subjective and unnecessary. Just food for thought 👍

graceful laurel
#

Yo Thanks for elaborating haha I think I changed everything like you suggested this is current code https://hst.sh/dowiqeboha.csharp tho im not sure what u meant by coroutines how I would use them? I need distinct cooldown for every single spawn point enemy sizes will vary and they will deliver different cooldown timers when spawned, spawnpoints cant act as a single unit. Also im quite rusty coming back year later so couldnt really ditch repeated allocation of List<Spawnpoint> (well I could but ended up with 2 loops idk which is worse)

#

maybe you got a clue how I could change selection of enum into enemy class here if I can get red box show up in yellow I can ditch dictionary and enum altogether aka Enemy class in Inustructions Enemy box

quasi igloo
# graceful laurel Yo Thanks for elaborating haha I think I changed everything like you suggested t...

I need distinct cooldown for every single spawn point enemy sizes will vary and they will deliver different cooldown timers when spawned, spawnpoints cant act as a single unit. Also im quite rusty coming back year later so couldnt really ditch repeated allocation of List<Spawnpoint>

This doesn't quite mesh with your current implementation, but in my head was thinking something sort of along the lines of

List<SpawnPoint> _availableSpawnPoints;
WaitForFixedUpdate _waitForTick = new();

void Awake() {
  // Initialize the available list to all spawn points
  _availableSpawnPoints = new(SpawnPoints);
}

bool SpawnEnemy( Enemy enemy ) {
  if (_availableSpawnPoints.Count == 0)
    return false; // Indicate that the enemy could not be spawned

  var randomSpawnPointIndex = Random.Range( 0, _availableSpawnPoints.Count );
  var spawnPoint = _availableSpawnPoints[ randomSpawnPointIndex ];

  // Remove the selected spawn point from the available pool and start the cooldown.
  _availableSpawnPoints.RemoveAt( randomSpawnPointIndex );
  StartCoroutine( SpawnPointCooldown( spawnPoint, enemy.TicksForSpawnPointCooldown ) );
  
  // ... additional enemy initialization logic

  return true; // Indicate that the enemy was spawned successfully (so whatever spawn loop can continue on to the next)
}

IEnumerator SpawnPointCooldown( SpawnPoint spawnPoint, int ticks ) {
  // Wait for *ticks* fixed updates. (Alternately, if time-based, no loop would be required)
  for (int i = 0; i < ticks; i++)
    yield return _waitForTick;

  // Return the spawn point to the available pool after cooldown.
  _availableSpawnPoints.Add( spawnPoint );
}

In this fashion, you no longer need spawn points to keep track of how long they've been on cooldown, perform any checks to see if a spawn point is available to use, or keep rebuilding the available list. Instead the available list is just updated whenever appropriate, so it always reflects just those spawn points which are ready to use