Check

June 19, 2026 · View on GitHub

Runtime guard-clause helpers for validating function arguments and preconditions. When a check fails, Check throws an Exception with a message that includes the source file, member name, and line number.

Designed for fail-fast debugging during development, not as a replacement for production error handling.


When checks run

Almost every Check method is marked [Conditional("UNITY_ASSERTIONS")]. That means:

  • Active when UNITY_ASSERTIONS is defined (Editor and Development builds by default).
  • Stripped entirely from Release builds, zero runtime cost in shipping players.

Check.Assert(bool, string) is always available and logs via Debug.LogError before throwing (except during unit tests).

#if UNITY_ASSERTIONS
// Checks are compiled in
#else
// Check.True(value) and similar calls disappear at compile time
#endif

Basic usage

Validate inputs at the top of a method before doing any work:

using UnityEngine;
using FronkonGames.GameWork.Foundation;

public void ApplyDamage(GameObject target, float damage, Vector3 hitPoint)
{
  Check.IsNotNull(target);
  Check.IsWithin(damage, 0.0f, 100.0f);
  Check.Greater(hitPoint, Vector3.zero);

  target.GetComponent<Health>()?.TakeDamage(damage);
}

On failure you get a message like: CombatSystem.cs:ApplyDamage:12 'target' must not be null.


Boolean

MethodPasses when
True(bool)Value is true
False(bool)Value is false
Check.True(isInitialized);
Check.False(isDisposed);

Null, type, and collections

MethodPasses when
IsNull(object)Value is null
IsNotNull(object)Value is not null
IsNotNullOrEmpty<T>(ICollection<T>)Collection is not null and Count > 0
OfType(object, Type)Value is an instance of the given type
IsAssignableFrom(Type, object)Value's runtime type can be assigned to the given type
Check.IsNotNull(player);
Check.IsNotNullOrEmpty(enemies);

Check.OfType(component, typeof(Rigidbody));
Check.IsAssignableFrom(typeof(IHealth), damageable);

Strings

MethodPasses when
IsNotNullOrEmpty(string)String is not null or empty
Length(string, int)Exact character count
MaxLength(string, int)Length ≤ max
MinLength(string, int)Length ≥ min
Check.IsNotNullOrEmpty(playerName);
Check.MaxLength(playerName, 32);
Check.MinLength(password, 8);
Check.Length(saveCode, 6);

Numeric comparisons

Works with any struct implementing IComparable<T>: int, float, double, etc.

MethodPasses when
Equal(a, b)a equals b
NotEqual(a, b)a does not equal b
Less(a, b)a < b
LessOrEqual(a, b)a ≤ b
Greater(a, b)a > b
GreaterOrEqual(a, b)a ≥ b
Negative(value)Value is strictly less than zero
NotNegative(value)Value is zero or positive
IsWithin(value, min, max)min ≤ value ≤ max (inclusive)
IsBetween(value, min, max)min < value < max (exclusive)
Check.Equal(level, expectedLevel);
Check.Greater(score, 0);
Check.IsWithin(health, 0.0f, maxHealth);
Check.IsBetween(progress, 0.0f, 1.0f);   // excludes 0 and 1
Check.NotNegative(ammo);

Unity vectors and quaternions

Vector2, Vector3, and Vector4 overloads compare magnitude for ordering (Less, Greater, etc.). Equal / NotEqual accept either another vector or a float magnitude (uses NearlyEquals for floats).

Quaternion supports Equal and NotEqual only.

Vector3 velocity = rigidbody.linearVelocity;

Check.Greater(velocity, Vector3.zero);        // magnitude > 0
Check.Greater(velocity, 5.0f);                // magnitude > 5
Check.Equal(direction, Vector3.forward);
Check.Equal(direction, 1.0f);                 // magnitude ≈ 1
Check.Equal(rotation, Quaternion.identity);

Reflection

MethodPasses when
Interface(Type)Type is an interface
NotInterface(Type)Type is not an interface
Check.Interface(typeof(IDisposable));
Check.NotInterface(typeof(MonoBehaviour));

Custom assertions

Use Check.Assert for conditions not covered by the built-in helpers:

Check.Assert(inventory.HasSpace(item), "Inventory is full.");
Check.Assert(phase == GamePhase.Playing, "Action only allowed during play.");

Practical patterns

Public API guard, validate every parameter a caller can pass incorrectly:

public void SpawnEnemy(GameObject prefab, int count, Transform spawnPoint)
{
  Check.IsNotNull(prefab);
  Check.IsNotNull(spawnPoint);
  Check.Greater(count, 0);
  Check.IsWithin(count, 1, maxSpawnCount);

  for (int i = 0; i < count; ++i)
    Instantiate(prefab, spawnPoint.position, spawnPoint.rotation);
}

State guard, assert internal invariants before a sensitive operation:

private void Fire()
{
  Check.True(isReady);
  Check.NotNegative(ammo);
  Check.IsNotNullOrEmpty(activeProjectiles);

  ammo--;
  SpawnProjectile();
}

Configuration guard, catch bad ScriptableObject data early:

public void Initialize(WeaponConfig config)
{
  Check.IsNotNull(config);
  Check.Greater(config.damage, 0.0f);
  Check.IsWithin(config.fireRate, 0.1f, 10.0f);
  Check.IsNotNull(config.projectilePrefab);
}

Check vs UnityEngine.Assertions

CheckUnityEngine.Assertions.Assert
Active whenUNITY_ASSERTIONS definedUNITY_ASSERTIONS defined
FailureThrows ExceptionThrows AssertionException
MessageFile, member, line, parameter nameCustom or generated
Vector supportMagnitude-based overloadsNone
Stripped in releaseYesYes

Use Check when you want readable guard clauses with consistent messages across your game code. Use UnityEngine.Assertions when you need tight integration with Unity Test Framework assertion types.


Source files

FileMethods
Check.csAssert
Check.Boolean.csTrue, False
Check.Type.csIsNull, IsNotNull, IsNotNullOrEmpty, OfType, IsAssignableFrom
Check.String.csIsNotNullOrEmpty, Length, MaxLength, MinLength
Check.Numeric.csEqual, NotEqual, Less, LessOrEqual, Greater, GreaterOrEqual, Negative, NotNegative, IsWithin, IsBetween
Check.Reflective.csInterface, NotInterface

Tests