# Adding diagnostics to C# code

> Use the managed code variant setting to include additional diagnostics, debug symbols, or instrumentation in your compiled C# code to help with debugging or profiling a built Player.

The [project build](/engine/6000.7/manual/building-and-publishing/building-introduction.md) process compiles managed (C#) project code into managed assemblies and packages them into an application that runs on a particular platform and architecture.

Depending on the build context, you might want to build different variants of managed code, with different kinds of code paths or metadata included to help with debugging or profiling.

You can choose to include the following kinds of additional information in your managed code assemblies:

* **Instrumentation**: Instrumentation code is included in managed code assemblies when the `UNITY_INCLUDE_INSTRUMENTATION` [scripting symbol](/engine/6000.7/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md) is defined. Instrumentation is the general term for extra code inserted around your functional code for the purposes of taking observations and measurements. In the context of a Unity project build, it means code related to the [Profiler](/engine/6000.7/manual/analysis/profiler.md) such as [profiler markers](/engine/6000.7/manual/analysis/profiler/markers.md) and most calls to the [`Profiler`](/engine/6000.7/script-reference/unityengine/profiling/profiler.md) API. For more information, refer to the [`Profiler`](/engine/6000.7/script-reference/unityengine/profiling/profiler.md) API reference.
* **Assertions**: Calls to Unity's [`Assertions.Assert`](/engine/6000.7/script-reference/unityengine/assertions/assert.md) API are included in managed code assemblies when the `UNITY_ASSERTIONS` [scripting symbol](/engine/6000.7/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md) is defined. When `UNITY_ASSERTIONS` isn't defined, the assertion methods are stripped out via the `[Conditional("UNITY_ASSERTIONS")]` attribute, so they add no runtime cost in shipping builds. For more information, refer to the [`Assertions.Assert`](/engine/6000.7/script-reference/unityengine/assertions/assert.md) API reference.
* **Safety checks**: Safety checks are included in managed code assemblies when the `UNITY_ENABLE_CHECKS` [scripting symbol](/engine/6000.7/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md) is defined. Safety checks are optional runtime validation that check for things such as out-of-bounds access to containers, concurrent data writes, and attempts to call main thread only APIs from a background thread.
* **Debug symbols**: [Debug symbols](https://en.wikipedia.org/wiki/Debug_symbol) are included in managed code assemblies when the `DEBUG` [scripting symbol](/engine/6000.7/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md) is defined. This code is unoptimized and appropriate for stepping through with a [debugger](/engine/6000.7/manual/scripting/debugging-and-diagnostics/managed-code-debugging.md).

This kind of additional information makes it easier to debug and profile a built Player but also increases the build size and impacts performance. You usually add it to a development build and omit it from a final release build shipped to customers.

## Configuring managed code variants ##managed-code-variant

You can include the different types of information mentioned previously in managed assemblies by configuring the managed code variant for your [build profile](/engine/6000.7/manual/building-and-publishing/build-settings/build-profiles.md). Managed code variants are predefined configurations of managed code, which include different levels of additional information, and define the relevant [scripting symbols](/engine/6000.7/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md).

The lowest-level variant, Release, includes no additional information. Each additional level includes everything from the level below. The highest-level variant, Debug, includes everything.

To change the managed code variant for your project in the Unity Editor:

1. Go to **Edit** > Editor > **Player**.
2. In **Other Settings**, navigate to the Optimization heading.
3. Set the **Managed Code Variant** property to the desired value.

You can also read or set the managed code variant from build scripts with [`PlayerSettings.GetManagedCodeVariant`](/engine/6000.7/script-reference/unityeditor/playersettings/getmanagedcodevariant.md) and [`PlayerSettings.SetManagedCodeVariant`](/engine/6000.7/script-reference/unityeditor/playersettings/setmanagedcodevariant.md) respectively.

The following table lists the managed code variant options:

| **Managed Code Variant** | **Scripting symbols defined**                                                                          | **Description**                                                                                                               | **Code optimization** |
| ------------------------ | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| **Debug**                | `DEBUG`, `UNITY_ASSERTIONS`, `UNITY_ENABLE_CHECKS`, `UNITY_INCLUDE_INSTRUMENTATION`, `ENABLE_PROFILER` | Adds debug symbols to the Checked variant.                                                                                    | Off                   |
| **Checked**              | `UNITY_ASSERTIONS`, `UNITY_ENABLE_CHECKS`, `UNITY_INCLUDE_INSTRUMENTATION`, `ENABLE_PROFILER`          | Adds safety checks and assertions to the Instrumented variant.                                                                | On                    |
| **Instrumented**         | `UNITY_INCLUDE_INSTRUMENTATION`, `ENABLE_PROFILER`                                                     | Adds instrumentation and enables the C# [`Profiler`](/engine/6000.7/script-reference/unityengine/profiling/profiler.md) APIs. | On                    |
| **Release**              | None.                                                                                                  | Adds no diagnostics or instrumentation.                                                                                       | On                    |

### Example

For example, the following snippet wraps a [`Profiler.BeginSample`](/engine/6000.7/script-reference/unityengine/profiling/profiler/beginsample.md) and [`Profiler.EndSample`](/engine/6000.7/script-reference/unityengine/profiling/profiler/endsample.md) pair so it only exists when instrumentation is enabled. This is only compiled into your managed assemblies when the managed code variant defines the `UNITY_INCLUDE_INSTRUMENTATION` scripting symbol:

```lang-cs
#if UNITY_INCLUDE_INSTRUMENTATION
    Profiler.BeginSample("MyExpensiveWork");
#endif
    DoExpensiveWork();
#if UNITY_INCLUDE_INSTRUMENTATION
    Profiler.EndSample();
#endif
```

## Code variants and Development Builds

In Unity versions before 6.6, selecting the Development Build option in the [Build Profiles window](/engine/6000.7/manual/building-and-publishing/build-settings/build-profiles-reference.md) produced a Player build that included the equivalent of the Checked managed code variant. This is no longer the case, and you must configure the Checked variant if you want a build that includes safety checks.

Although for the time being the **Development Build** option still defines `UNITY_ASSERTIONS` and `UNITY_INCLUDE_INSTRUMENTATION`, this is subject to change. It's best practice to use the [managed code variant setting](#managed-code-variant) to indicate what you want to include in your managed code.

> **Important:**
>
> Selecting the **Script Debugging** checkbox that appears when you select **Development Build** is equivalent to selecting the Debug managed code variant and produces the same Player build result.

## Additional resources

* [Debugging C# code](/engine/6000.7/manual/scripting/debugging-and-diagnostics/managed-code-debugging.md)
* [Introduction to building](/engine/6000.7/manual/building-and-publishing/building-introduction.md)
* [Unity Profiler](/engine/6000.7/manual/analysis/profiler.md)
* [Scripting symbol reference](/engine/6000.7/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md)
* [`ManagedCodeVariant` API reference](/engine/6000.7/script-reference/unityeditor/managedcodevariant.md)
