|
Post by timmypowergamer on Apr 22, 2015 16:04:25 GMT
Hello, I'm relatively new to Core GameKit and I couldn't find anything about this on these boards, so I thought I would ask: I'm trying to create an enemy spawning "factory" (like the spawners in the game "Gauntlet", where enemies keep coming out until you destroy the spawner). The behavior I am looking for specifically is to have enemies spawn from the factory at a constant rate, until a certain number of enemies is reached, then stop. Once one or more of those enemies is killed, the factory should keep spawning more until the number is reached again. Repeat forever until the factory is destroyed.
I was able to get something close to it by using a triggered spawner with a min/max to spawn of 10, with a 2 second interval between spawns (using some example numbers to keep it simple), and setting the enemies that are spawned from it to respawn indefinitely using the killable script. The only problem is that once you kill any of the enemies, the ones that re-spawn don't respect the 2-second interval. They just show up immediately after they are killed (or after whatever respawn delay I set). What I would prefer is if the enemies that get killed could somehow notify the spawner that it can spawn more, so that the enemies coming out of the spawner always spawn at a constant rate.
Is there a proscribed way of doing something like this with Core GameKit? I figure I could probably subclass the triggered spawner, or use some sort of custom events or something, but I wanted to ask here before I started writing redundant code.
Thanks!
|
|
|
Post by DarkTonic Dev on Apr 23, 2015 0:29:47 GMT
No way out of the box. That's a good workaround you found with the respawn setting of Killable. However they will still continue to respawn even after the spawner is destroyed, so that's not going to work.
Depending on how your spawns move, there's a setting on Syncro Spawners that may do the job. Syncro Spawners have a Spawn Limit Controls section with a "Min. Distance" field. That means you won't spawn a new one until all spawns from the current wave are X units away. Let me know if that works for you.
The problem is that Triggered Spawners don't keep track of what they spawn. It's "fire and forget", so first they would need to be able to do that. I didn't allow that before because keeping track of every single wave type they support could take a lot of memory. I'll put this on the roadmap and make it off by default (not tracking spawns).
If you do end up subclassing Triggered Spawner and get this working, please share the code with me (in case you do it before I get to it).
|
|
|
Post by timmypowergamer on Apr 23, 2015 4:14:35 GMT
Thanks for the response. I had never considered the Syncro spawners before as my game levels are procedurally generated and don't really revolve around waves of enemies, but more exploration. The triggered spawners have a ton of nice features and don't require me to set up all the waves ahead of time. Tomorrow I will look into the Syncro spawners though and see what I can do with that. I suspect I will end up writing something custom though. I'll share whatever I come up with  Either way, you've already saved me a ton of time with just the killables and world variables alone. I've spent many hours making weapon/damage systems on previous projects that have been less robust and not at all portable. So thank you for that. One other quick question, a little off topic: is it possible/advisable to add world vars at run time? Like if I had 2 or more players locally, and I want them to all have their own stats, could I add them as players join the game, or should I just create them all ahead of time for however many players I think I'll support?
|
|
|
Post by DarkTonic Dev on Apr 23, 2015 4:39:48 GMT
There is a "goto wave" command in the API that might be useful for Syncro Spawners, but ultimate I think they won't work for you because they automatically advance to the next wave. There's nothing now to create new World Variables after the Scene has started, but I think it could be added pretty easily. I'll put that on the roadmap near the top  For now I would have you create them all ahead of time.
|
|
|
Post by timmypowergamer on Apr 23, 2015 20:56:47 GMT
Here's what I came up with today. I ended up being able to do it with just a Killable Listener. I set up my spawners to just spawn 1 enemy per wave, but to repeat the wave X number of times. When I put the listener on the enemies spawned from it, on their death they automatically increment the repeat value on the spawner (for whatever event type I specify). It's pretty much tailored to my specific use case right now, but I'm sure it could be made to modify any number of wave parameters fairly easily. I might work on making it more robust later, but for now it solves the problem nicely. using UnityEngine; using System.Collections; using DarkTonic.CoreGameKit;
public class RepeatWaveOnDeath : KillableListener {
public TriggeredSpawner.EventType eventToModify = TriggeredSpawner.EventType.OnEnabled; public string customEventName = "";
public override void DestroyingKillable (Killable deadKillable) { base.DestroyingKillable (deadKillable);
if (deadKillable.SpawnedFromObject != null) { TriggeredSpawner spawner = deadKillable.SpawnedFromObject.GetComponent<TriggeredSpawner>(); if (spawner != null) { TriggeredWaveSpecifics waveData = GetWaveSpecifics(spawner, eventToModify, customEventName); if (waveData != null) { waveData.maxRepeat.Value++; } } } }
/// <summary> /// Helper for easily retrieving TriggeredWaveSpecifics by the EventType enum /// </summary> /// <returns>The wave specifics.</returns> /// <param name="spawner">A TriggeredSpawner</param> /// <param name="eType">Wave type to retrieve</param> /// <param name="customEventName">Custom event name if using a custom event.</param> public TriggeredWaveSpecifics GetWaveSpecifics(TriggeredSpawner spawner, TriggeredSpawner.EventType eType, string customEventName) { switch (eType) { case TriggeredSpawner.EventType.OnEnabled: return spawner.enableWave; case TriggeredSpawner.EventType.OnDisabled: return spawner.disableWave; case TriggeredSpawner.EventType.Visible: return spawner.visibleWave; case TriggeredSpawner.EventType.Invisible: return spawner.invisibleWave; case TriggeredSpawner.EventType.MouseOver_Legacy: return spawner.mouseOverWave; case TriggeredSpawner.EventType.MouseClick_Legacy: return spawner.mouseClickWave; case TriggeredSpawner.EventType.OnCollision: return spawner.collisionWave; case TriggeredSpawner.EventType.OnTriggerEnter: return spawner.triggerEnterWave; case TriggeredSpawner.EventType.OnTriggerExit: return spawner.triggerExitWave; case TriggeredSpawner.EventType.OnSpawned: return spawner.spawnedWave; case TriggeredSpawner.EventType.OnDespawned: return spawner.despawnedWave; case TriggeredSpawner.EventType.CodeTriggered1: return spawner.codeTriggeredWave1; case TriggeredSpawner.EventType.CodeTriggered2: return spawner.codeTriggeredWave2; case TriggeredSpawner.EventType.OnClick_NGUI: return spawner.clickWave; case TriggeredSpawner.EventType.OnCollision2D: return spawner.collision2dWave; case TriggeredSpawner.EventType.OnTriggerEnter2D: return spawner.triggerEnter2dWave; case TriggeredSpawner.EventType.OnTriggerExit2D: return spawner.triggerExit2dWave; case TriggeredSpawner.EventType.SliderChanged_uGUI: return spawner.unitySliderChangedWave; case TriggeredSpawner.EventType.ButtonClicked_uGUI: return spawner.unityButtonClickedWave; case TriggeredSpawner.EventType.PointerDown_uGUI: return spawner.unityPointerDownWave; case TriggeredSpawner.EventType.PointerUp_uGUI: return spawner.unityPointerUpWave; case TriggeredSpawner.EventType.PointerEnter_uGUI: return spawner.unityPointerEnterWave; case TriggeredSpawner.EventType.PointerExit_uGUI: return spawner.unityPointerExitWave; case TriggeredSpawner.EventType.Drag_uGUI: return spawner.unityDragWave; case TriggeredSpawner.EventType.Drop_uGUI: return spawner.unityDropWave; case TriggeredSpawner.EventType.Scroll_uGUI: return spawner.unityScrollWave; case TriggeredSpawner.EventType.UpdateSelected_uGUI: return spawner.unityUpdateSelectedWave; case TriggeredSpawner.EventType.Select_uGUI: return spawner.unitySelectWave; case TriggeredSpawner.EventType.Deselect_uGUI: return spawner.unityDeselectWave; case TriggeredSpawner.EventType.Move_uGUI: return spawner.unityMoveWave; case TriggeredSpawner.EventType.InitializePotentialDrag_uGUI: return spawner.unityInitializePotentialDragWave; case TriggeredSpawner.EventType.BeginDrag_uGUI: return spawner.unityBeginDragWave; case TriggeredSpawner.EventType.EndDrag_uGUI: return spawner.unityEndDragWave; case TriggeredSpawner.EventType.Submit_uGUI: return spawner.unitySubmitWave; case TriggeredSpawner.EventType.Cancel_uGUI: return spawner.unityCancelWave; case TriggeredSpawner.EventType.CustomEvent: // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < spawner.userDefinedEventWaves.Count; i++) { if (spawner.userDefinedEventWaves[i].customEventName == customEventName) { return spawner.userDefinedEventWaves[i]; } } return null; default: Debug.Log("Unknown event type: " + eType.ToString()); return null; } } }
Feel free to do what you will with it 
|
|
|
Post by DarkTonic Dev on Apr 23, 2015 23:45:49 GMT
Cool job I'll do something a little simpler to implement (no coding probably) when I get to this on the roadmap.
|
|
|
Post by DarkTonic Dev on Jan 22, 2018 1:06:03 GMT
Update: Triggered Spawners now have elimination waves as of today's update!
|
|