Take a look at the two classes of a game.
public class Enemy : MonoBehaviour
{
...
if (transform.position.y < _bottomEdge)
{
_horizontalRandom = UnityEngine.Random.Range(_leftEdge, _rightEdge);
transform.position = new Vector3(_horizontalRandom, _topEdge, 0);
}
}
This class Enemy repositions a falling object at the top after it reaches the bottom.
The second class SpawnManager adds a new object every five seconds.
public class SpawnManager : MonoBehaviour
{
...
IEnumerator SpawnRoutine()
{
while (true)
{
_horizontalRandom = UnityEngine.Random.Range(_leftEdge, _rightEdge);
transform.position = new Vector3(_horizontalRandom, _topEdge, 0);
Instantiate(_enemyPrefab, transform.position, Quaternion.identity);
yield return new WaitForSeconds(5.0f);
}
}
}
Running together, there will be more and more falling Enemy objects.
Too many objects
Childed (pronouced child•ed)
From the training:
We can organize these enemies to be instantiated, but then be childed inside of the spawn manager within an enemy container.
(a) Instantiate the object
(b) Get a reference to the object
(c) Assign the parent of the object to, for example, the SpawnManager or whatever the container is.
First define a container for the Enemy objects, an Empty Object with Spawn_Manager as the parent.
Create Empty object under Spawn_Manager
The Enemy Container object will be a place where we can place all our Enemy objects inside of.
Enemy Container object Hierarchy
Code a matching GameObject in the .cs file to work with.
public class SpawnManager : MonoBehaviour { [SerializeField] private GameObject _enemyPrefab; [SerializeField] private GameObject _enemyContainer; ... }
Save and view how added variable appears in Inspector for Spawn_Manager:
![]()
Enemy Container variable in the Spawn_Manager Inspector
Highlight the Spawn_Manager, drag and drop the Enemy Container for coding access.
A Brief Review of Variables
Here are a C# message and a GameObject. Both not accessible:
Debug.Log("5"); Instantiate(_enemyPrefab, transform.position, Quaternion.identity);
Better and accessible when assigned to a variable:
public class SpawnManager : MonoBehaviour ... [SerializeField] private GameObject _enemyContainer; IEnumerator SpawnRoutine(float waitTime) { while (true) { Vector3 posToSpawn = new Vector3(Random.Range(_leftEdge, _rightEdge), _topEdge, 0); GameObject newEnemy = Instantiate(_enemyPrefab, posToSpawn, Quaternion.identity); newEnemy.transform.parent = _enemyContainer.transform; ... } } }
newEnemy is type “GameObject”
something.transform.parent is type “transform”
_enemyContainer is type “GameObject”
_enemyContainer.transform is type “transform”
Before save and run:
… spawned Enemy objects not inside “Enemy Container” in Hierarchy
![]()
Spawning outside of new “Enemy Container”
After save and run:
… spawned Enemy object now inside “Enemy Container” in Hierarchy.
![]()
Spawning inside new “Enemy Container”