Where Should My Extension Be Installed?
This is a natural question for developers interested in submitting an Editor Extension/Scripting Package to the Unity Asset Store.
A detailed writeup about this follows, but for those looking for the quick solution (the TL;DR version), this depends on the version of Unity you’re using.
Unity 5.2.2+
Unity quietly made a change in Unity 5.2.2 to support Editor folders anywhere in the Plugins directory (read: not directly underneath Plugins). If you plan to support only Unity 5.2.2 and above, Editor Extensions/Scripting Packages should be installed as follows:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts: Assets/Plugins/[Package_Name]/**Editor**/...
Editor Resources: Assets/Editor Default Resources/[Package_Name]/...
Legacy Unity
If you need to support Unity versions prior to Unity 5.2.2, Editor Extensions/Scripting Packages should be installed as follows:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts: Assets/Plugins/**Editor**/[Package_Name]/...
Editor Resources: Assets/Editor Default Resources/[Package_Name]/...
Onward to details!
The [Wrong] Default Approach
Most extensions appear to install directly into a project’s Assets folder root, which feels like a natural solution:
Main Contents: Assets/[Package_Name]/...
Editor Scripts: Assets/[Package_Name]/Editor/...
Editor Resources: Assets/[Package_Name]/Resources/...
It turns out that this actually has two pretty surprising problems:
- If the package has scripts and supports an API, only the original language the API was written in can be used to interface with it. This has to do with the Script Compilation Order.
- All assets in the Resources folder are actually included with your user’s build, even if they’re GUISkins or fonts intended solely for use with your EditorWindow!
Unity provides mechanisms for getting around these issues: the Special Folders. There are three different Special Folder groups that circumvent problem 1 above:
Assets/Standard Assets/...Assets/Pro Standard Assets/...Assets/Plugins/...
The [Pro ]Standard Assets folders appear to be used for the standard assets that Unity provides with every installation. This leaves the Plugins folder which doesn’t look like a great location for non-native (or, at the very least, assembly) plugin installation, given the documentation.
So which is better? Unity engineers have informed me that
Nice. This means that if you wrote your Editor Extension in C# and wanted someone writing in Unityscript or Boo to be able to interface with your tech out of the box, you will need to organize your package for installation as follows:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts (5.2.2+): Assets/Plugins/[Package_Name]/Editor/...
Editor Scripts (pre-5.2.2): Assets/Plugins/Editor/[Package_Name]/...
A Source of Confusion/Common Misconception(?)
It has become apparent that there is a lot of confusion about Special Folders and how they work, even for Unity employees. It appears as though most people believe that they follow the generic Editor folder rules:
-
Scripts inside a folder called
Editorfound almost* anywhere will be compiled in a separate pass from game scripts. -
Scripts in these folders are not included in Assemblies for final builds.
- this will be addressed below, but
Editorworks differently when combined with other Special Folder names in versions of Unity prior to 5.2.2.
By this I mean that most people seem to expect that the following would work:
- Scripts inside a folder called
Pluginsare compiled in the firstpass compilation pass, and therefore accessible by any scripting language.
By this logic, the following folder setup should enable a library written in C# to be accessed by scripts written in Unityscript or Boo:
Main Contents: Assets/[Package_Name]/Plugins/...
Editor Scripts: Assets/[Package_Name]/Editor/...
This is NOT the case! According to current Unity folder rules, this results in all package scripts getting compiled in the normal pass. Further, the Editor scripts end up in the normal Editor compilation pass, not the firstpass one.
Okay, so Plugins isn’t a magic “anywhere folder” like Editor. Fine. Let’s try to move our package into Plugins, then, to get that language agnosticism. Results here depend on what version of Unity you’re targeting.
For Unity 5.2.2+
This works in Unity 5.2.2+:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts: Assets/Plugins/[Package_Name]/Editor/...
Great. Skip ahead to the What About Resources? section below if you don’t care about versions prior to Unity 5.2.2.
For Pre Unity 5.2.2
Unlike recent versions of Unity, this doesn’t work for versions prior to 5.2.2:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts: Assets/Plugins/[Package_Name]/Editor/...
The problem is that all scripts now end up in the firstpass assembly for game content - the Editor scripts do not end up in the Editor-firstpass assembly as we’d hoped! In fact, they do not end up in an Editor package at all, resulting in errors (no UnityEditor) during the build process. This is because when placed within Special Folders, the Editor folder name does not follow the standard rules! As outlined in the pre 5.2.2 documentation, you must place your Editor scripts in the Assets/Plugins/Editor folder to gain Editor-firstpass compilation! Therefore:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts: Assets/Plugins/Editor/[Package_Name]/...
In summation, the Plugins folder does not work like standard Editor folders. And, for that matter, Editor folders under Assets/Plugins do not work like Editor either.
What About Resources?
In case you weren’t already aware, everything in a Resources folder ends up in a special package called resources.assets that is included with the build package. This means that if your nifty Unity library includes nice Editor UI icons in a folder called Resources, those will end up in the final game! That’s just wasted space for your user (or yourself)!
Luckily Unity provides a special option for assets that are intended for use solely within the Editor. Such assets should be placed in a special folder called Editor Default Resources:
Editor Resources: Assets/Editor Default Resources/[Package_Name]/...
Assets (textures, skins, fonts, etc.) in this folder will not end up in the exported resources.assets package at build time. Note that these are accessed using a special API call: EditorGUIUtility.Load.
So this implies that if you wish to play nicely with the Unity Special Folders and gain access to their advantages, a full Editor extension would need to be installed with the following setup:
Main Contents: Assets/Plugins/[Package_Name]/...
Editor Scripts (5.2.2+): Assets/Plugins/[Package_Name]/Editor/...
Editor Scripts (Pre-5.2.2): Assets/Plugins/Editor/[Package_Name]/...
Editor Resources: Assets/Editor Default Resources/[Package_Name]/...
Why This Is Important; Going Forward
As Editor Extension developers the goal is frequently to create a library that provides some enhanced or added functionality to the user. In an ideal word, the solution provided should enable the end user to integrate your extension with their workflow with minimal effort. This means supporting all Unity-supported scripting languages. At present, this is possible but only using the folder structure outlined above.
Some of the Unity engineers I’ve talked to seemed to be under the impression that all of the special folder names acted the same way as the Editor name, implying that the following would work:
Main Contents: Assets/[Package_Name]/Plugins/...
Editor Scripts: Assets/[Package_Name]/Plugins/Editor/...
Editor Resources: Assets/[Package_Name]/Editor Default Resources/...
The benefit to such a setup is that everything would be contained within a single folder that the end-user could reorganize as they saw fit while maintaining the benefits of firstpass compilation and Resource usage. When they realized that such a setup did not work according to their expectations, they considered it a bug and something that should get fixed. Nice.
Hopefully, barring a full package system overhaul, something like the above will become viable in the near future, representing a relatively simple solution for both extension developer and user!
