Search Unity

Delay for checking project file changes on Editor focus

Discussion in 'Editor & General Support' started by n-gist, Jun 12, 2019.

  1. n-gist

    n-gist

    Joined:
    Mar 7, 2016
    Posts:
    41
    Hi!

    I like how Unity handles changes in files, we dont need to click anything, just make changes, switch to Unity, and get it working (auto recompile, reimport and so on).
    But it is even better when it is automated furthermore. So, my code editor configured to save all dirty files when it loses its window focus. Basically it works nice - i just need to switch to Editor with click or Alt+Tab in order to get new code recompiled and ready, without explicitly saving changes before switch.

    But, it seems like, if script file is slightly larger, or there is some OS delay comes to play, sometimes Editor did not picks up changed files. Seems like changes checking operation runs before a code editor actually manages to save a file, and i did come to the need to looking at my mouse cursor to see the work icon, whether the editor recompiled the modified script. If not, then I need to unfocus and focus Editor again to give it a second try (which is always successful).

    While I want this to be fixed more gently in the core (maybe configured delay in settings, or from script at least), there is a script I ended with, which just tracks when editor loses and gets focus again, running AssetDatabase.Refresh, which happens little bit later, and now it always catches changes. Windows only. Thanks!

    Code (CSharp):
    1. #if UNITY_EDITOR_WIN
    2. using UnityEditor;
    3. using System;
    4. using System.Diagnostics;
    5. using System.Runtime.InteropServices;
    6.  
    7. [InitializeOnLoad]
    8. public static class ChangesChecker {
    9.     private static int  editorPID;
    10.     private static bool focused;
    11.  
    12.     static ChangesChecker() {
    13.         editorPID = Process.GetCurrentProcess().Id;
    14.         focused = editorPID == FocusedWindowProcessId();
    15.         EditorApplication.update += Update;
    16.     }
    17.     private static void Update() {
    18.         if (focused) {
    19.             if (FocusedWindowProcessId() != editorPID) focused = false;
    20.         } else {
    21.             if (FocusedWindowProcessId() == editorPID) {
    22.                 focused = true;
    23.                 if (   !EditorApplication.isPlaying
    24.                     && !EditorApplication.isUpdating
    25.                     && !EditorApplication.isCompiling) AssetDatabase.Refresh();
    26.             }
    27.         }
    28.     }
    29.     private static int FocusedWindowProcessId() {
    30.         var foregroundHandle = GetForegroundWindow();
    31.         if (foregroundHandle != IntPtr.Zero) {
    32.             GetWindowThreadProcessId(foregroundHandle, out int foregroundWindowProcessId);
    33.             return foregroundWindowProcessId;
    34.         }
    35.         return -1;
    36.     }
    37.     [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
    38.     private static extern IntPtr GetForegroundWindow();
    39.     [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
    40.     private static extern int GetWindowThreadProcessId(IntPtr h, out int pId);
    41. }
    42. #endif
     
    Hozgen90 likes this.