#include "Engine/TriggerVolume.h" in header or cpp file?

Should the #include “Engine/TriggerVolume.h” be included in the Door.h or in the Door.cpp file? Was thinking it was best to include it in the header since then it will be accessible in booth. But when I strated to change anything in the include statements int the header, even as little as putting an extra line between #pragma once and the first preprocessor directive #include “CoreMinimal.h” then errors started to appear int the cpp file. Like BeginPlay() turning read.

Have not bean active in the course for a while so maybe it is something very simple I don’t remember from before. Appreciate any guiding words. :slight_smile:

The dreaded read squiggles after changes to Unreal header files are caused by Visual Studio not understanding the Unreal build system, and they shouldn’t really influence your choice of where to put your includes. I’ll get back to that at the end of the post.

The usual guideline is to include as few other headers as possible in header files. This reduces dependencies between headers and can greatly reduce compile times in large systems. Of course each header should still include what it needs, you don’t want a header that only works if somebody else includes its dependencies.

Since class UOpenDoor inherits from UActorComponent you need the complete definition of that class and thus have to include the Components/ActorComponent.h header.

However, UOpenDoor only stores a pointer to ATriggerVolume, so the header needs no information about the size of ATriggerVolume instances in memory or the methods that can be called on them. Therefore, in a larger project I would forward declare ATriggerVolume in the header file and include Engine/TriggerVolume.h in the corresponding .cpp file. So my OpenDoor.h file would start like this:

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "OpenDoor.generated.h"

class ATriggerVolume;

Having said that, in small projects like the ones in this course it’s not really necessary to worry about compilation speed or dependencies, so you can just include the Engine/TriggerVolume.h header in OpenDoor.h and be done with it.

Back to the red squiggles that we all know and love.

To understand why they appear even when you make only minimal changes, such as inserting a blank line, it helps to look at the Unreal build process.

In order to provide all the wonderful reflection features that are not present in standard C++, Unreal performs a preprocessing step before feeding your code to the C++ compiler. The program that does this is called the Unreal Header Tool (UHT), and it is responsible for generating the code that integrates your classes with the reflection code written by Epic’s wizards. This generated code lives in the .generated.h file that you have to include after all other includes.

The function of macros such as GENERATED_BODY() is essentially to insert a “hook” into your files where the code generated by UHT can attach to your code. But that is a bit of a problem, since the generated code is different for each class (or struct, etc.) that you define. Since it’s common to define multiple classes that need a GENERATED_BODY() macro inside a single file UHT can’t just write a definition of GENERATED_BODY into the .generated.h file since then the same code would be added to all classes in the file. To solve this problem, many Unreal macros expand into other macros that include the line number on which the macro appeared. For example, in my OpenDoor.h header file the GENERATED_BODY() macro appears in line 15, so you can imagine that it is replaced by GENERATED_BODY_15(). If I had another occurence of GENERATED_BODY() in line 79, that occurence would be replaced by GENERATED_BODY_79(), and so on.

It is important to note that this expansion is done by Visual Studio using standard C++ language features, so Visual Studio is actually responsible for producing the GENERATED_BODY_15() macro call inside OpenDoor.h. UHT knows about this scheme, of course, and inserts the definition of GENERATED_BODY_15 into the .generated.h file. So everything works out nicely.

But what happens when we insert a blank line at the start of the file?

Suddenly the GENERATED_BODY() appears no longer in line 15 but in line 16. Visual Studio, rightly, thinks that it should therefore expand the macro to GENERATED_BODY_16(). But the .generated.h file is only regenerated when UHT runs, so it still contains the definition of GENERATED_BODY_15(), not the one we now need. Visual Studio therefore no longer knows about all the goodies that Unreal defines for us, and your carefully crafted code turns into a mess of red squiggles and warnings.

I hope that the solution has by now become pretty obvious: Just recompile the header; the Unreal Build Tool will figure out that something has changed, call UHT to re-generate the .generated.h file and life will be good again.

Except that, well, sometimes this doesn’t help.

The reason for that seems to be that the generated headers live in the Intermediate folder, and depending on your version of UE4 and Visual Studio, sometimes VS doesn’t seem to realize that new versions of files in Intermediate have become available. In that case, right clicking inside the source of the offending header in VS and selecting Rescan -> Rescan File solves the problem quite reliably with recent versions of VS and UE4.

Edit: It might be that even re-scanning the file does not make the squiggles go away. In that case you’ll need to add a cpp.hint file to your project that simplifies the UE4 macros for Visual Studio.

OK, that was probably way more than you bargained for. I hope it helps, though.

2 Likes

This is some very helpful information. Thank you for taking the time to share!

Great info, thanks again.