HCProduct_Tirsova/UE5_BP_to_CPP_Packaging_Guide.md

243 lines
9.3 KiB
Markdown
Raw Permalink Normal View History

2026-04-22 18:53:45 +02:00
# UE5 Blueprint-to-C++ Project Conversion & Packaging Fix Guide
## Problem
When you copy an Unreal Engine 5 Blueprint-only project to a new machine, "Package Project" does nothing -- no error in the UI, no output. The log shows:
```
LogProjectPackagingSettings: UProjectPackagingSettings FindBestTargetInfo for '' resulted in null FTargetInfo*.
Listing targets that were searched:
End of target list.
```
This happens because:
1. The project has no `Source/` directory (BP-only projects auto-generate source in `Intermediate/Source/` during packaging)
2. Stale configs from the original machine override local settings
3. The editor can't discover build targets without compiled `.target` metadata files
## Step-by-Step Fix
### 1. Add Modules to .uproject
The `.uproject` file MUST declare a Modules section. Without it, the editor won't look for `.target` files in `Binaries/` and the target list will always be empty.
Add this before the `"Plugins"` array:
```json
{
"FileVersion": 3,
"EngineAssociation": "5.7",
"Modules": [
{
"Name": "YourProjectName",
"Type": "Runtime",
"LoadingPhase": "Default"
}
],
"Plugins": [
...
]
}
```
> **Critical:** Without this section, even if `.target` files exist in `Binaries/`, the editor's `FindBestTargetInfo` will return an empty target list.
### 2. Create Source/ Directory
Create the following structure at the project root:
```
Source/
YourProjectName.Target.cs (Game target)
YourProjectNameEditor.Target.cs (Editor target)
YourProjectName/
YourProjectName.Build.cs (Module build rules)
YourProjectName.cpp (Module implementation)
```
**YourProjectName.Target.cs:**
```csharp
using UnrealBuildTool;
public class YourProjectNameTarget : TargetRules
{
public YourProjectNameTarget(TargetInfo Target) : base(Target)
{
DefaultBuildSettings = BuildSettingsVersion.Latest;
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
Type = TargetType.Game;
ExtraModuleNames.Add("YourProjectName");
}
}
```
**YourProjectNameEditor.Target.cs:**
```csharp
using UnrealBuildTool;
public class YourProjectNameEditorTarget : TargetRules
{
public YourProjectNameEditorTarget(TargetInfo Target) : base(Target)
{
DefaultBuildSettings = BuildSettingsVersion.Latest;
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
Type = TargetType.Editor;
ExtraModuleNames.Add("YourProjectName");
}
}
```
**YourProjectName/YourProjectName.Build.cs:**
```csharp
using UnrealBuildTool;
public class YourProjectName : ModuleRules
{
public YourProjectName(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PrivateDependencyModuleNames.Add("Core");
}
}
```
**YourProjectName/YourProjectName.cpp:**
```cpp
#include "CoreTypes.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultModuleImpl, YourProjectName, "YourProjectName");
```
### 3. Build Both Targets from Command Line
Close the editor, then build from terminal:
```batch
:: Build Editor target (needed to open the project)
"C:\Program Files\Epic Games\UE_5.7\Engine\Build\BatchFiles\Build.bat" YourProjectNameEditor Win64 Development "C:\Path\To\YourProject.uproject" -WaitMutex
:: Build Game target (needed for packaging -- THIS IS THE ONE PEOPLE FORGET)
"C:\Program Files\Epic Games\UE_5.7\Engine\Build\BatchFiles\Build.bat" YourProjectName Win64 Shipping "C:\Path\To\YourProject.uproject" -WaitMutex
```
> **Critical:** You must build BOTH targets. The Editor build creates `Simulore_TirsovaEditor.target`, and the Game build creates `Simulore_Tirsova-Win64-Shipping.target`. The packaging system only looks for Game-type targets. If you only build the Editor target, the target list will still be empty.
### 4. Clean Stale Data from Copied Project
When a project is copied from another machine, these directories contain stale/incompatible data:
| Directory | Safe to delete | Regenerated by |
|---|---|---|
| `Intermediate/` | Yes | Editor on startup |
| `Binaries/` | Yes | Build step above |
| `DerivedDataCache/` | Yes | Editor on startup |
| `Saved/StagedBuilds/` | Yes | Packaging process |
| `Saved/Cooked/` | Yes | Cooking process |
| `Saved/Crashes/` | Yes | Not regenerated (just old logs) |
| `Saved/Temp/` | Yes | Editor on startup |
**Never delete:** `Config/`, `Content/`, `Source/`, `.uproject`, `Saved/Config/` (fix it instead)
### 5. Fix Hardcoded Paths (THE SILENT KILLER)
Copied projects contain paths from the original machine in multiple locations. Check ALL of these:
#### 5a. Config/DefaultGame.ini
```ini
[/Script/UnrealEd.ProjectPackagingSettings]
BuildTarget=YourProjectName
StagingDirectory=(Path="") ; <-- was hardcoded to other user's Desktop
```
#### 5b. Saved/Config/WindowsEditor/Game.ini (HIGHEST PRIORITY -- overrides DefaultGame.ini!)
This is the one that actually matters for packaging. The editor reads this file, not DefaultGame.ini:
```ini
[/Script/DeveloperToolSettings.PlatformsMenuSettings]
StagingDirectory=(Path="") ; <-- fix this
CookBuildTarget=YourProjectName ; <-- was empty
PackageBuildTarget=YourProjectName ; <-- was empty (ROOT CAUSE of "no targets")
```
> **This was the hardest bug to find.** `DefaultGame.ini` has `BuildTarget=YourProjectName` but the editor actually reads `PackageBuildTarget` from `Saved/Config/WindowsEditor/Game.ini`, which has higher priority. If this is empty, the editor passes an empty string to `FindBestTargetInfo`.
#### 5c. Saved/Config/WindowsEditor/EditorPerProjectUserSettings.ini
Search for and fix any paths referencing other machines:
```ini
SwarmIntermediateFolder= ; <-- was C:/Users/OtherUser/...
LastExecutedLaunchDevice= ; <-- was Windows@OTHER-PC
LastExecutedLaunchName= ; <-- was OTHER-PC
```
#### Quick way to find all stale paths:
```bash
grep -rn "C:/Users/" Config/ Saved/Config/ --include="*.ini" | grep -v "prime"
```
Replace `prime` with the current username.
## UE5 Config Priority System
Understanding this prevents hours of debugging:
| Priority | Source | Hex |
|---|---|---|
| 1 (lowest) | Constructor defaults | 0x00 |
| 2 | Scalability (BaseScalability.ini tiers) | 0x01 |
| 3 | GameUserSettings (in-game quality menu) | 0x02 |
| 4 | ProjectSettings (`[/Script/Engine.RendererSettings]`) | 0x03 |
| 5 | **`[SystemSettings]` and `[ConsoleVariables]` in DefaultEngine.ini** | 0x04 |
| 6 | Device Profiles | 0x05 |
| 7 | Standalone ConsoleVariables.ini (NOT loaded in Shipping!) | 0x06 |
| 8 | Command line | 0x07 |
| 9 | C++ code Set() | 0x08 |
| 10 (highest) | In-game console (~) | 0x09 |
### Where to put rendering overrides:
- **`[/Script/Engine.RendererSettings]`** -- Project-level feature toggles (Lumen on/off, RayTracing on/off, VSM on/off). These affect shader compilation.
- **`[SystemSettings]`** -- Runtime quality overrides that must survive scalability and device profile changes. Use this for forced quality settings in packaged builds.
- **`[ConsoleVariables]`** -- Same priority as SystemSettings. Good for non-rendering cvars (shader pipeline cache, etc).
- **`DefaultGameUserSettings.ini` `[ScalabilityGroups]`** -- Default scalability levels for first-time users. Gets overridden by hardware auto-detect on first run.
### Scalability override gotcha:
If you set `sg.ShadowQuality=3` in `[ScalabilityGroups]` AND `r.Shadow.MaxResolution=512` in `[SystemSettings]`, the scalability system will apply its shadow preset values first, then `[SystemSettings]` overrides specific cvars. Your individual settings win because they have higher priority.
**However:** Device Profiles (priority 0x05) can override `[SystemSettings]` (priority 0x04). If you see cvars being overridden, check `Saved/Config/WindowsEditor/` for device profile configs. The WindowsEditor device profile commonly overrides shadow and scalability settings.
## Packaging from Command Line (Bypass Editor UI)
If the editor UI still refuses to package, use RunUAT directly:
```batch
"C:\Program Files\Epic Games\UE_5.7\Engine\Build\BatchFiles\RunUAT.bat" BuildCookRun ^
-project="C:\Path\To\YourProject.uproject" ^
-platform=Win64 ^
-clientconfig=Shipping ^
-cook -build -stage -package -pak ^
-prereqs -compressed ^
-target=YourProjectName ^
-unrealexe="C:\Program Files\Epic Games\UE_5.7\Engine\Binaries\Win64\UnrealEditor-Cmd.exe"
```
This bypasses the editor's target discovery entirely and invokes UnrealBuildTool + cooker directly.
## Checklist Summary
When transferring a BP-only UE5 project to a new machine:
- [ ] Add `"Modules"` section to `.uproject`
- [ ] Create `Source/` with Target.cs, Build.cs, and .cpp files
- [ ] Build Editor target from command line
- [ ] Build Game target (Shipping) from command line
- [ ] Delete `Intermediate/`, `Binaries/` (before building), `DerivedDataCache/`, `Saved/StagedBuilds/`, `Saved/Cooked/`
- [ ] Fix `Config/DefaultGame.ini` -- `BuildTarget`, `StagingDirectory`
- [ ] Fix `Saved/Config/WindowsEditor/Game.ini` -- `PackageBuildTarget`, `CookBuildTarget`, `StagingDirectory`
- [ ] Fix `Saved/Config/WindowsEditor/EditorPerProjectUserSettings.ini` -- remove other machine's paths
- [ ] Grep all .ini files for hardcoded paths from other machines
- [ ] Open editor, verify Platforms > Windows > Package Project works