Explanation of Source Code folder structure?

In the shooter example, I see folders like Public which has ShooterGame.h.
Then I see Classes which has the game class header files.
Then I see a Private folder which has the .cpp files.

However, when Unreal Editor adds a source file, it adds the files to the root of the source folder without an option to place the file in a folder and keep things organized. It would be nice to be able to do that by the way without having to manually move the file and then call the rebuild project files script.

So I started moving files around in the project to make things more organized like in ShooterGame and the compiler started complaining about not seeing the header files. This makes sense because I need to say

#include “Characters/Player/MyGamePlayer.h”

After doing that the code compiled.

But then I saw that ShooterGame didn’t explicitly write out the full folder paths. I tried putting my source files into the same kind of folder structure. I had my header files in the Public folders and the .cpp files in the Private folders. I removed the full paths from my header file includes, and added

#include “MyGameClasses.h”

To the main module header file. Suddenly things compiled no problem. So it seems like the build system is able to see header files without the full path being used if I put them in a folder called Public. I couldn’t find a precise explanation of how this works anywhere, and I’d like it if the unreal editor gave me the option of automatically placing the files in the right locations.

The closest I found is in the style guidelines where it talks about keeping code that can be exposed in the Public folder and code that shouldn’t be exposed in the Private folder. Epic C++ Coding StandardBlueprint Debugging in Unreal Engine | Unreal Engine Documentation

The Public folder is for things that will be exposed from your module. For a game this doesn’t really matter since nothing else will be using it, but it’s important if you ever make an engine or editor module.

The Private folder is for anything that is not exposed. This is all your source files, as well as any header files that aren’t needed by a public interface.

The Classes folder is a semi-legacy thing. This is where the UObject types used to go as it was the only place the UHT would parse. UHT now parses all three folders, so your UObject types can go anywhere now.

All three of these folders are available on the include paths for your module (which is why your include worked after you moved the header to Public). Please note though that things inside the Private folder can only be included by other things inside the Private folder; trying to include something from Private in a Public/Classes header is an error.

If you link to another module via the UBT, only the headers in the Public folder (probably the Classes folder too) of that module will be available to you to include.

If you want to add extra paths in your module to your include paths, you can do this with the PublicIncludePaths and PrivateIncludePaths arrays in your Build.cs file (see ShooterGame.Build.cs).

I would like to add that PublicIncludePaths is not needed for sub-folders in the module itself. All of a module’s public folders are auto-detected by UBT.

This is not true for private sub-folders, however. If you have a sub-folder structure within Private, you must add each of them to the PrivateIncludePaths array, or otherwise the compiler will not find your private header files.

Just a question. In the Plugin documentation I read

“Plugins are allowed to declare new
UObject types (UCLASS, USTRUCT, etc)
in header files in a Classes
subdirectory in their module code
folders.”

This is still mandatory for plugins or, as you said, “UHT now parses all three folders, so your UObject types can go anywhere now.”? :slight_smile:

That’s no longer required as far as I am aware.

You should be able to put your UObject types anywhere now (which is great, since it lets implementation specific UObject types be hidden from outside the module via the Private folder; something that wasn’t possible with the Classes folder).

Great answer, bravo!