Search Unity

Custom Editor Problem: Editor folder scripts can't access external scripts

Discussion in 'Scripting' started by snowfy5, May 23, 2020.

  1. snowfy5

    snowfy5

    Joined:
    Jun 17, 2019
    Posts:
    4
    Hello everyone, I'm new to working with Unity so this might be a noob question. I've briefly scoured a couple tutorials for making a custom Editor that modifies game-runtime scripts. I think I'm missing something, because I can't get any of their Editor scripts to recognize other non-editor scripts.

    The two script directories are:
    Assets/RW/Scripts/TankController
    Assets/RW/Editor/TankControllerEditor

    The Error: in TankControllerEditor
    the type or namespace name 'TankController' could not be found are you missing an assembly reference


    Is it that Assembly-CSharp-Editor cannot access Assembly-CSharp? The guide says that Assembly-CSharp-Editor compilation happens after Assembly-CSharp, therefore it has access to the other. My references for the editor assembly has the main assembly under it.

    Is something weird happening with the folder structure or VisualStudio?

    Thanks for any responses in advance
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    EDIT: Disregard the remainder of this post: I confused this with the limitations of the Plugins directory, which is compiled into Assembly-CSharp-firstpass, at which point the balance of your project's classes are not yet compiled.


    My original WRONG post here... IGNORE:

    Unfortunately this is how it is in Unity if you put your Editor scripts in an Editor folder.

    You can google it up details by asking about "compilation order in Unity3d"

    The work-around is to place your Editor scripts in a "regular" folder of the game, but then encase the entire script (or at least everything that uses classes in the UnityEditor namespace) in a
    #if UNITY_EDITOR
    and
    #endif
    block. It's kinda unsightly but you get past it.

    Code (csharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3.  
    4. public class MyEditor : Editor
    5. {
    6.   // foo
    7. }
    8. #endif
    Then like I said, move it somewhere that isn't anywhere under a folder called Editor.
     
    Last edited: May 24, 2020
    DSivtsov likes this.
  3. snowfy5

    snowfy5

    Joined:
    Jun 17, 2019
    Posts:
    4
    Hey there, I appreciate your response and may use your method if I can't figure out another way.

    But would there be a purpose for the Editor folder if you did this (move them outside of the Editor folder)? Answer: there is because you can still edit other variables/data than just game-scripts.

    (After doing some research, I'm gonna try to layout what I've learned, some of which may need to be corrected).

    Pre-processor Directives
    I found what you're doing is using define directives (used to test out other platform's code at game-time, or sneak in UnityEditor code in play-mode). Apparently there is also a [ExecuteInEditMode] class property, but it can't access the UnityEditor code.

    Tutorials:
    The tutorials I've seen aren't limited to using this. They all have a script in the Editor folder, inheriting "Editor" or "EdityorWindow", and using the [CustomEditor(typeof(*insert class here*))] class property. This property defines what type of object the CustomEditor is manipulating. The modifying class is always external to the Editor folder, in a "Scripts" folder of the same location as the "Editor" folder.

    These are a few example tutorials, but I can't get them to work (they share the same Editor-script error, trying to find class/namespace of external scripts):
    https://www.raywenderlich.com/7751-unity-custom-inspectors-tutorial-getting-started
    https://www.raywenderlich.com/3169311-runtime-mesh-manipulation-with-unity
    (Haven't implemented this one, but am about to)

    Here is a tutorial using the method that you currently use: https://blog.theknightsofunity.com/custom-unity-editor-window/ . I haven't read it yet, but I shall try to understand what's different from the others.

    Maybe I am importing them wrong? Or maybe these are using old code and it no longer works like this in Unity now? It's possibly something simple, because none of the tutorials mention the error I'm getting.

    Editor:
    Furthermore, the Unity documentation, "Custom Editors", gives an example of using UnityEditor and UnityEngine code without the define directives (the same formatting as the tutorial code). Though, on this page, it doesn't directly say anything about the Editor folder.

    I think the purpose of putting it in the Editor folder is to implicitly allow it to compile in Edit-mode; the Editor folder isn't compiled during the final game build, which is why you'd have to use the define directives to check, if it's elsewhere. From what I read, the purpose of the different assemblies are to not have to re-compile every inch of code when making changes, splitting it up by dependencies.

    Compilation
    The documentation, "Special folders and script compilation order", talks about the 4 compilation phases (each with their own Assembly and Assembly references). It says:
    "The basic rule is that anything that is compiled in a phase after the current one cannot be referenced. Anything that is compiled in the current phase or an earlier phase is fully available."

    Assembly-CSharp-Editor happens last, and should have access to the earlier assemblies (Assembly-CSharp), but not the other way around. Maybe there is something weird going on with assemblies?

    My brain is melting:
    I'm just confused. I don't think we should have to be using a "work-around" here. There's official documentation and tutorials about doing it another way. Maybe I'm doing something odd with folder structure, so I shall go check up on those rules.
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    Assembly-CSharp-Editor can access Assembly-CSharp. That's the whole point. The way you set it up in your original post should work, so there's something odd going on.

    @Kurt-Dekker is just straight up wrong here.

    Have you by any chance added any assembly definition files? Those work differently, so if you eg. had an asmdef file in your Scripts/ or Editor/ folders, that would bypass the default ("old") compilation order.

    EDIT: or you might have introduced a namespace somewhere, but you seem to know enough programming that that's probably not the issue? Should check, though.
     
    Bunny83 likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    Baste, you are completely correct. I was mixing it up with the Plugins folder limitations, which goes in
    Assembly-CSharp-firstpass and hence has that restriction.

    OP: sorry to lead you astray. Baste's ideas about namespaces and/or asmdef files is something to look at. Another thing to look at is sometimes Unity does not recompile when you expect it to, i.e., when you change a file. The easiest way to force a full recompile is to just create a new Monobehavior in the Plugins folder, then when it finishes compiling, delete it.
     
    Terkish1987, Bunny83 and Baste like this.
  6. snowfy5

    snowfy5

    Joined:
    Jun 17, 2019
    Posts:
    4
    Thank you guys for your help. One tutorial project I am able to hit the play button and it runs, but has errors in Visual Studio. For now I'll work with it, and if I figure it out I'll update this thread.
     
  7. kirbyderby2000

    kirbyderby2000

    Joined:
    Apr 28, 2017
    Posts:
    35
    Were you ever able to get this working? I've been struggling with making Editor scripts for this same exact reason. I'd rather not do the workaround suggested in this thread because Editor scripts shouldn't require this workaround. I'm starting to suspect it's a problem with Visual Studio and not Unity.
     
  8. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    If it compiles in Unity, but not in VS, then yes VS is the issue.
     
  9. kirbyderby2000

    kirbyderby2000

    Joined:
    Apr 28, 2017
    Posts:
    35
    Yeah, you were right. I tried everything to get Visual Studio to play nice with Unity; reinstalled Unity, reinstalled Visual Studio, cleared Unity local cache files (suggested from some sources around the internet), but all my efforts made to no avail because I kept getting broken namespace / assembly reference errors.

    Do note though that I was using Visual Studio Community. I finally decided to jump ship and start using Visual Studio Code and wouldn't you know it, no errors! I'm guessing that's because Visual Studio Code doesn't have a compiler and just leaves the compilation process to Unity. Don't know why it took me this long to check out VS Code, it's incredibly nice and lightweight. Definitely recommend it.
     
    Last edited: Oct 1, 2020
  10. ZoraMikau

    ZoraMikau

    Joined:
    Oct 11, 2016
    Posts:
    6
    Someone else was having the issue with Visual Studio and this might be the solution: https://answers.unity.com/questions/1728985/custom-editor-and-visual-studio-solutions.html

    Also, I am having this exact issue with VSCode right now and the only solution for me was to change the folder from (or move them to a folder not named) "Editor". Not ideal, but I only have a couple of them so I'm not too worried about it right now.

    Things that have not worked for me while trying to figure it out:
    - Updating Unity
    - Moving the Editor folder to the Assets/ folder from the Assets/Scripts folder
     
    Last edited: Oct 15, 2020
    ahSOLO1 likes this.
  11. gamedev1506

    gamedev1506

    Joined:
    Nov 2, 2019
    Posts:
    36
    For future reference on the same bug (Visual Studio Code for me, i wasnt getting any compilation error, but the code was highlighted red indicating a error on the VS)
    On the file Assembly-CSharp-Editor.csproj:
    Code (csharp):
    1.  
    2.   <ItemGroup>
    3.     <ProjectReference Include="Assembly-CSharp.csproj">
    4.       <Project>{1a4289e9-7cdb-7fca-1e77-356aecc42dc3}</Project>
    5.       <Name>Assembly-CSharp</Name>
    6.       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    7.     </ProjectReference>
    8.   </ItemGroup>
    9.  
    I changed the ReferenceOutputAssembly to true and it solved on the visual studio code.
     
  12. kirbyderby2000

    kirbyderby2000

    Joined:
    Apr 28, 2017
    Posts:
    35
    Okay so follow-up to this problem. I mentioned that when I switched to Visual Studio Code from Visual Studio Community, these assembly reference errors disappeared. Well, I randomly started getting these errors again in Visual Studio Code too. I spent all day trying to figure out how to fix it, here's how I managed to fix it on my end:

    1.) Close Visual Studio

    2.) From Unity, go to Window -> Package Manager -> Select "Visual Studio Code Editor" (or "Visal Studio Editor" if you're using Visual Studio), -> Update the package to the latest version

    3.) Then in Unity, go to Edit -> Preferences -> External Tools -> "Regenerate project files"

    4.) Re-open Visual Studio or Visual Studio Code


    This fixed my assembly reference issues in both Visual Studio and Visual Studio Code.
     
  13. kjc1943

    kjc1943

    Joined:
    Jan 4, 2018
    Posts:
    2
    Thank you "kirbyderby2000"

    your solution work me very well

    AWESOME!!
     
  14. milktheknife

    milktheknife

    Joined:
    Dec 7, 2018
    Posts:
    1
    THANK YOU
     
    gamedev1506 likes this.
  15. pandaleo

    pandaleo

    Joined:
    Dec 14, 2018
    Posts:
    1
    This works for me! Thanks!
     
    AndyMartin458 likes this.
  16. jim3878

    jim3878

    Joined:
    Mar 14, 2018
    Posts:
    1
    It still works in 2020.3.13f1
    Thank you!
     
  17. cielbird

    cielbird

    Joined:
    Dec 15, 2017
    Posts:
    11
    Regenerating project files on it's own worked for me:

    Edit > Preferences > External Tools > Regenerate Project Files
     
  18. daochihao98

    daochihao98

    Joined:
    Apr 16, 2020
    Posts:
    5
    Thank you so much!!!
     
  19. ThomasHoy

    ThomasHoy

    Joined:
    Mar 15, 2022
    Posts:
    1
    This didn't work in my case, just wanted people to know. :)
     
  20. Biscuitlid

    Biscuitlid

    Joined:
    Apr 1, 2013
    Posts:
    8
    But it did work for me! Thank you!
     
  21. DSivtsov

    DSivtsov

    Joined:
    Feb 20, 2019
    Posts:
    151
    It was a minimum, you which must to do it before next step, which depends on where you want to put your "CustomEditor" scripts in "common assembly" (like Assembly-CSharp-Editor) or custom assembly.
    In this case, it all depends on the correct naming of the folder.
    In case of custom assembly are many workarounds ( @Kurt-Dekker described some of them). May be more appropriate is the creation of separate assembly definition for CustomEditor script see Link

    ADDED:

    I used this folder structure:
    Scripts\CustomEditor\
    - here the CustomEditor.asmdef and custom "PropertyAttribute"
    Scripts\CustomEditor\Editor
    - here the corresponding "PropertyDrawer"
    in this case the "PropertyAttribute" was accessible from every script doesn't matter where it resides in "common assembly" or custom assembly (without any additional reference to this "CustomEditor" assembly). It is very comfortable
     
    Last edited: Jul 8, 2022
    wing3s likes this.