Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to execute a script ONLY in edit mode ?

Discussion in 'Scripting' started by pitibonom, Dec 6, 2010.

  1. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    Hello all.

    I think am really missing something. I was searching for a way to changes things on an object during edit mode, and to avoid calling the 'update' during runtime.

    i didn't find other way to do this than putting a test on runtime or not in the update function.
    Is there a more beautifull way to achieve this ? like some ExecuteOnlyInEditor keyword ?
    I searched for info a lot, but didn't find anything that suits my needs or helps a bit.

    Here's my code atm...
    using UnityEditor;
    using UnityEngine;
    using System.Collections;

    [ExecuteInEditMode]
    [AddComponentMenu("UV/messup_mesh")]
    public class messup_mesh : MonoBehaviour {

    public float dec=0.0f;

    public void Update()
    {
    if(EditorApplication.isPlaying ) return;

    Mesh mesh = GetComponent<MeshFilter>().mesh;
    Vector3[] vertices = mesh.vertices;
    int p = 0;
    while (p < vertices.Length)
    {
    vertices[p] += new Vector3(0, Random.Range(-dec, dec), 0);
    p++;
    }
    mesh.vertices = vertices;
    mesh.RecalculateNormals();
    }
    }



    The 'OnInspectorUpdate' was a good looking function for what i need, but unfortunately, it's never called.

    If anyone could show me some tips or a lil piece of code, this would be great and help a lot !!!

    Thanks !
     
    juanitogan likes this.
  2. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
  3. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    Any help except fizixman's headshot and his brief&unusefull reply ?
     
    grom27, skabed, BikramKumar and 6 others like this.
  4. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,551
    Have you tried FizixMan's suggestion:

    #if (UNITY_EDITOR)
    // your code here
    #endif

    UPDATE: Ah, wait. I'm not sure what you mean by edit mode, I'm guessing you mean its when the game is not being played and only on the Unity Editor. I think what you already have works fine, what's wrong with it? Is it too slow or something?

    The OnInspectorUpdate only works for editor scripts. Editor scripts only work if you put the script in Assets/Editor inside your project folder.
     
    Last edited: Dec 9, 2010
  5. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    if (Application.platform == RuntimePlatform.WindowsEditor)
    Debug.Log("Do something special here!");
     
  6. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,551
    That will check if you are in the editor, yes, but not "if the game is currently being run or not".
     
  7. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Sorry for my brief unuseful reply; I misunderstood what you were exactly asking for.

    What are you exactly asking for? A more easier/elegant way to separate your "editor" code from your "game" code than the ways already offered?
     
    Last edited: Dec 9, 2010
    jeffersonrcgouveia likes this.
  8. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    Hi all :) and thanks for your replies.

    I spend part of the night trying to solve my problem and i managed to find an
    almost satisfying solution.
    Maybe i should explain a bit more what i expected. This would avoid misundertanding.
    But my english is this bad that i use to post as short as i can ;-)

    In fact, i needed some script to run ONLY in edit mode. I don't want it to run in
    editor play mode nor at runtime after compilation. The reason for this, is that the script
    is a bit heavy, and i got lots of gameobjects having it. and always running it even in play
    or run mode ( hmm am not sure i use the good words: for me the 'play' mode is when
    you click on the 'play' button on top of the unity window, beside the 'pause' button, and
    the run mode is for me the mode you are in when you launch an exe on windows, or a
    webplayer ) would dramatically reduce performance.
    In fact, this script is an UV relocating script. When i edit my objects in unity, i change the
    UVs with this script. But when it's done, i don't have to change UVs at all. So the script
    don't have to be run.
    I found the if(EditorApplication.isPlaying ) return; solution, but then i thought it was
    stoopid to do this, as during play or run, those objects don't need any Update() at all. So
    why call it if it's for an instant return ? Tho it's not very time consuming, if i got 1000 objects
    doing this, they'll all do some unusefull things.
    For this reason, i was wondering wether there was a way to run some script in edit mode
    and not in play or run mode ;-)
    I simply found a solution ( was pretty simple but non obvious to me ) to use a custom
    inspector for my script, calling for non real-time functions in this script. It works pretty
    fine, and is much more clean as it separates treatment from interface :-D

    Anyway, i thank you all for your answers and wish you a nice day !!!

    gbye !
     
    LeuzziLuigi likes this.
  9. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    what fixitman mentioned at the top is basically the best way to go.

    make an #if check that encapsulates the whole content of the class with a unity_editor check. that way that code is only present while you are in the editor.


    I guess it was missleading / confusing because you don't know of preprocessor constants so here an example


    Code (csharp):
    1.  
    2. [ExecuteInEditMode]
    3. public class DummyInEditor : MonoBehaviour
    4. {
    5. #if UNITY_EDITOR
    6.   void Update()
    7.   {
    8.    Debug.Log("Its time: " + Time.time);
    9.   }
    10. #endif
    11. }
    12.  
    What you can't do is check for "totally out of play mode", as thats something for which you normally don't use monobehaviours aside of the ongizmo function as they are a total overkill. Editor extensions are much more performant for such usages
     
    Last edited: Dec 10, 2010
  10. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    Nope DREAMORA

    You lil script is executed in play mode..... That's what i don't want. it' appears
    my explainations are not clear yet ;P
     
  11. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    As mentioned, thats not possible. if you want such a script, do an editor extension, because "not present in play mode" -> no use for it to be a monobehaviour -> do an editor extension that handles it (for examle customeditor for scriptableobject or alike)
    any other script will run at least in editor play mode unless manually disabled.

    No way to get around it.

    But I explained that there already that this is the best you can achieve on the reasonable level (reasonable means not with the devastating function present to directly jump out which still bogs the whole pipeline due to the sendmessage alike path thats used to call update, fixedupdate etc)
     
  12. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    Hmm lemme show a short example doing what i want:
    (tho it might not be a very 'academic' way to do things ;-P )

    1st script:

    [ExecuteInEditMode]
    public class the_script_for_my_object : MonoBehaviour
    {
    #if UNITY_EDITOR
    void somefunction()
    {
    Debug.Log("Call from inspector");
    }
    #endif
    }



    2nd script:

    @CustomEditor(the_script_for_my_object)
    enum modes {creation = 0, pairing = 1, apply = 2}

    class the_interface_of_script_for_my_object extends Editor
    {

    function OnInspectorGUI()
    {
    // doing things here with some buttons
    // and text and numbers entries
    //--------------------------------------------------------
    target.somefunction();
    }
    }


    Notice that in those both scripts, there are NO Update() functions.
    For this reason it's not called at run time nor at play time. Only
    when mouse if playing with my custom inspector buttons....

    I hope thingies are more clear now ;-)


    Have a nice day !
     
    skabed likes this.
  13. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    okies :) i created my message just while you were creating yours...

    you got the point, and i did what you said ;-)
    and it works exactly the way i want.

    thanks a lot for your help!
     
  14. ad48hp

    ad48hp

    Joined:
    Sep 18, 2013
    Posts:
    12
    #if UNITY_EDITOR
    void DoThat()
    {
    if(Application.isPlaying)
    {
    //do
    }
    }
    #endif
     
  15. vovo801

    vovo801

    Joined:
    Feb 3, 2015
    Posts:
    18
    I use this solution and it works, the code executes only in editor, suitable for instant previews, etc:
    On top of my class I have added
    [ExecuteInEditMode]
    Then in my Update() function:
    if (Application.isEditor && !Application.isPlaying)
    {
    //do what you want
    }
     
  16. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    712
    Hi there the perfect solution for me is using the "Context Menu" Option.

    Save the script and attach it to a GameObject. Then click the gear icon of this script, usually you will find reset, remove and copy here but this time you will find at the bottom your new declared methods. Simply click it and it will call your method'(s).

    Example:

    [ContextMenu ("Do Something")]
    void DoSomethingMethod ()
    {
    //Do something here such as get the total number of child game objects on this Parent.
    }

    It has many advantages aside from only being called once, you can just throw it inside any script in its own little corner without affecting any other sensitive variables, functions or methods. Also it seems to not impact performance at all. Of course if you prefer you can make it its own script as if it were a Utility script which is my current use for it.
     
    Last edited: Jan 4, 2016
    Ghujelk, bkovner100 and Ratboy601 like this.
  17. Eluem

    Eluem

    Joined:
    Apr 13, 2013
    Posts:
    57
    What's wrong with this?

    Code (CSharp):
    1.  
    2. void Update()
    3. {
    4.      if (!Application.isEditor || Application.isPlaying)
    5.      {
    6.           gameObject.SetActive(false);
    7.      }
    8. }

    Edit: Could probably just check for Application.isPlaying, honestly.
     
    objectstateequalswin likes this.
  18. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    712
    Your script doesn't work in the editor does it, it only works during Play mode?
    Even if it does, your script is checking every frame. Not good practice.
     
  19. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,954
    Once a game object is disabled, as is being done in the post you quoted, any scripts stop running.

    https://docs.unity3d.com/ScriptReference/GameObject.SetActive.html

    By the way the post you quoted is almost a year old and the author hasn't posted since July. ;)
     
  20. GregoryFenn

    GregoryFenn

    Joined:
    Feb 13, 2018
    Posts:
    43
    Greviouss likes this.
  21. jimmio92

    jimmio92

    Joined:
    Nov 3, 2009
    Posts:
    31
    Here's an idea, disable the object's script from a manager object of some kind. Update can't be called on something disabled, right?
     
  22. ninjarulzs

    ninjarulzs

    Joined:
    Feb 26, 2017
    Posts:
    1
    If you just make a bool that gets set to true on start, it will be false in the editor and true when the game is running.
     
  23. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,551
    Tonymotion and BullDoze like this.
  24. hockenmaier

    hockenmaier

    Joined:
    May 11, 2016
    Posts:
    11
    Not sure if it's "beautiful" or not but wouldn't it simply work to add a "this.enabled = false;" to your start script on a monobehaviour that executes in edit mode? Start is never called in edit mode so this should work just fine