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
- Right-click any node in a Blueprint graph
- Select "Add Breakpoint" (or press F9)
- A red circle appears on the node
- 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
- Can I reproduce this consistently?
- What exactly is the symptom?
- What do I think is wrong?
- Where should I place breakpoints?
- What values do I need to verify?
- Have I checked my assumptions about input values?
- Have I traced back to find where state first went wrong?
- Have I tested the fix in multiple scenarios?