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.

Adding objects to the scene at Start using an editor script

Discussion in 'Scripting' started by mstevenson, Mar 11, 2011.

  1. mstevenson

    mstevenson

    Joined:
    Sep 24, 2009
    Posts:
    189
    I'd like to create an editor script that enters play mode and creates a non-persistent GameObject in the scene. I'm having trouble finding a way to create an non-persistent object that isn't destroyed as soon as play mode begins.

    Here's what I've tried:
    1. Set Application.isPlay to true then immediately create a game object. The game object is permanently added to the scene even after play mode stops.
    2. If, in addition to #1, the object's HideFlags is set to DontSave, the object is destroyed before Awake is ever called.
    3. If the object is created using an EditorApplication.playmodeStateChanged callback method, the object survives into play mode, but none of Unity's built-in events (such as Update) are called on any of its components (?!)

    The most obvious solution would be to yield the editor script and wait for Start during play mode, then create the object, but I've found no way to yield in the editor or to pass relevant runtime information back to an editor script. The object that I'm creating is time-dependent, so I'd like to create it before or during Start, if at all possible.

    Thanks!
     
    Last edited: Mar 11, 2011
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Editor scripts normally don't run in the games environment and it makes not so much time that you try it either as it will not exist outside the editor.

    Question is what you want to achieve in detail to lead you a better way to achieve the what you are looking to do.
     
  3. mstevenson

    mstevenson

    Joined:
    Sep 24, 2009
    Posts:
    189
    I'm building a game recorder that consists of two parts: capturing the state of selected objects every x seconds and serializing to disk, and reading the recorded state changes and playing them back while capturing a series of screenshots that will later be compiled into a movie.

    It's all controlled from a single editor window, and I'd like to avoid permanently modifying the scene when using the recorder. I'd prefer to do all of this completely in an editor script, but since both parts of my system rely on Update() I figure the best approach is to have the editor script silently create hidden non-saved components in the scene to do the heavy lifting.
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Sounds like this is something you primarily want to do with game scripts, with a editor script only talking to this "movie taking manager script" within the game actually as you are primarily relying on game mode with the editor part doing barely nothing.

    Doing this is pretty easy. just make your editor start and stop play mode and before you start it, add the game object / prefab responsible for the movie taking and keep track of it.
    when the editor script ends play mode, remove it again.

    you can control the play mode state from editor scripts, not only react to it changing
     
  5. mstevenson

    mstevenson

    Joined:
    Sep 24, 2009
    Posts:
    189
    Thanks, that's effectively what I'm doing, I was just hoping there'd be a way to do it without visibly modifying the scene. It seems that if I add and then remove an object using an editor script then the scene is marked as dirty unless the object's hide flags have been set to either DontSave or HideAndDontSave. I'm hoping to avoid any nasty edge cases, like the user saving the scene before the recorder is destroyed or closing the editor window while a capture is in progress.
     
    Last edited: Mar 11, 2011
  6. mstevenson

    mstevenson

    Joined:
    Sep 24, 2009
    Posts:
    189
    I found a solution! EditorApplication.playmodeStateChanged is called twice for every playmode change. When entering playmode, isPlaying == false, but when playmodeStateChanged is called again isPlaying == true.

    If my game object is created during the first callback, the object gets stuck in that unreachable no-man's-land mentioned in my first post. If instead I wait until isPlaying switches from false to true on the second callback then I can create a game object that is automatically cleaned up without needing to set HideFlags.DontSave. In fact, if I do set HideFlags.DontSave the object will persist and will be saved in the scene! Must be a bug.
     
  7. Innocent

    Innocent

    Joined:
    Sep 29, 2012
    Posts:
    1
    This saved me so much frustration!