Skip to content

Instantly share code, notes, and snippets.

@Protonz
Created October 9, 2017 23:56
Show Gist options
  • Save Protonz/2744e3d37170b012d5b9715e773b01f2 to your computer and use it in GitHub Desktop.
Save Protonz/2744e3d37170b012d5b9715e773b01f2 to your computer and use it in GitHub Desktop.
[Rx] Spawn prefabs at pre-defined spawn points. There can be a delay before spawning, then the prefabs can be spawned in batches with a delay between each batch.
using UnityEngine;
using UniRx;
using System;
/// <summary>
/// Spawn prefabs at pre-defined spawn points.
/// There can be a delay before spawning, then the prefabs can be spawned in batches with a delay between each batch.
/// </summary>
public class ListSpawnerRx : MonoBehaviour {
public GameObject[] PrefabList;
public Transform[] SpawnPoints;
public float SpawnDelay = 0f;
public float SpawnRepeatRate = 0.5f;
public int SpawnBatchSize = 3;
struct SpawnEvent {
public long EnemyId;
public GameObject Prefab;
public Transform SpawnPoint;
}
void Start () {
// A Timer that emits a value after the SpawnDelay, then repeats based on the SpawnRepeatRate
// |0---1---2--->
var spawnTimer = Observable.Timer(TimeSpan.FromSeconds(SpawnDelay), TimeSpan.FromSeconds(SpawnRepeatRate));
// Make the spawn timer emit multiple values so that you can spawn multiple enemies per timer tick
// |012---345---678--->
var batchSpawnTimer = spawnTimer
.SelectMany(timerIndex => Observable.Range((int)timerIndex * SpawnBatchSize, SpawnBatchSize));
// A stream of all the prefabs to be spawned
var prefabStream = PrefabList.ToObservable();
// A stream of spawn points that loops so it has enough to handle all the prefabs
var spawnPointStream = SpawnPoints.ToObservable()
.Repeat() // Reuse spawn points if there are more Prefabs than Spawn Points
.Take(PrefabList.Length); // Repeat will infinitely loop and freeze without the Take to limit it
// Create a stream of SpawnEvents by zipping together 3 streams: batchSpawnTimer, prefabStream, spawnPointStream
IObservable<SpawnEvent> spawnEventStream = Observable.Zip( batchSpawnTimer, prefabStream, spawnPointStream,
( timerLoopIndex, prefab, spawnPoint ) => new SpawnEvent {
EnemyId = timerLoopIndex,
Prefab = prefab,
SpawnPoint = spawnPoint
});
// Listen for any Spawn Events and Instantiate the Prefab
spawnEventStream
.Subscribe(e => {
Debug.Log("Spawning Enemy #" + e.EnemyId);
var newGO = Instantiate(e.Prefab);
newGO.transform.position = e.SpawnPoint.position;
}).AddTo(this);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment