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

Resolved AssetDatabase.AllowAutoRefresh() not working?

Discussion in 'Scripting' started by ClementSXD, Aug 29, 2023.

  1. ClementSXD

    ClementSXD

    Joined:
    Aug 29, 2022
    Posts:
    9
    Hello,

    I am working on an editor tool that stops manual compilation and prevents the auto refresh of the Asset folder each time I edit a script from Visual Studio, to avoid long waiting times between each back and forth with the editor. To do so, I call
    EditorApplication.LockReloadAssemblies()
    to block the automatic recompilation, and
    AssetDatabase.DisallowAutoRefresh()
    to prevent domain reloading after leaving Visual Studio.

    Then, I want to be able to go back to automatic compilation if the user chooses so. To do so I use the opposite methods,
    EditorApplication.UnlockReloadAssemblies()
    and
    AssetDatabase.AllowAutoRefresh()
    . To swap between both modes, I use a menuItem that creates a toggle in the editor's toolbar.

    Code (CSharp):
    1. [MenuItem(ManualCompilationMenuItems.ENABLE_MANUAL_COMPILATION_PATH)]
    2.         private static void ToggleEnableManualCompilationBtn()
    3.         {
    4.             bool enableManualCompilation = Menu.GetChecked(ManualCompilationMenuItems.ENABLE_MANUAL_COMPILATION_PATH);
    5.  
    6.             enableManualCompilation = !enableManualCompilation;
    7.  
    8.             Menu.SetChecked(ManualCompilationMenuItems.ENABLE_MANUAL_COMPILATION_PATH, enableManualCompilation);
    9.             EditorPrefs.SetBool(ManualCompilationMenuItems.ENABLE_MANUAL_COMPILATION_PATH, enableManualCompilation);
    10.  
    11.             ManualCompilationMenuItems.SetCompilationState(enableManualCompilation);
    12.         }
    13.  
    14. private static void SetCompilationState(bool manual)
    15.         {
    16.             if (manual)
    17.             {
    18.                 EditorApplication.LockReloadAssemblies();
    19.                 AssetDatabase.DisallowAutoRefresh();
    20.  
    21.                 EditorSettings.enterPlayModeOptionsEnabled = true;
    22.                 EditorSettings.enterPlayModeOptions = EnterPlayModeOptions.DisableDomainReload;
    23.             }
    24.             else
    25.             {
    26.                 EditorApplication.UnlockReloadAssemblies();
    27.                 AssetDatabase.AllowAutoRefresh();
    28.  
    29.                 EditorSettings.enterPlayModeOptionsEnabled = false;
    30.             }
    31.         }
    32.  
    For some reason,
    AssetDatabase.AllowAutoRefresh()
    doesn't re-enable the automatic refresh of the assets. I can technically live with that, but I'd like to understand the reason behind it. The documentation says this methods affects a counter and MUST be accompanied by
    AssetDatabase.DisallowAutoRefresh()
    , but I'm 100% certain this isn't the source of the issue as each one of them is called by the toggle. So I'm stumped. Any advice would help.

    Thank you for your answers.
     
  2. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    280
    I'm not sure, but one thought that popped into my head is that when you re-enable auto-refresh, maybe call AssetDatabase.Refresh(). I'm not sure if that will solve the problem, but I thought I would throw it out there.

    Other than that, my instincts tell me that maybe something you're doing doesn't take full effect the same exact frame. There are a lot of things like that in the engine/editor that don't just do everything and take effect all at once. Some things are delayed by at least a frame and need callbacks or continuations of asynchronous operations to get it to all work properly. Again, I'm just guessing.
     
  3. ClementSXD

    ClementSXD

    Joined:
    Aug 29, 2022
    Posts:
    9
    Hi, thank you for taking the time to answer. Adding AssetDatabase.Refresh() right after AllowAutoRefresh() seems to solve my issue. Ideally I would prefer to avoid any kind of loading time, so I'd like to stay away from that method as much as possible. I don't understand why AllowAutoRefresh() doesn't do the job on its own. I've thought about calls being delayed for a few frames as well, but there is nothing going on right after the call, and going back and forth between Unity and VS should have given the tool enough time to recompile.
     
  4. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    280
    But, refreshing the asset database is not only about reloading scripts. It's also about rebuilding the asset database for all of your assets, images, audio, video, 3D models, etc. If you've had that setting toggled off for an unknown amount of time, how do you know you DON'T need to immediately do a refresh of the asset database? It's supposed to be doing it automatically if necessary as soon as that setting is toggled on. So, how do you know that NOTHING needs to be refreshed when that setting flips on?

    I understand what you mean that if indeed nothing is dirty and nothing needs a refresh it would be unnecessary to perform one, but I just thought I would point out that you don't have any conditional code in there to confirm that absolutely nothing in the Assets folder has changed since the setting was turned off. Now that I'm mentioning it, how does the automatic functionality of the AssetDatabase know? (I'm not an expert in that department.) Did something you disabled with the toggle off prevent it from even knowing it should auto refresh or not when you toggle everything back on?

    Also, I don't think Visual Studio telling the Asset Database to refresh should really be considered part of your plugin logic. People use many different IDEs to work with scripts in Unity. It should work with Rider, or VSCode, or whatever people might be using. Did you modify code after toggling it back on? Visual Studio manually telling the AssetDatabase to refresh, and the AssetDatabase in Unity knowing that scripts have been dirtied are two separate things. Make sure you keep them straight in your head, and you know how they work better than anyone if trying to do this. Your plugin should probably not assume that anyone is using Visual Studio, and to test it properly you should make sure it works with this Visual Studio setting enabled AND disabled.
    ADRefresh.png
     
  5. ClementSXD

    ClementSXD

    Joined:
    Aug 29, 2022
    Posts:
    9
    Visual Studio doesn't send any message to Unity; Unity itself, when it gets the focus back, seems to search through the AssetDatabase for any dirty files and refreshes if it finds any. I've tested my plugin with VS, VSCode, Notepad++ and the default Windows notepad, and the behaviour stays the same.

    I think you don't seem to understand what i'm trying to do. Whether or not some files are dirty or not doesn't matter here; I just need Unity to trigger its asset refresh when it regains focus after I edit a file, not when I uncheck the menu toggle. Unchecking the toggle is just supposed to re-enable its auto-detection flag, and in the current state of the plugin, manually adding AssetDatabase.Refresh() makes the refresh occur right after the toggle, not when I regain focus after editing a file.
     
  6. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    280
    I think I do understand. Nothing I said really contradicts what you just said, unless I miscommunicated. I know for a fact that the setting I highlighted in the image just above DOES tell Unity to refresh the asset database when you save in Visual Studio. I mean, it's literally what the setting is named. I was just trying to be helpful by pointing out that setting, and that it may be relevant to what you're trying to do. You did not originally mention that you had edited or saved a file, you only said you had "gone back and forth" which is why I specifically asked that question. I'm sorry if there is any miscommunication. You still haven't said what you currently have that setting set to in Visual Studio. If the setting is disabled, and you have toggled your menu option back on (without the forced refresh), then edited and saved a file, then refocused Unity, and the asset database has not refreshed to show your script changes, then I unfortunately don't know the exact solution to your issue. As I said, "I'm not sure." Best of luck though.
     
  7. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    Here's an idea:

    A) Leave AutoRefresh enabled for a tyical work session:
    - Meticulously count how many times the automatic refresh bothers you.
    - Multiply that number by the average time it takes the refresh to complete. This is the time in seconds auto-refresh forces you to wait.

    B) Then ... for the next work session (same duration and work) use that toggle menu as you please:
    - Count how often you flip this menu item toggle. Multiply this by two. This is how much time you spend at a minimum interacting with your menu toggle.
    - And whenever you find out that you were trying to test a change but then realized the script change did not compile or the asset wasn't in its current state because autorefresh was disabled, recall or at least estimate how much time (in seconds) went by since starting to test until you found out you shot yourself in the foot. Add to that the average time it takes for refresh to complete.
    - Sum up these times.

    If you are sharing this script with a team: have several or all of them go through A and B.

    Lastly, compare these two times for A and B. If the time for A is significantly greater than B, your script could be helpful. I doubt it. Unless proven otherwise I'd consider it somewhere on the scale between disruptive and destructive. ;)

    If you suffer from long Assembly Reload times (5-10s and specifically if higher) I would argue dev time is best spent on exploring causes for long refreshes and trying to reduce these times.
     
    Last edited: Aug 29, 2023
  8. ClementSXD

    ClementSXD

    Joined:
    Aug 29, 2022
    Posts:
    9
    Sorry for misunderstanding you. I'm not quite sure what you mean by that "setting" in Visual Studio. Yes, the option "Refresh Unity's AssetDatabse on save" is set to true in VS, but the refresh happens even when editing a file from another source, like Notepad++. The fault's on me for not being clear about this. As it stands, the solution you provided still does the job, even if it's not ideal to still have a domain reload, si I'll stick to that while looking for another solution if one exists. Thank you for your help.