In the spirit of 7DRL, I’m creating a little roguelike game. I’m instantiating 3D “tile” representation of my randomly generated map and so far there is only 2 types of tiles: floor (0), and wall (everything else). In code below, I’m creating a container object for all these level “tiles” and would like to assign it as a parent for my instantiated level geometry objects.
I have narrowed down the problem to be the line that is commented out in the code. Everything is fine, until I assign a parent to those objects. With that line commented, a normal 100x100 tile map loads in under 1 second, but when I uncomment the line to make it assign the parent object it takes about 15 seconds longer. The reason I’d like to assign parent for these objects is not to have my object hierarchy tab be cluttered by thousands of objects while I run and debug my game within Unity. Is parenting objects just this resource intensive or am I doing something inefficiently? How can I improve the performance while still having non-cluttered hierarchy view in Unity?
private void LoadLevel(DungeonLevel level) {
// TileObjects is an ArrayList of tile data
GameObject LevelContainer = new GameObject("LevelContainer");
Object obj;
List<GameObject> TileInstances = new List<GameObject>();
foreach (KeyValuePair<LevelTileLocation, LevelTile> entry in level.GetTiles()) {
if (entry.Value.TileType == 0) {
// Floor
obj = Instantiate(TileObjects[entry.Value.TileType] as GameObject, new Vector3(entry.Key.y + 0.5f, -0.5f, -entry.Key.x - 0.5f), new Quaternion(0, 0, 0, 0));
} else {
// Wall
obj = Instantiate(TileObjects[entry.Value.TileType] as GameObject, new Vector3(entry.Key.y + 0.5f, 0.5f, -entry.Key.x - 0.5f), new Quaternion(0, 0, 0, 0));
}
TileInstances.Add(obj as GameObject);
}
foreach (GameObject item in TileInstances) {
//item.transform.parent = LevelContainer.transform;
}
}
Added information after more experiments:
- This only happens inside Unity. If I “Build & Run” the game there is no big delay loading the level.
- Reducing map size from 100x100 to 30x30 doesn’t cause the big delay anymore while assigning parent to objects.
- I attached some code to trying to find out exact times. Here’s some data and the script modified to time the delay:
Average results over 10 tests:
- 100x100 map (10000 objects) without assigning parent to objects: ~340ms
- 100x100 map (10000 objects) with assigning parent to objects: ~16700ms
- 30x30 map (900 objects) without assigning parent to objects: ~38ms
- 30x30 map (900 objects) with assigning parent to objects: ~204ms
Modified script to measure the delay:
private void LoadLevel(DungeonLevel level) {
int count = 0;
Debug.Log("--- Starting to load level ---");
System.DateTime start = System.DateTime.Now;
Transform LevelContainer = (new GameObject("LevelContainer")).transform;
Object obj;
foreach (KeyValuePair<LevelTileLocation, LevelTile> entry in level.GetTiles()) {
if (entry.Value.TileType == 0) {
obj = Instantiate(TileObjects[entry.Value.TileType] as GameObject, new Vector3(entry.Key.y + 0.5f, -0.5f, -entry.Key.x - 0.5f), new Quaternion(0, 0, 0, 0));
} else {
obj = Instantiate(TileObjects[entry.Value.TileType] as GameObject, new Vector3(entry.Key.y + 0.5f, 0.5f, -entry.Key.x - 0.5f), new Quaternion(0, 0, 0, 0));
}
//(obj as GameObject).transform.parent = LevelContainer;
count++;
}
System.DateTime stop = System.DateTime.Now;
Debug.Log("Done loading " + count + " level geometry objects in " + (stop - start).TotalMilliseconds + "ms.");
}
Problem is not so noticeable with 30x30 map size but timed test data would seem to indicate that the problem is still there. I think it’s safe to say that major part of the delay is caused by assigning a parent to the objects.