Conditional Compilation allows parts of a script to be selectively removed by the compiler when specific compilation symbols are defined or not. For example:
Regular if |
Conditional #if |
---|---|
|
|
This condition could be either true or false when MyMethod is called so it needs to be checked every time. |
The #if is checked when the code is compiled. In the Unity Editor the UNITY_EDITOR symbol is defined so the code is just public void MyMethod() { Debug.Log("This is the Unity Editor"); } and in Runtime Builds that symbol is not defined so the code is just public void MyMethod() { Debug.Log("This is a Runtime Build"); } . This is known as Platform Dependent Compilation. |
Anything marked as [Editor-Only]
(such as the Animancer.Editor.AnimancerEditorUtilities
class) will only exist when the UNITY_EDITOR
symbol is defined (i.e. in the Unity Editor) so any usage will need to be inside a #if UNITY_EDITOR
and #endif
block.
The UNITY_ASSERTIONS
symbol is similar, but it is also defined in Runtime Builds if the Development Build
toggle is enabled in the Build Settings. This is referred to as [Assert-Only]
and is useful for performing additional safety checks and debug logging without affecting the performance of Runtime Builds at all.
Attribute
The [System.Diagnostics.Conditional]
can be placed on methods so that any calls to them are removed by the compiler unless the specified symbol is defined. For example:
// You could put this in a common utility class.
[System.Diagnostics.Conditional("UNITY_EDITOR")]
public static void EditorLog(object message)
{
Debug.Log(message);
}
public void MyMethod()
{
EditorLog("This is a test");
}
- In the Unity Editor, calling
MyMethod
would log"This is a test"
in the Console. - In a Runtime Build, calling
MyMethod
would do nothing as if you had put#if UNITY_EDITOR
and#endif
around theEditorLog
call.
Any method marked as [Editor-Conditional]
or [Assert-Conditional]
is using a [Conditional]
attribute.
Assertions
An assertion, or Assert
statement, tests a condition:
- If the condition evaluates to
true
, no action occurs. - If the condition evaluates to
false
, the assertion fails.
It's like saying "(condition) must be true, so give error (message) if it is not".
The consequences of an assertion failing depend on the specific method used:
Debug.Assert
logs an error in the Console but will keep executing the rest of the method.AnimancerUtilities.Assert
throws an Exception (UnityEngine.Assertions.AssertionException
) to prevent the rest of the method from executing.
Both methods have a [System.Diagnostics.Conditional("UNITY_ASSERTIONS")]
attribute so they will only be executed in the Unity Editor and in Development Builds, but not in regular release builds.
For example:
var rigidbody = GetComponent<Rigidbody>();
Debug.Assert(rigidbody != null, "There is no Rigidbody attached to this object.");
// ... Use the rigidbody.
- If there is a
Rigidbody
component attached to that object, the assertion will pass and do nothing. - But otherwise it will log the specified error message.