Unity: Avoid Custom “ENABLE_X” Preprocessor Symbols

Picture of a laptop computer with code

I just stumbled upon a weird Unity behaviour when using preprocessor symbols beginning with “ENABLE_”. This cost me hours of debugging to find, so I hope this information reaches you in time. Debugging preprocessor directives really wasn’t too much fun.

I heavily use preprocessor directives in C# for platform-specific compilation. Unity also heavily relies on them in order to include or exclude code for specific platforms.

Taking this a step further, we can define Custom Symbols for use in our Preprocessor Directives. I personally use this to determine which social features I activate in my builds (Steamworks, Apple GameCenter, etc). This may come in handy if you plan to sell your games not only on Steam, but also on Itch.io, Epic, GOG, the Apple App Store or others.

The Problem

Unity supports configuring custom preprocessor symbols in the Player Settings. Here we can find Scripting Define Symbols in the Other Settings Section alongside other compilation settings.

Preprocessor directives we configure in the Unity Editor are synchronised to the resulting .csproj project files. This works great for most of the time and provides a good experience with your IDE.

Unity adds your custom symbols to the PropertyGroup displayed below within the DefineConstants block.
Open your .csproj file to find this PropertyGroup.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>Temp\Bin\Debug\play\</OutputPath>
    <DefineConstants>UNITY_2021_2_14;UNITY_2021_2;UNITY_2021;UNITY_5_3_OR_NEWER;
       UNITY_5_4_OR_NEWER;PLATFORM_ARCH_64;ENABLE_AUDIO;ENABLE_CACHING;
       ENABLE_CLOTH;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;
       ENABLE_INPUT_SYSTEM;DISABLESTEAMWORKS;FLAG_GAMECENTER;
    </DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <NoWarn>0169,0649</NoWarn>
    <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
  </PropertyGroup>

Notice how Unity includes many internal symbols prefixed with “ENABLE_”. I had previously used custom symbols such as “ENABLE_GAMECENTER” or “ENABLE_PLAYGAMES” to control if we use Googles or Apples social platforms for achievements etc.
This seemed to work at first: Our symbols were added to the csproj files and the built players behaved as expected.

The problem begins when removing custom symbols which are prefixed with “ENABLE_”.
Unity will not remove custom symbols prefixed with “ENABLE_” from the .csproj files!

The Solution

This behaviour does not seem to be documented anywhere, but I was able to reproduce this behaviour in Unity 2021.2.14f1 and 2021.3.0f1

As we cannot change this behaviour, the solution is simple: Avoid it.
You may use “FLAG_X” such as I do, or any other prefix such as “ACTIVATE_X”, etc.

I assume that the developers of Steamworks.net made their experience with this issue, as they use the “DISABLESTEAMWORKS” symbo, which avoids this behaviour.