Is it the case that #if UNITY_EDITOR and Application.isEditor will always evaluate to the same values of true or false? If so, is there any reason I would use one over the other?
#if UNITY_EDITOR → Code won’t be compiled at all in your final game build (so it’ll never be executed as it had never existed). It also gives you access to the UnityEditor assembly/namespance.
Application.isEditor → Code will be compiled and executed in your final game build, although it will always return false.
There’s also a third option: ConditionalAttribute.
When [Conditional("UNITY_EDITOR")] is added above a method definition, then all calls to that method will be stripped from builds.
private void Awake()
{
LogMessageIfEditor($"initializing {this}..."); // <- this line will get removed during the build process
Initialize();
}
[Conditional("UNITY_EDITOR")]
private void LogMessageIfEditor(string message)
{
Debug.Log(message, this);
}
One thing that you can do using the #if UNITY_EDITOR preprocessor directive but not using Application.isEditor is referencing types in the UnityEditor assembly in types that are included in builds.
Using just Application.isEditor would result in a build error, since the namespace doesn’t exist in builds.
#if UNITY_EDITOR
private void OnValidate()
{
Debug.Log($"Validating {UnityEditor.AssetDatabase.GetAssetOrScenePath(this)}", this);
}
#endif
The downside with using preprocessor directives is that the code isn’t even compiled when the symbol isn’t defined. This means that could think that everything is fine with all your code, but when you try to do a build then code inside #if !UNITY_EDITOR suddenly causes an error. This can make refactoring your code more difficult, because renaming a type of a member might not also affect inactive code inside directives.
So which one you should use depends on the situation.
You can also use Assembly Definitions to have an entire assembly of types only be compiled in the editor.
I’m pretty sure Application is UnityEngine namespace tho, so should be safe.
edit: I’m probably misunderstanding something you said.
edit2: yeah, it’s supposed to be read as “Using just Application.isEditor [in the following example] would result in a build error, since the namespace doesn’t exist in builds.”
@orionsyndrome What I meant was that UnityEditor.AssetDatabase.GetAssetOrScenePath(this) would not compile if just Application.isEditor was used to avoid executing the code.
My question was if they always evaluate to the same truth value.
Yes otherwise it wouldn’t make sense. It’s either Editor or Player build; one for compile-time, one for runtime.