Assert() in Unity3d?

Can someone tell me, what should be used for Asserts in Unity? I have searched through the documentation and found these.

System.Diagnostics.Debug.Assert(bool)

But that won’t stop a debugger as Unity3D hasn’t got one yet.

I found these but I am not sure how or if I should use them.

Application.RegisterLogCallback

http://unity3d.com/support/documentation/ScriptReference/Application.RegisterLogCallback.html?from=LogType

Application.LogCallback

Or perhaps people just create their own Assert class and output Debug.LogError messages when conditions are false?

There isn’t an assert API in Unity, but you can do most things with good use of Debug.Log/print statements.

Thanks andeeee. I thought that might be the case. Hopefully we’ll get an assert in version 3.0.

Assert would be great. If I had an assert statement I would have them everywhere. I hate it when I print an error and not notice it. I want the application to come to a crashing halt in some cases :slight_smile:

Use Debug.LogError in combination with error pause in the console.

–Eric

I’ve been using this:

using UnityEngine;
using System.Collections;

public class Assert
{
	
[System.Diagnostics.Conditional("UNITY_EDITOR")]
	public static void Test(bool comparison, string message)
	{
		if(!comparison)
		{
			Debug.LogWarning(message);
			Debug.Break();
		}
	}
	[System.Diagnostics.Conditional("UNITY_EDITOR")]
	public static void Throw(string message)
	{
		Debug.LogWarning(message);
	}
}

Note: This only works in U3 as it relies on the platform define.

It will automatically strip all Tests and Throws on anything built outside the editor.

I really like Ntero’s solution and started adopting this approach in my code. However, I tend to want to spit out the values of offending variables in the message string, but this adds a lot of execution overhead with constant string concatenations taking place without the assertion actually being tripped.

I found that I could defer the string concatenations by using a delegate function that returns a string after the conditional fails. This afforded me roughly a 15x speedup in the assertion code and I simply had to get used to inserting “() =>” before each message string as shown below.

Here are two new Assert.Test method variations I added. The first is incredibly fast if you can drop the message altogether and simply rely on line numbers in the stack trace. My use of System.Func may seem a bit cryptic – you can substitute your own delegate type if you prefer.

		[System.Diagnostics.Conditional("UNITY_EDITOR")]
		public static void Test(bool comparison) {
			if (!comparison) {
				Debug.LogError("Assertion failed");
				Debug.Break();
			}
		}

		[System.Diagnostics.Conditional("UNITY_EDITOR")]
		public static void Test(bool comparison, System.Func<string> strf) {
			if (!comparison) {
				Debug.LogError(strf());
				Debug.Break();
			}
		}

Here is an example of how the assertion is made using a delegate function that returns a string:.

         Assert.Test(i<=j  j<=k, () => "Incorrect variable order -- i,j,k = " + i + ',' + j + ',' + k);

Then again, if execution speed is of prime importance, then you can’t afford even the method call to Assert.Test(). So nothing beats the speed of the following, with the downside that the #if / #endif pairs make the code a bit less readable. When the assertions are skipped, this runs about forty times faster than the string delegate on my system.

#if ASSERT
        if (i > j || j > k) Assert.Throw("Incorrect variable order  -- i,j,k = " + i + ',' + j + ',' + k);
        if (i > j || j > k) Debug.LogError("Incorrect variable order -- i,j,k = " + i + ',' + j + ',' + k);
#endif

System.Diagnostic.Debug.Assert can be used after some preparations:

/// <summary>
/// Unity-specific trace listener for making it possible to use stuff from
/// System.Diagnostics (like traces and asserts).
/// </summary>
public class UnityTraceListener: TraceListener {

public override void
Fail(string message)
{
    String text = String.Format("Application failure: {0}", message);
    UnityEngine.Debug.LogError(text);
    throw new ApplicationException(text);
}

public override void
Write(string message)
{
    UnityEngine.Debug.Log(message);
}

public override void
WriteLine(string message)
{
    UnityEngine.Debug.Log(message);
}

}

void
SomeInitFunction()
{
    Trace.Listeners.Add(new UnityTraceListener());
}