Instantiating TONS of primitives in editor script

I’ve got myself an editor script here which puts a child object on each tree in a scene, problem is, with many trees (around ten thousand), it freezes the editor. The progress bar says that the generation is going fast, but when it reaches the amount its supposed to generate, it hangs on the last one forever. Here is the editor script.

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;

public class GameManager : MonoBehaviour {

	[HideInInspector] public static List<GameObject> trees = new List<GameObject>();
	public static List<Transform> tempList = new List<Transform> ();
	
	#if UNITY_EDITOR
	[MenuItem ("Modded Shit/+Bake Tree Colliders")] public static void GenerateColliders() {

		float progressBar = 0.0f;
		EditorUtility.DisplayProgressBar("Baking Tree Colliders", "Working...", progressBar);
		
		Terrain terrain = Terrain.activeTerrain;
		TreeInstance[] _originalTrees = terrain.terrainData.treeInstances;

		float hundredPercent = terrain.terrainData.treeInstances.Length;
		int amountDone = 0;

		while (amountDone < hundredPercent) {
			progressBar = amountDone++ / hundredPercent;
			int percentage = (int)(progressBar * 100f);
			string progressStr = amountDone.ToString()+"/"+hundredPercent.ToString();
			EditorUtility.DisplayProgressBar("Placing Prefabs", progressStr, progressBar);
		}
		
		for (int i = 0; i < terrain.terrainData.treeInstances.Length; i++) {
			TreeInstance treeInstance = terrain.terrainData.treeInstances*;*
  •  	GameObject capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule);*
    
  •  	capsule.hideFlags = HideFlags.HideInHierarchy;*
    
  •  	CapsuleCollider capsuleCollider = capsule.collider as CapsuleCollider;*
    
  •  	capsuleCollider.height = 20;*
    
  •  	capsuleCollider.center = new Vector3(0, 10f, 0);*
    
  •  	DestroyableTree tree = capsule.AddComponent<DestroyableTree>();*
    
  •  	tree.terrainIndex = i;*
    
  •  	capsule.transform.position = Vector3.Scale(treeInstance.position, terrain.terrainData.size);*
    
  •  	capsule.tag = "Tree";*
    
  •  	capsule.transform.parent = terrain.transform;*
    
  •  	capsule.renderer.enabled = false;*
    
  •  	//Debug.Log("Created Collider"+capsule.transform.position.ToString());*
    
  •  	trees.Add(capsule);*
    
  •  	amountDone++;*
    
  •  	EditorApplication.Step();*
    
  •  }*
    
  •  // Remove the progress bar to show that work has finished*
    
  •  EditorUtility.ClearProgressBar();*
    
  • }*

  • [MenuItem (“Modded Shit/+Remove Tree Colliders”)] public static void RemoveColliders() {*

  •  Terrain terrain = Terrain.activeTerrain;*
    
  •  TreeInstance[] _originalTrees = terrain.terrainData.treeInstances;*
    
  •  for (int i = 0; i < terrain.transform.childCount; i++) {*
    
  •  	tempList.Add(terrain.transform.GetChild(i));*
    
  •  }*
    
  •  foreach (Transform T in tempList) {*
    
  •  	DestroyImmediate(T.gameObject);*
    
  •  }*
    
  •  tempList.Clear ();*
    
  • }*

  • #endif*

The progress bar is updated all the way to 100% in the while loop, which runs to completion before the for loop begins. So the “fast progress” you see is just a while loop filling up a progress bar before any of the actual work begins - it’s value isn’t based on anything pertaining to the for loop or the processing your script does. The while loop actually serves no purpose - you should place the progress bar code in the same for loop that does the actual work, setting its progress value to (i / terrain.terrainData.treeInstances.Length)