Potential problem in using ExecuteIEditMode

While I can see ExecuteInEditMode being a useful feature I was wondering if there are potential problems. As I understand it the Update function in the script will still execute if the program is in Play mode. Could this be a potential problem if you want different behaviours in Edit and play mode? For example I may want the blocks to snap to a grid when being placed in the Unity Editor but to be able to move freely when the scene is running. Thinking about this I looked for possible solutions. The one that I found was to use the Application.isPlaying flag to determine whether or not to use the Edit Mode. Thus the EditorSnap C# programt would become:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]

public class EditorSnap : MonoBehaviour {

    [SerializeField][Range(1f, 20f)] float gridSize = 10f;

    void Update()
    {
        if (!Application.isPlaying)
        {
            Vector3 snapPos;
            snapPos.x = Mathf.RoundToInt(transform.position.x / gridSize) * gridSize;
            snapPos.z = Mathf.RoundToInt(transform.position.z / gridSize) * gridSize;
            transform.position = new Vector3(snapPos.x, 0f, snapPos.z);
        }        
    }
}

This may not be relevant to this particular application but might be potentially useful, and it is worth bearing in mind that ExecuteInEditMode may have unexpected consequences. If anyone knows of a better way of handling this please feel free to post.

1 Like

I found a similar problem, highlighted by the fact that I also made every object in the scene a snappable object (I based waypoint, enemy, tower, wall, etc all on “GridLike”. I found that my animations didn’t flow smoothly from tile to tile, sometimes they would get pulled back… and the game ran at 6fps…

Same solution, I used if(!Application.isPlaying) to disable the scripts during play, and all those problems went away.

1 Like

Thank you - makes a lot of sense. I also posted on the Q&A about using Progrids

You can use the Awake() function (or Start()) to disable the script. The magic keyword ‘this’ will refer to the component/script, so you can just disable this. This will disable the component when you play the game or go back into edit mode, but in edit mode you can just manually re-enable it by ticking the component.

Note that when you go to finally build your finished game, it’s best to leave all editor scripts disabled so that don’t get loaded into your game.

I use this method in my own snap-to-grid code:

using UnityEngine;

[ExecuteInEditMode]
public class SnapToGrid: MonoBehaviour
{
    [Header("Snap to cube-grid of width gridSize.")]
    [Range(1, 60)][SerializeField] int gridSize = 12;

    void Start()
    {
        // Manually enable this component whenever you need it in edit mode,
        // leave disabled during the game and for the final build.
        this.enabled = false;
    }

    void Update()
    {
        Vector3 pos = transform.position;
        float x = Mathf.RoundToInt(pos.x / gridSize) * gridSize;
        float y = Mathf.RoundToInt(pos.y / gridSize) * gridSize;
        float z = Mathf.RoundToInt(pos.z / gridSize) * gridSize;
        transform.position = new Vector3(x, y, z);
    }
}

p.s. instead of grid sizes of 10, I suggest 12 (or even 60) because 12 divides neatly into 2,3,4, and 6: whereas 10 only divides neatly into 2 and 5. This means we can make blocks/enemies/obstacles of sizes that fit perfectly into halves, thirds, and quarters, instead of just halves and fifths. (I know this doesn’t matter really because you could use thirds with values of 3.33333, and quarters with values of 2.5, but using 12 is much neater don’t you think?)

Privacy & Terms