ProjectID
ProjectID
#Overview
name: ProjectID
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 24
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of ProjectID is to provide a unique identifier for the project. This setting variable is primarily used for project identification and tracking across various Unreal Engine subsystems and tools. Here’s a detailed breakdown:
-
Unreal Engine subsystems that rely on this variable:
- Analytics systems (Engine analytics, Editor analytics)
- Project generation and management
- Blueprint editor
- Studio Telemetry
-
The value of this variable is typically set when a new project is created. It’s generated as a new GUID (Globally Unique Identifier) during project creation and stored in the project’s configuration files.
-
Other variables that interact with ProjectID:
- ProjectName
- ProjectVersion
- Other project-related settings in the GeneralProjectSettings class
-
Special considerations for developers:
- ProjectID should remain constant throughout the project’s lifecycle.
- It’s used for analytics and tracking, so changing it may affect data consistency.
- It’s stored in the project’s configuration files, so manual editing of these files should be done carefully.
-
Best practices:
- Don’t modify the ProjectID manually unless absolutely necessary.
- When cloning or forking a project, generate a new ProjectID to avoid conflicts.
- Use the ProjectID when integrating with external tools or services that need to uniquely identify the project.
- Include the ProjectID in crash reports or bug submissions to help with issue tracking.
The ProjectID is a crucial identifier for your Unreal Engine project, used across various engine systems for tracking, analytics, and project management. It’s automatically generated and managed by the engine, so in most cases, developers don’t need to interact with it directly.
#Setting Variables
#References In INI files
Location: <Workspace>/Projects/Lyra/Config/DefaultGame.ini:4, section: [/Script/EngineSettings.GeneralProjectSettings]
- INI Section:
/Script/EngineSettings.GeneralProjectSettings
- Raw value:
0537642E459369628A8717AB63363CBF
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Experimental/StudioTelemetry/Source/StudioTelemetry/Private/StudioTelemetry.cpp:103
Scope (from outer to inner):
file
function void FStudioTelemetry::StartSession
Source code excerpt:
FString ProjectIDString;
GConfig->GetString(TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectID"), ProjectIDString, GGameIni);
FGuid ProjectID;
TArray<FString> Elements;
if (ProjectIDString.ParseIntoArray(Elements, TEXT("=")) == 5)
{
ProjectID = FGuid(FCString::Atoi(*(Elements[1])), FCString::Atoi(*(Elements[2])), FCString::Atoi(*(Elements[3])), FCString::Atoi(*(Elements[4])));
}
FGuid SessionID;
FPlatformMisc::CreateGuid(SessionID);
FString SessionLabel;
#Loc: <Workspace>/Engine/Plugins/Experimental/StudioTelemetry/Source/StudioTelemetry/Private/StudioTelemetry.cpp:121
Scope (from outer to inner):
file
function void FStudioTelemetry::StartSession
Source code excerpt:
// Set the default event attributes
DefaultEventAttributes.Emplace(TEXT("ProjectName"), ProjectName);
DefaultEventAttributes.Emplace(TEXT("ProjectID"), ProjectID);
DefaultEventAttributes.Emplace(TEXT("Session_ID"), SessionID.ToString(EGuidFormats::DigitsWithHyphensInBraces));
DefaultEventAttributes.Emplace(TEXT("Session_Label"), SessionLabel);
DefaultEventAttributes.Emplace(TEXT("Session_StartUTC"), FDateTime::UtcNow().ToUnixTimestampDecimal());
DefaultEventAttributes.Emplace(TEXT("Build_Configuration"), LexToString(FApp::GetBuildConfiguration()));
#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:836
Scope (from outer to inner):
file
function bool GameProjectUtils::CreateProject
Source code excerpt:
SlowTask.MakeDialog();
TOptional<FGuid> ProjectID;
FString TemplateName;
if ( InProjectInfo.TemplateFile.IsEmpty() )
{
ProjectID = GenerateProjectFromScratch(InProjectInfo, OutFailReason, OutFailLog);
TemplateName = InProjectInfo.bShouldGenerateCode ? TEXT("Basic Code") : TEXT("Blank");
}
else
{
ProjectID = CreateProjectFromTemplate(InProjectInfo, OutFailReason, OutFailLog, OutCreatedFiles);
TemplateName = FPaths::GetBaseFilename(InProjectInfo.TemplateFile);
}
bool bProjectCreationSuccessful = ProjectID.IsSet();
if (!bProjectCreationSuccessful && CleanupIsEnabled())
{
// Delete the new project folder
const FString NewProjectFolder = FPaths::GetPath(InProjectInfo.ProjectFilename);
IFileManager::Get().DeleteDirectory(*NewProjectFolder, /*RequireExists=*/false, /*Tree=*/true);
#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:869
Scope (from outer to inner):
file
function bool GameProjectUtils::CreateProject
Source code excerpt:
EventAttributes.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), InProjectInfo.bShouldGenerateCode ? TEXT("C++ Code") : TEXT("Content Only")));
EventAttributes.Add(FAnalyticsEventAttribute(TEXT("Outcome"), bProjectCreationSuccessful ? TEXT("Successful") : TEXT("Failed")));
EventAttributes.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), *(bProjectCreationSuccessful ? ProjectID.GetValue().ToString() : FString())));
if (InProjectInfo.TargetedHardware.IsSet())
{
UEnum* HardwareClassEnum = StaticEnum<EHardwareClass>();
if (HardwareClassEnum != nullptr)
{
#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1379
Scope (from outer to inner):
file
function TOptional<FGuid> GameProjectUtils::GenerateProjectFromScratch
Source code excerpt:
ResetCurrentProjectModulesCache();
FGuid ProjectID;
// Generate config files
if (!GenerateConfigFiles(InProjectInfo, CreatedFiles, OutFailReason, ProjectID))
{
return TOptional<FGuid>();
}
// Insert any required feature packs (EG starter content) into ini file. These will be imported automatically when the editor is first run
if(!InsertFeaturePacksIntoINIFile(InProjectInfo, OutFailReason))
#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1484
Scope (from outer to inner):
file
function TOptional<FGuid> GameProjectUtils::GenerateProjectFromScratch
Source code excerpt:
UE_LOG(LogGameProjectGeneration, Log, TEXT("Created new project with %d files (plus project files)"), CreatedFiles.Num());
return ProjectID;
}
static bool SaveConfigValues(const FProjectInformation& InProjectInfo, const TArray<FTemplateConfigValue>& ConfigValues, FText& OutFailReason)
{
const FString ProjectConfigPath = FPaths::GetPath(InProjectInfo.ProjectFilename) / TEXT("Config");
#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1824
Scope (from outer to inner):
file
function TOptional<FGuid> GameProjectUtils::CreateProjectFromTemplate
Source code excerpt:
TemplateDefs->AddConfigValues(ConfigValuesToSet, TemplateName, ProjectName, InProjectInfo.bShouldGenerateCode);
FGuid ProjectID = FGuid::NewGuid();
ConfigValuesToSet.Emplace(TEXT("DefaultGame.ini"), TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectID"), ProjectID.ToString(), /*InShouldReplaceExistingValue=*/true);
// Add all classname fixups
for (const TPair<FString, FString>& Rename : ClassRenames)
{
const FString ClassRedirectString = FString::Printf(TEXT("(OldClassName=\"%s\",NewClassName=\"%s\")"), *Rename.Key, *Rename.Value);
ConfigValuesToSet.Emplace(TEXT("DefaultEngine.ini"), TEXT("/Script/Engine.Engine"), TEXT("+ActiveClassRedirects"), *ClassRedirectString, /*InShouldReplaceExistingValue=*/false);
#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:1919
Scope (from outer to inner):
file
function TOptional<FGuid> GameProjectUtils::CreateProjectFromTemplate
Source code excerpt:
}
return ProjectID;
}
bool GameProjectUtils::SetEngineAssociationForForeignProject(const FString& ProjectFileName, FText& OutFailReason)
{
if(FUProjectDictionary(FPaths::RootDir()).IsForeignProject(ProjectFileName))
{
#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:926
Scope (from outer to inner):
file
function void FBlueprintEditor::AnalyticsTrackNodeEvent
Source code excerpt:
// Build Node Details
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
FString ProjectID = ProjectSettings.ProjectID.ToString();
TArray<FAnalyticsEventAttribute> NodeAttributes;
NodeAttributes.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
NodeAttributes.Add(FAnalyticsEventAttribute(TEXT("BlueprintId"), Blueprint->GetBlueprintGuid().ToString()));
TArray<TKeyValuePair<FString, FString>> Attributes;
if (UK2Node* K2Node = Cast<UK2Node>(GraphNode))
{
K2Node->GetNodeAttributes(Attributes);
#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:966
Scope (from outer to inner):
file
function void FBlueprintEditor::AnalyticsTrackCompileEvent
Source code excerpt:
// Build Node Details
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
FString ProjectID = ProjectSettings.ProjectID.ToString();
const bool bSuccess = NumErrors == 0;
TArray<FAnalyticsEventAttribute> Attributes;
Attributes.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
Attributes.Add(FAnalyticsEventAttribute(TEXT("BlueprintId"), Blueprint->GetBlueprintGuid().ToString()));
Attributes.Add(FAnalyticsEventAttribute(TEXT("Success"), bSuccess? TEXT("True") : TEXT("False")));
Attributes.Add(FAnalyticsEventAttribute(TEXT("NumErrors"), FString::FromInt(NumErrors)));
Attributes.Add(FAnalyticsEventAttribute(TEXT("NumWarnings"), FString::FromInt(NumWarnings)));
// Send Analytics event
#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:2897
Scope (from outer to inner):
file
function FBlueprintEditor::~FBlueprintEditor
Source code excerpt:
{
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
FString ProjectID = ProjectSettings.ProjectID.ToString();
TArray<FAnalyticsEventAttribute> BPEditorAttribs;
BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("GraphActionMenusExecuted.NonContextSensitive"), AnalyticsStats.GraphActionMenusNonCtxtSensitiveExecCount));
BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("GraphActionMenusExecuted.ContextSensitive"), AnalyticsStats.GraphActionMenusCtxtSensitiveExecCount));
BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("GraphActionMenusClosed"), AnalyticsStats.GraphActionMenusCancelledCount));
#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:2911
Scope (from outer to inner):
file
function FBlueprintEditor::~FBlueprintEditor
Source code excerpt:
BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("PastedNodesCreated"), AnalyticsStats.NodePasteCreateCount));
BPEditorAttribs.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.Usage.BlueprintEditorSummary"), BPEditorAttribs);
for (auto Iter = AnalyticsStats.GraphDisallowedPinConnections.CreateConstIterator(); Iter; ++Iter)
{
TArray<FAnalyticsEventAttribute> BPEditorPinConnectAttribs;
BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("FromPin.Category"), Iter->PinTypeCategoryA));
#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:2925
Scope (from outer to inner):
file
function FBlueprintEditor::~FBlueprintEditor
Source code excerpt:
BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("ToPin.IsReference"), Iter->bPinIsReferenceB));
BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("ToPin.IsWeakPointer"), Iter->bPinIsWeakPointerB));
BPEditorPinConnectAttribs.Add(FAnalyticsEventAttribute(TEXT("ProjectId"), ProjectID));
FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.Usage.BPDisallowedPinConnection"), BPEditorPinConnectAttribs);
}
}
SaveEditorSettings();
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Analytics/EditorAnalytics.cpp:25
Scope (from outer to inner):
file
function void FEditorAnalytics::ReportEvent
Source code excerpt:
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
TArray<FAnalyticsEventAttribute> ParamArray;
ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString()));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("Platform"), PlatformName));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), bHasCode ? TEXT("C++ Code") : TEXT("Content Only")));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("VanillaEditor"), (GEngine && GEngine->IsVanillaProduct()) ? TEXT("Yes") : TEXT("No")));
ParamArray.Append(ExtraParams);
FEngineAnalytics::GetProvider().RecordEvent( EventName, ParamArray );
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Analytics/EditorAnalytics.cpp:41
Scope (from outer to inner):
file
function void FEditorAnalytics::ReportEvent
Source code excerpt:
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
TArray<FAnalyticsEventAttribute> ParamArray;
ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString()));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("Platform"), PlatformName));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), bHasCode ? TEXT("C++ Code") : TEXT("Content Only")));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("VanillaEditor"), (GEngine && GEngine->IsVanillaProduct()) ? TEXT("Yes") : TEXT("No")));
ParamArray.Add(FAnalyticsEventAttribute(TEXT("ErrorCode"), ErrorCode));
const FString ErrorMessage = TranslateErrorCode(ErrorCode);
ParamArray.Add(FAnalyticsEventAttribute(TEXT("ErrorName"), ErrorMessage));
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Kismet2/Kismet2.cpp:593
Scope (from outer to inner):
file
function UBlueprint* FKismetEditorUtilities::CreateBlueprint
Source code excerpt:
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
Attribs.Add(FAnalyticsEventAttribute(FString("ProjectId"), ProjectSettings.ProjectID.ToString()));
Attribs.Add(FAnalyticsEventAttribute(FString("BlueprintId"), NewBP->GetBlueprintGuid().ToString()));
FEngineAnalytics::GetProvider().RecordEvent(FString("Editor.Usage.BlueprintCreated"), Attribs);
}
return NewBP;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:657
Scope (from outer to inner):
file
function void FUnrealEdMisc::InitEngineAnalytics
Source code excerpt:
TArray< FAnalyticsEventAttribute > ProjectAttributes;
ProjectAttributes.Add( FAnalyticsEventAttribute( FString( "Name" ), *GetDefault<UGeneralProjectSettings>()->ProjectName ));
ProjectAttributes.Add( FAnalyticsEventAttribute( FString( "Id" ), *GetDefault<UGeneralProjectSettings>()->ProjectID.ToString() ));
FGameProjectGenerationModule& GameProjectModule = FModuleManager::LoadModuleChecked<FGameProjectGenerationModule>(TEXT("GameProjectGeneration"));
bool bShouldIncludeSourceFileCountAndSize = true;
GConfig->GetBool(TEXT("EngineAnalytics"), TEXT("IncludeSourceFileCountAndSize"), bShouldIncludeSourceFileCountAndSize, GEditorIni);
if (bShouldIncludeSourceFileCountAndSize)
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:873
Scope (from outer to inner):
file
function void FUnrealEdMisc::TickAssetAnalytics
Source code excerpt:
}
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
AssetAttributes.Add( FAnalyticsEventAttribute( FString( "ProjectId" ), *ProjectSettings.ProjectID.ToString() ));
AssetAttributes.Add( FAnalyticsEventAttribute( FString( "AssetPackageCount" ), PackageNames.Num() ));
AssetAttributes.Add( FAnalyticsEventAttribute( FString( "Maps" ), NumMapFiles ));
AssetAttributes.Emplace( TEXT("Enterprise"), IProjectManager::Get().IsEnterpriseProject() );
// Send project analytics
FEngineAnalytics::GetProvider().RecordEvent( FString( "Editor.Usage.AssetCounts" ), AssetAttributes );
TArray< FAnalyticsEventAttribute > AssetInstances;
AssetInstances.Add( FAnalyticsEventAttribute( FString( "ProjectId" ), *ProjectSettings.ProjectID.ToString() ));
for( auto ClassIter = ClassInstanceCounts.CreateIterator(); ClassIter; ++ClassIter )
{
AssetInstances.Add( FAnalyticsEventAttribute( ClassIter.Key().ToString(), ClassIter.Value() ) );
}
// Send class instance analytics
FEngineAnalytics::GetProvider().RecordEvent( FString( "Editor.Usage.AssetClasses" ), AssetInstances );
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1018
Scope (from outer to inner):
file
function void FUnrealEdMisc::OnExit
Source code excerpt:
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
TabsAttribs.Add(FAnalyticsEventAttribute(FString("ProjectId"), ProjectSettings.ProjectID.ToString()));
FEngineAnalytics::GetProvider().RecordEvent(FString("Editor.Usage.WindowCounts"), TabsAttribs);
// Report asset updates (to reflect forward progress made by the user)
TArray<FAnalyticsEventAttribute> AssetUpdateCountAttribs;
for (auto& UpdatedAssetPair : NumUpdatesByAssetName)
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1199
Scope (from outer to inner):
file
function void FUnrealEdMisc::PreSaveWorld
Source code excerpt:
BrushAttributes.Add( FAnalyticsEventAttribute( FString( "Subtractive" ), NumSubtractiveBrushes ));
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
BrushAttributes.Add( FAnalyticsEventAttribute( FString( "ProjectId" ), ProjectSettings.ProjectID.ToString()) );
FEngineAnalytics::GetProvider().RecordEvent( FString( "Editor.Usage.Brushes" ), BrushAttributes );
}
void FUnrealEdMisc::CB_MapChange( uint32 InFlags )
{
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1268
Scope (from outer to inner):
file
function void FUnrealEdMisc::CB_LevelActorsAdded
Source code excerpt:
{
const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>();
FEngineAnalytics::GetProvider().RecordEvent(FString("Editor.Usage.PawnPlacement"), FString( "ProjectId" ), ProjectSettings.ProjectID.ToString());
}
}
void FUnrealEdMisc::CB_PreAutomationTesting()
{
// Shut down SCC if it's enabled, as unit tests shouldn't be allowed to make any modifications to source control
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Analytics/EngineAnalyticsSessionSummary.cpp:180
Scope (from outer to inner):
file
function FEngineAnalyticsSessionSummary::FEngineAnalyticsSessionSummary
Source code excerpt:
Store->Set(TEXT("GRHIAdapterMemory"), static_cast<uint64>(TextureMemStats.DedicatedVideoMemory));
Store->Set(TEXT("ProjectName"), EngineAnalyticsProperties::GetProjectName(ProjectSettings));
Store->Set(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString(EGuidFormats::DigitsWithHyphens));
Store->Set(TEXT("ProjectDescription"), ProjectSettings.Description);
Store->Set(TEXT("ProjectVersion"), ProjectSettings.ProjectVersion);
Store->Set(TEXT("EngineVersion"), FEngineVersion::Current().ToString(EVersionComponent::Changelist));
Store->Set(TEXT("CommandLine"), FString(FCommandLine::GetForLogging()));
Store->Set(TEXT("MonitorPid"), CrcProcessId); // CrashReportClient acts as the monitoring/reporting process.
Store->Set(TEXT("Plugins"), FString::Join(PluginNames, TEXT(",")));
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/EngineAnalytics.cpp:248
Scope (from outer to inner):
file
function void FEngineAnalytics::AppendMachineStats
Source code excerpt:
// Add project info whether we are in editor or game.
EventAttributes.Emplace(TEXT("ProjectName"), ProjectSettings.ProjectName);
EventAttributes.Emplace(TEXT("ProjectID"), ProjectSettings.ProjectID);
EventAttributes.Emplace(TEXT("ProjectDescription"), ProjectSettings.Description);
EventAttributes.Emplace(TEXT("ProjectVersion"), ProjectSettings.ProjectVersion);
EventAttributes.Emplace(TEXT("Application.Commandline"), FCommandLine::Get());
EventAttributes.Emplace(TEXT("Build.Configuration"), LexToString(FApp::GetBuildConfiguration()));
EventAttributes.Emplace(TEXT("Build.IsInternalBuild"), FEngineBuildSettings::IsInternalBuild());
EventAttributes.Emplace(TEXT("Build.IsPerforceBuild"), FEngineBuildSettings::IsPerforceBuild());
#Loc: <Workspace>/Engine/Source/Runtime/EngineSettings/Classes/GeneralProjectSettings.h:45
Scope (from outer to inner):
file
class class UGeneralProjectSettings : public UObject
Source code excerpt:
/** The project's unique identifier. */
UPROPERTY(config, EditAnywhere, Category=About)
FGuid ProjectID;
/** The project's non-localized name. */
UPROPERTY(config, EditAnywhere, Category=About)
FString ProjectName;
/** The project's version number. */