Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Adding a GameObject created at runtime to the Scene?

Discussion in 'Editor & General Support' started by brolol404, Jul 2, 2020.

  1. brolol404

    brolol404

    Joined:
    Feb 14, 2015
    Posts:
    21
    tldr: Is it possible to add a GameObject that is created at runtime to the current Scene?

    I created a script that randomly places a GameObject prefab x number of times to the current scene during runtime. Is there a way to “save” these randomly placed prefabs so that when the play button is clicked again to end runtime they do not disappear and instead become permanent GameObjects in the scene?
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Are you looking for an in-game feature, or an in-editor feature?
     
    Joe-Censored likes this.
  3. brolol404

    brolol404

    Joined:
    Feb 14, 2015
    Posts:
    21
    I am looking for an in-editor feature (not for the player) to save myself time placing these objects during development. However, I am open to any solution that will allow me to “save” these GameObjects to the scene.
     
  4. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    Sounds like you want to create an editor script instead. You can use the [MenuItem] attribute to make a function executable in the editor from a component -- put your spawning logic in there. It will create your objects outside of play mode, which can then be saved to the scene.
     
  5. brolol404

    brolol404

    Joined:
    Feb 14, 2015
    Posts:
    21
    Thanks. Once I add the script to an empty GameObject as a component, how do I execute the function in the editor?

    I am getting the following error and I am not sure why:

    Assets\Editor\ResourceSpawner.cs(25,6): error CS0246: The type or namespace name 'MenuItemAttribute' could not be found (are you missing a using directive or an assembly reference?)

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Collections.Specialized;
    5. using UnityEditor;
    6. using UnityEngine;
    7.  
    8. public class ResourceSpawner : MonoBehaviour
    9. {
    10.     public GameObject Resource;
    11.     public int MaxResources;
    12.     public float XSpawnRange1;
    13.     public float XSpawnRange2;
    14.     public float ZSpawnRange1;
    15.     public float ZSpawnRange2;
    16.     private float xPosition;
    17.     private float zPosition;
    18.     private int ResourceCount;
    19.  
    20.     void Start()
    21.     {
    22.         ResourceSpawn();
    23.     }
    24.  
    25.     [MenuItem("Spawn Resources")]
    26.     void ResourceSpawn()
    27.     {
    28.         while (ResourceCount < MaxResources)
    29.         {
    30.             xPosition = UnityEngine.Random.Range(XSpawnRange1, XSpawnRange2);
    31.             zPosition = UnityEngine.Random.Range(ZSpawnRange1, ZSpawnRange2);
    32.  
    33.             Instantiate(Resource, new Vector3(xPosition, 20, zPosition), Quaternion.Euler(0, UnityEngine.Random.Range(0, 360), 0));
    34.             ResourceCount += 1;
    35.         }
    36.     }
    37.  
    38. }
     
  6. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Someone correct me if I'm wrong, but I believe the error in this case is because the script needs to be in an Editor folder, so that it uses the correct editor assembly.
    Your ResourceSpawn method also needs to be static for it to appear as a menu item within Unity.

    Also, last time I checked, you can't use
    Instantiate
    to add prefabs into the scene via an editor utility script, otherwise they just get deleted when you close Unity.
    You might have to use PrefabUtility.InstantiatePrefab instead.
     
  7. brolol404

    brolol404

    Joined:
    Feb 14, 2015
    Posts:
    21
    I think the script is already in an Editor folder (Assets/Editor), but I am not sure how to create another high level "Editor" folder outside of the Assets folder if that is required. I changed Instantiate to PrefabUtility.InstantiatePrefab without any apparent errors; however, after changing the method to static, I now have an error for each variable in the function:

    Assets\Editor\ResourceSpawner.cs(28,16): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.ResourceCount'
    Assets\Editor\ResourceSpawner.cs(28,32): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.MaxResources'
    Assets\Editor\ResourceSpawner.cs(30,13): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.xPosition'
    Assets\Editor\ResourceSpawner.cs(30,50): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.XSpawnRange1'
    Assets\Editor\ResourceSpawner.cs(30,64): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.XSpawnRange2'
    Assets\Editor\ResourceSpawner.cs(31,13): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.zPosition'
    Assets\Editor\ResourceSpawner.cs(31,50): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.ZSpawnRange1'
    Assets\Editor\ResourceSpawner.cs(31,64): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.ZSpawnRange2'
    Assets\Editor\ResourceSpawner.cs(33,45): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.Resource'
    Assets\Editor\ResourceSpawner.cs(33,67): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.xPosition'
    Assets\Editor\ResourceSpawner.cs(33,82): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.zPosition'
    Assets\Editor\ResourceSpawner.cs(34,13): error CS0120: An object reference is required for the non-static field, method, or property 'ResourceSpawner.ResourceCount'


    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Collections.Specialized;
    5. using UnityEditor;
    6. using UnityEngine;
    7.  
    8. public class ResourceSpawner : MonoBehaviour
    9. {
    10.     public GameObject Resource;
    11.     public int MaxResources;
    12.     public float XSpawnRange1;
    13.     public float XSpawnRange2;
    14.     public float ZSpawnRange1;
    15.     public float ZSpawnRange2;
    16.     private float xPosition;
    17.     private float zPosition;
    18.     private int ResourceCount;
    19.  
    20.     void Start()
    21.     {
    22.         ResourceSpawn();
    23.     }
    24.  
    25.     [MenuItem("Spawn Resources")]
    26.     static void ResourceSpawn()
    27.     {
    28.         while (ResourceCount < MaxResources)
    29.         {
    30.             xPosition = UnityEngine.Random.Range(XSpawnRange1, XSpawnRange2);
    31.             zPosition = UnityEngine.Random.Range(ZSpawnRange1, ZSpawnRange2);
    32.  
    33.             PrefabUtility.InstantiatePrefab(Resource, new Vector3(xPosition, 20, zPosition), Quaternion.Euler(0, UnityEngine.Random.Range(0, 360), 0));
    34.             ResourceCount += 1;
    35.         }
    36.     }
    37.  
    38. }
     
  8. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Now that your method is static, you can't use instance variables from your class.
    MenuItems aren't really designed to have configurable settings like you're trying to do here. They're just supposed to be basic one-click actions.

    I think what you want to do instead here is make a custom editor window.
    From there, you can have configurable settings.
     
  9. brolol404

    brolol404

    Joined:
    Feb 14, 2015
    Posts:
    21
    Thanks for all of the help with this, but I discovered how to add GameObjects that are created at runtime to the current Scene using the original code, so I will use that to save time.

    For anyone interested, I discovered that you can copy GameObjects that are created during runtime in the Hierarchy Window and then paste them back into the Hierarchy Window after closing out of runtime.