Programmatically creating entities in subscenes at edit time

I’m currently working through several edit time uses cases for our developers to better understand how we can create content that will be used in the new ECS framework. One of those use-cases is “How we can create edit-time content in subscenes like we would for traditional scenes?”.

I have an empty scene and a subscene with a single RandomSpawner MonoBehavior that is creating GameObjects at random within a BoxCollider. The intent is that this mocks up some functionality we might typically do for creating content at edit-time and saved to the subscene that would then be converted to entities upon play.

using System.Collections.Generic;
using System.Linq;
using JCMG.Utility;
using Sirenix.OdinInspector;
using Unity.Entities;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Game.ProcGen
{
    [ExecuteInEditMode]
    public class RandomSpawnerView : MonoBehaviour
    {
        [SerializeField, Required]
        private BoxCollider _collider;

        [OnValueChanged(nameof(Generate))]
        [SerializeField, Required]
        private GameObject _spawnTarget;

        [Min(1), OnValueChanged(nameof(Generate))]
        [SerializeField, Required]
        private int _maxNumberOfObjects = 1;

        [SerializeField, ReadOnly]
        private List<GameObject> _objects;

        private void Update()
        {
            if (transform.hasChanged)
            {
                transform.hasChanged = false;
               
                Generate();
            }
        }

        [Button]
        private void Generate()
        {
            if (_collider == null ||
                _spawnTarget == null)
            {
                return;
            }

            if (_objects.Any())
            {
               // A extentsion method is used to destroy all the gameobjects at edit time in this list.
                _objects.DestroyAll();
            }

            var bounds = _collider.bounds;
            for (var i = 0; i < _maxNumberOfObjects; i++)
            {
                var randomPosition = new Vector3(
                    Random.Range(bounds.min.x, bounds.max.x),
                    Random.Range(bounds.min.y, bounds.max.y),
                    Random.Range(bounds.min.z, bounds.max.z));

                var randomRotation = Quaternion.Euler(
                    Random.Range(0f, 180f),
                    Random.Range(0f, 180f),
                    Random.Range(0f, 180f));

                var obj = Instantiate(_spawnTarget, randomPosition, randomRotation, transform);

                _objects.Add(obj);
            }
        }
    }
}

This functionality works for the most part, especially as the objects being instantiated at edit-time are simple GameObjects (default Boxes). The only part where this runs into errors in the editor that doesn’t appear to be blocking is when I move the RandomSpawner object around which triggers the Transform.hasChanged logic. That seems to cause an error for a background transform job that I assume is a part of the live baking for the subscene.

As a side note Transform.HasChanged seems to be triggered everytime the subscene is loaded which makes it difficult to rely on for content generation like this where I would want a developer moving the transform or otherwise causing it to be moved to be the trigger.

Is there a better way to accomplish what I’m doing here or other considerations I should be taking into account? How can I avoid causing errors like the one shown here?

I suppose you are new to Untiy ECS? If so there are Baker and Baking systems to do this kind of work.
https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/conversion-intro.html