code11
code11

Reputation: 2309

Instantiate GameObjects from editor via InitializeOnLoad

I have a programmatically generated board of a certain size. In order to see it, I would normally have to hit run, which is quite annoying and makes it hard to visualize.

Is it possible to make, and thus be able to visualize, the board via InitializeOnLoad?

I gave it a try:

Setup.cs

[InitializeOnLoad]
public class Setup : MonoBehaviour {

    public static Map initialMap;

    static Setup(){
        initialMap = new Map ();
        initialMap.createMap ();
    }
}

Map.cs

public class Map {
    private Tile[,] tiles= new Tile[5,5];
    //I had Resources.Load here, but apparently thats not allowed either...
    public GameObject defaultObj= new GameObject("MyCreatedGO"); 

    public Map (){
        Debug.Log("In Constructor");
    }

    public void createMap(){
        for (int x = 0; x < tiles.GetLength(0); x += 1) {
            for (int y = 0; y < tiles.GetLength(1); y += 1) {
                // Tile Instantiates the defaultObj
                tiles [x, y] = new Tile (defaultObj, new Vector3 (x, y, 0));
            }
        }
    }
}

But unity responded by complaining that

UnityException: Internal_CreateGameObject is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. Called from MonoBehaviour 'Setup' on game object 'Map'.

Is the engine even in a state where it can make objects when the InitializeOnLoad-ed static constructor happens?

If this isn't possible, how are you supposed to visualize a procedurally generated map in Unity?

Upvotes: 1

Views: 1021

Answers (2)

dogiordano
dogiordano

Reputation: 714

You can create a custom editor for your Setup script. You can add a couple of buttons to it like Create and Destroy and, onClick, you can execute every code you want at edit-time as opposed to runtime.

Here's the manual with useful informations on how to execute code in the editor and a video tutorial for writing Editor extensions.

Upvotes: 1

Zapafaz
Zapafaz

Reputation: 41

I'm not sure if Unity can do that, but you can work around it.

Make a width and height variable, then expose them to the editor - either by making them public or by [SerializeField] attribute, and then edit them in the inspector while the editor is running the game. Use those variables for your x and y values in createMap(). Then you'd just have to add a section like this in Update(), to generate a new map on left click:

        if (Input.GetMouseButtonDown(0))
        {
            // call generate map here
        }

Check out this tutorial, too: https://unity3d.com/learn/tutorials/projects/procedural-cave-generation-tutorial/cellular-automata

Upvotes: 1

Related Questions