Treasure chest of Unity developer tools. Professional inspector tooling, high-performance utilities, spatial queries, and 20+ editor tools.
Bring structured, color-coded logs to any Unity project without sprinkling Debug.Log everywhere. WallstopStudiosLogger adds extension methods (this.Log, this.LogWarn, this.LogError, this.LogDebug) that automatically capture component metadata, thread info, timestamps, and user-defined tags rendered by UnityLogTagFormatter.
UnityMainThreadDispatcher / UnityMainThreadGuard).time|GameObject[Component] when logging on the main thread and inserts |thread| only when background workers emit messages, keeping logs deterministic without extra noise.$"{name:b,color=cyan}") without string concatenation. Tags deduplicate automatically and can be stacked in any order.These helpers live in
Runtime/Core/Extension/WallstopStudiosLogger.csandRuntime/Core/Helper/Logging/UnityLogTagFormatter.cs. Tests atTests/Runtime/Extensions/LoggingExtensionTests.csdemonstrate every supported scenario.
Logging – Tag Formatter package sample and open Samples~/Logging - Tag Formatter/Scenes/LoggingDemo.unity.LoggingDemoBootstrap (decorator registration) and LoggingDemoController (runtime toggles + this.Log* usage) to copy the patterns into your project.using UnityEngine;
using WallstopStudios.UnityHelpers.Core.Extension;
public sealed class EnemyHUD : MonoBehaviour
{
private void Start()
{
string mode = Application.isEditor ? "Test" : "Live";
int hp = 42;
this.Log(
$"Player {"Rogue-17":b,color=orange} :: HP {hp:color=#FF4444} ({mode:italic})"
);
}
}
pretty: false if you only want the decorated text without the timestamp (or optional thread) prefix.this.LogWarn, this.LogError, or this.LogDebug for severity-specific output; all overloads accept Exception e to append stack traces.ENABLE_UBERLOGGING is defined automatically for DEBUG, DEVELOPMENT_BUILD, and UNITY_EDITOR. Define it manually (or DEBUG_LOGGING / WARN_LOGGING / ERROR_LOGGING) in Player Settings if you need the extensions in release builds.
| Tag syntax | Effect | Notes |
|---|---|---|
:b, :bold, :! |
Wraps value in <b> |
Editor-only (uses Unity rich text) |
:i, :italic, :_ |
Wraps value in <i> |
Editor-only |
:json |
Serializes value via ToJson() |
Works in player builds |
:#color, :color=name, :color=#hex |
Wraps with <color=...> |
Named colors resolve to UnityEngine.Color constants |
:42, :size=42 |
Wraps with <size=42> |
Integers 1–100 (or any positive int) |
$"{stats:json,b,color=yellow}" emits bold, colored JSON.:b has no effect.Register project-specific tags at startup (for example, in an InitializeOnLoad editor script or a runtime bootstrapper):
using WallstopStudios.UnityHelpers.Core.Extension;
using WallstopStudios.UnityHelpers.Core.Helper.Logging;
[InitializeOnLoad]
internal static class LoggingBootstrap
{
static LoggingBootstrap()
{
UnityLogTagFormatter formatter = WallstopStudiosLogger.LogInstance;
formatter.AddDecoration(
predicate: tag => tag.StartsWith("stat:", StringComparison.OrdinalIgnoreCase),
format: (tag, value) =>
{
string label = tag.Substring("stat:".Length);
return $"<color=#7AD7FF>[{label}]</color> {value}";
},
tag: "StatLabel",
priority: -10 // run before built-ins
);
}
}
Key APIs:
AddDecoration(string match, Func<object,string> format, string tag, int priority = 0, bool editorOnly = false, bool force = false)AddDecoration(Func<string,bool> predicate, Func<string,object,string> format, string tag, int priority = 0, bool editorOnly = false, bool force = false)RemoveDecoration(string tag, out Decoration removed) to swap or disable decorators at runtime.UnityLogTagFormatter.Separator (',') controls how stacked tags are parsed.Use negative priorities for “outer” wrappers (run earlier) and higher numbers for final passes. Setting force: true replaces existing tags with the same name.
| API | Description |
|---|---|
component.Log(FormattableString, Exception e = null, bool pretty = true) |
Sends an info log through the formatter. Guarded by ENABLE_UBERLOGGING/DEBUG_LOGGING. |
component.LogWarn(...), component.LogError(...), component.LogDebug(...) |
Severity-specific variants with the same signature. |
component.GenericToString() |
Serializes all public fields/properties into JSON (used by the formatter when you pass :json). |
component.EnableLogging() / component.DisableLogging() |
Per-object toggle. Disabled components are skipped without allocations. |
component.GlobalEnableLogging() / component.GlobalDisableLogging() / SetGlobalLoggingEnabled(bool) |
Global kill switch suitable for in-game consoles or dev toggles. |
WallstopStudiosLogger.IsGlobalLoggingEnabled() |
Query current state (useful for tooling UIs). |
Additional behavior:
UnityMainThreadDispatcher.TryDispatchToMainThread first. If unavailable, it falls back to UnityMainThreadGuard.TryPostToMainThread and, if that fails, emits an “offline” log with a [WallstopMainThreadLogger:*] prefix.timestamp|GameObject[Component]|message on the main thread, inserting |thread| only for worker threads). Pass pretty: false when emitting data the Unity console already decorates (for example, performance CSV dumps).Debug.Log*, preserving click-to-focus navigation even when logs originate from pooled helper classes.[RuntimeInitializeOnLoadMethod] to register project-wide tags. Avoid allocating per-frame delegates.$"{health:json}" keeps minimal formatting allocations compared to string.Format.pretty: false for exporters — When writing to files or parsing logs, disable prefixes to simplify downstream tooling.ENABLE_UBERLOGGING (or DEBUG_LOGGING / WARN_LOGGING / ERROR_LOGGING) and make sure log volume is acceptable (or wrap noisy calls in your own #defines).Tests/Runtime/Extensions/LoggingExtensionTests.cs covers every default tag and stacking scenario. Copy those patterns when adding new decorations to ensure behavior stays deterministic.