Difficult logic: respawn a target when each target falls out of view, destroyed, or when each target is destroyed after a hit to the Player.
Easier logic: ignore targets after Instantiation, and respawn new targets after a fixed or random time period.
Create an Empty Object to contain the manager script code.
Create Empty to hold script
The new Spawn Manager is a GameObject with components
Spawn_Manager GameObject
Mouse over to the Scripts folder in the Project window and right click to create a new C# Script.
Created SpawnManager in Scripts folder
Drag and drop the script onto the Spawn_Manager GameObject in the Hierarchy.
Script now included in GameObject
How to Instantiate and Delay
Coroutines allow pauses in an object’s function, to wait.
From the Unity manual:
Coroutines
A coroutine allows you to spread tasks across several frames. In Unity, a coroutine is a method that can pause execution and return control to Unity but then continue where it left off on the following frame.
…
In situations where you would like to use a method call to contain a procedural animation or a sequence of events over time, you can use a coroutine.
Here is a C# method of type “void” with a “null return” (not a coroutine, no slow motion):
void myMethod()
{
...
return;
}
Here is a coroutine of “type IEnumerator” with a “yield return null” from the manual:
IEnumerator Fade()
{
Color c = renderer.material.color;
for (float alpha = 1f; alpha >= 0; alpha -= 0.1f)
{
c.a = alpha;
renderer.material.color = c;
yield return null;
}
}
The IEnumerator combined with the yield can hold up the Unity Update loop for a few steps.
MonoBehaviour.StartCoroutine
Declaration
public Coroutine StartCoroutine(IEnumerator routine);
Description
Starts a Coroutine.
The execution of a coroutine can be paused at any point using the yield statement. When a yield statement is used, the coroutine pauses execution and automatically resumes at the next frame.
public class SpawnManager : MonoBehaviour
{
private IEnumerator coroutine;
void Start()
{
Debug.Log("starting coroutine");
coroutine = SpawnRoutine(5.0f);
StartCoroutine(coroutine);
}
...
IEnumerator SpawnRoutine(float waitTime) // 5 seconds
{
while (true)
{
yield return new WaitForSeconds(waitTime); // 5 seconds
Debug.Log("waiting" + Time.time); // elapsed time
}
}
}
(a) “private IEnumberator cotoutine” is outside the methods.
(b) WaitAndPrint(2.0f); and StartCoroutine( … ) are called inside “void Start(){ … }”;
(c) “yield return new WaitforSeconds(waitTime);” is inside infinite loop inside the IEnumerator declaration
(d) Example class “SpawnManager” is an added component C# Script added to a create empty object “Spawn_Manager” in the Hierarchy list.
Example game run with coroutine messages
Managing a GameObject
(a) Create [Serialize] private GameObject _enemyPrefab;
(b) run and address “UnassignedReference…” exception
Enemy Prefab unassigned
Highlight the Hierarchy Game Span_Manager and Drag the Project Assets Prefabs Enemy to the “None (Game Object…” in the Inspector.
Enemy Prefab assigned
(c) Add the Instantiate(…) code
public class SpawnManager : MonoBehaviour
{
...
IEnumerator SpawnRoutine(float waitTime)
{
while (true)
{
// instantiage Enemy
_horizontalRandom = UnityEngine.Random.Range(_leftEdge, _rightEdge);
transform.position = new Vector3(_horizontalRandom, _topEdge, 0);
Instantiate(_enemyPrefab, transform.position, Quaternion.identity);
yield return new WaitForSeconds(waitTime);
}
}
}