BlueprintsSeptember 9, 202611 min read

The Complete Guide to Debugging Blueprints in UE5

Print String is not a debugging strategy. Here's how to systematically find and fix Blueprint bugs.

The Problem with Print String Debugging

Every Blueprint developer has done it: scatter Print String nodes everywhere, run the game, squint at the screen trying to catch values flying by. It works for simple issues. It falls apart for anything complex.

Unreal has real debugging tools. They're underused because they're not as obvious as Print String. This guide covers everything.

Blueprint Breakpoints

Breakpoints pause execution at a specific node, letting you inspect the entire state of your Blueprint.

Setting Breakpoints

  1. Right-click any node in a Blueprint graph
  2. Select "Add Breakpoint" (or press F9)
  3. A red circle appears on the node
  4. Play in Editor (PIE)—execution pauses when it hits that node

What You Can Do When Paused

  • Inspect variables: Hover over any variable node to see its current value
  • Watch expressions: Add variables to the Watch window for persistent monitoring
  • Step through: Execute one node at a time with F10
  • Continue: Resume execution with F5
  • Call stack: See how you got to this point

Conditional Breakpoints

Right-click a breakpoint and select "Edit Breakpoint" to add conditions. The breakpoint only triggers when the condition is true.

Example: Break only when Health < 10 or ActorName == "Boss"

The Watch Window

Window → Developer Tools → Blueprint Debugger opens the debugging panel. The Watch section lets you track variables across execution.

Adding Watches

  • Right-click a variable in the graph → "Watch this value"
  • Or type variable names directly in the Watch panel
  • Watches persist between debug sessions

Watching Complex Types

For structs and objects, expand the watch entry to see member values. For arrays, you'll see the count and can expand to see elements.

Blueprint Call Stack

When paused at a breakpoint, the Call Stack panel shows the chain of function calls that led to this point. This is invaluable for:

  • Understanding how an event triggered
  • Finding the source of unexpected calls
  • Tracing through complex event chains

Click any entry in the call stack to jump to that point in the code.

Visual Execution Tracing

During PIE, Blueprints show execution flow visually:

  • Red pulses: Show execution wire activity
  • Data wire values: Hover over data wires to see last values
  • Node execution counts: Enable in viewport to see how many times nodes execute

This passive visualization often reveals issues without explicit debugging— you can see that a branch never executed or a loop ran unexpectedly.

Systematic Debugging Process

When something's broken, resist the urge to scatter Print Strings. Follow this process:

1. Reproduce Reliably

Before debugging, ensure you can reproduce the bug consistently. Random bugs require different approaches (logging, telemetry).

2. Identify the Symptom

What exactly is wrong? "It doesn't work" isn't specific enough.

  • "The actor doesn't spawn" → Check spawn logic
  • "The actor spawns in the wrong location" → Check transform values
  • "The actor spawns but disappears" → Check lifespan, visibility, destruction

3. Form a Hypothesis

Based on the symptom, what might be wrong? Common categories:

  • Wrong value (math error, wrong variable used)
  • Wrong timing (event fires too early/late)
  • Missing connection (wire not connected, event not bound)
  • Wrong reference (null, wrong object, stale reference)

4. Place Strategic Breakpoints

Don't breakpoint everything. Place breakpoints at:

  • The entry point of the suspicious system
  • Just before where the bug manifests
  • At decision points (branches, switches)

5. Verify Assumptions

When paused, check the values you assumed were correct. Often the bug is earlier than you thought—a value was wrong before it reached the code you suspected.

6. Narrow Down

Use binary search: if the bug happens after node 50, place a breakpoint at node 25. Is the state correct there? If yes, problem is between 25-50. If no, problem is before 25. Repeat until you find the exact point where state goes wrong.

Common Blueprint Bugs

Null References

"Accessed None trying to read property..." is the most common Blueprint error.

Causes:

  • GetComponent before component exists
  • Referencing destroyed actors
  • Array access out of bounds
  • Cast failures

Debugging:

  • Add IsValid checks before accessing references
  • Check the error message—it tells you which property
  • Trace back to find where the reference should have been set

Timing Issues

Events firing in unexpected order, usually around BeginPlay.

Debugging:

  • Print the tick/frame number with your debug output
  • Use delays or timers to sequence initialization
  • Consider using GameMode for coordinating actor setup

Replication Bugs (Multiplayer)

Different state on server vs client.

Debugging:

  • Use the "Number of Players" PIE setting to test locally
  • Print HasAuthority to verify which instance you're debugging
  • Check property replication settings
  • Verify RPCs are being called on correct net role

Loop Issues

Infinite loops freeze the editor. Loops that run wrong number of times.

Debugging:

  • Add a safety counter that breaks after N iterations
  • Breakpoint inside the loop with a hit count condition
  • Check loop bounds before entry

When Print String Is Actually Useful

Print String has its place:

  • Quick sanity checks: "Did this event fire at all?"
  • Value monitoring over time: When you need to see how a value changes across many frames
  • Packaged builds: Breakpoints don't work in packaged builds; print logging does
  • Multiplayer: When you need to see both server and client simultaneously

Better Print String Practices

  • Include the actor name: [{GetDisplayName()}] Value: X
  • Use different colors for different systems
  • Print to screen AND log (check "Print to Log")
  • Use Print String duration of 0 for rapid-fire values

Log Categories

For production debugging, proper logging beats Print String:

// In C++ header
DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);

// In C++ source
DEFINE_LOG_CATEGORY(LogMyGame);

// Usage
UE_LOG(LogMyGame, Warning, TEXT("Player health: %f"), Health);

In Blueprints, use the Log node with custom category names. Filter log output with Log CategoryName in Output Log.

Debugging Checklist

  1. Can I reproduce this consistently?
  2. What exactly is the symptom?
  3. What do I think is wrong?
  4. Where should I place breakpoints?
  5. What values do I need to verify?
  6. Have I checked my assumptions about input values?
  7. Have I traced back to find where state first went wrong?
  8. Have I tested the fix in multiple scenarios?