What are debugging best practices for blueprints?

What are debugging best practices for blueprints?

For example, here are some questions:

  1. What is the best way to display logging/debug information in such a way that it is easy to turn on and off? Right now I have just been using “Print String” in my blueprints. That works but pretty soon it becomes a real mess. Ideally I would like some kind of debug/logging function where I can configure what messages are printed by what classes or by level of message or something. Does such a thing exist? If not, how should one display logging/debug messages?
  2. How should one do something like an assert statement? For example, it seems like I sometimes need to do a lot of casting. Since I’m not yet an expert on this my casts sometimes fail. Currently I use Print String to notify myself when that happens but it is clunky. Ideally, it would be nice to have a blueprint node called something like assert which takes in an exec line, a boolean (defaulting to false), and an optional string. When the condition is false, something should get displayed or logged saying exactly which blueprint the assert failed in. That way I wouldn’t have to constantly type the names of which blueprint the cast is failing when I use my “Print String” hack. Maybe I could write a blueprint macro to do this but I would need to know how to get the name of the blueprint the macro is running in dynamically.
  3. Sometimes I want to draw debug information (e.g., Draw Debug Arrow). Is there a convenient way to turn such things on and off as asked in 1?
  4. More generally is there a tutorial or wiki somewhere describing best practices for debugging/logging or libraries one can use for such things?

Thanks,
-X

I think one approach is to create a GameMode object which has a DebugLevel variable. One can then get the game mode and access the DebugLevel to determine how much debugging info to print. This lets you change the debug level in just one place. That seems reasonable.

One thing I think would be really useful would be to have better logging. In particular, it would be useful to have a logging function I can call which will tell me which blueprint is doing the logging so that I can find it later without having to look through all blueprints. I could probably right this myself if someone could tell me how to access the name of a blueprint that I am working in. Is there a way to do this?

I think it would be even better to allow a secondary output file parameter to be put into the “Print” node. That, coupled with your debug variable idea would allow some fairly neat and concise control over what to print to logs, when to print them, and where to print them to.

Just, set up a “PrintF” function, that you can call, passing in, strings (just my suggestion), put build the string the way you wish, grab the name of the object it’s working in, and always dump that in the output, set up a variable for the function (simple boolean) to turn on, off the output,a nd then you can do as you wish.

1
Log your messages to the clients console.

2
You can just create your own function in blueprint, choose your input, in your case a condition and a message if it doesnt meet that condition, inside that function you could output it to screen depending on whatever condition you feel is necessary

3

4
https://docs.unrealengine.com/latest/INT/Engine/Blueprints/UserGuide/Debugging/index.html

Hope this helps

Unfortunately, the Blueprint logging system is not as customizable as I’d like. For example, it would be great if there was a way to change the Print String settings (screen, log, both, or neither) for all nodes within a Blueprint.

As a workaround, I’ve taken to create helper functions for common objects I need to debug all the time. Something like GetObjectDescription, which returns a string containing the object’s DisplayName and any property I commonly need (such as location or health or whatever). Then whenever I need to output a debug message involving such an object, I also include the description in the output.

It’s also surprisingly helpful to use different colors in the screen logs. If I see something red whooshing by, I know that there was some kind of error and I need to check the log.

And of course, Breakpoints can be useful if you already know where your code passes through but need to find out what goes wrong afterwards.

The different colors, is extremely helpful, I have my function set up to be able to take a different color per blueprint, but now that you mention color again, I think I will modify it, to be able to accept a different color per call, and if null, well then just use the color set for the blueprint, I have it set up, such that all the controls are present by simply clicking controls during run time, if that is when it’s used.

I have this function inside the package called IwTransit (lmao, it’s far more than a simple debug function), that I will be releasing for the marketplace in a couple of days. You are very correct in it’s usefullness, I know for myself that this one function alone speeded up the early development, by at least 10 to 1. Because the entire system does 99% of it’s work during the construction script phase, where Breakpoints do not work.

Thinking about the output, beign directed into a file, as a VERY Kludgy work around, perhaps just putting each debug statement into an Array variable, that would maintain it, yet a pain in the ■■■ to deal with, a Struct for a data blueprint probably would be better, and still Kludgy as all get out. Will have to see if there is something else that can be done.

The other thing that is helpfull, is to grab the class name of the blueprint, and put that into every message, which can be done via the function, without it being a pain. The way I have it setup for myself, is that the class name is obtained, this ensures that every Message is uniquely tied to one blueprint, and can be done in the function when it’s building the string to do the printF with. Then I assign another message header per function that is passed in, and then a Message ID. These strings must take all of 20 seconds to do, which the function header only needs to be done once, the Messaage ID, needs to be done for each message, but still very much worth it, because then, you can use the “find variable reference” to locate where all those particular kinds of messages are in the blueprint.

The class name being displayed is an absolute must, if you are debugging mutliple instances of the same blueprint, and they are all dumping out information into the output log. I found that out early, as during my early testing, I had a level set up with over 100 usages of IwTransit,and IwActor in the level, and at times it was like, oh geezus, which one am I looking at now! lol