PlatformGroupName

PlatformGroupName

#Overview

name: PlatformGroupName

The value of this variable can be defined or overridden in .ini config files. 8 .ini config files referencing this setting variable.

It is referenced in 31 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of PlatformGroupName is to group similar platforms together for use in per-platform override properties in Unreal Engine 5.

PlatformGroupName is primarily used in the engine’s platform configuration and customization systems. It serves as an identifier to categorize platforms into broader groups such as “Desktop”, “Mobile”, or “Console”. This grouping allows developers to apply settings or properties across multiple related platforms more efficiently.

Key points about PlatformGroupName:

  1. It is part of the FDataDrivenPlatformInfo structure, which contains various platform-specific information.

  2. It is used in multiple subsystems, including rendering, LOD (Level of Detail) management, and asset cooking processes.

  3. The value is typically set in platform-specific configuration files and loaded during engine initialization.

  4. It’s heavily utilized in the editor for customizing platform-specific properties, especially in areas like LOD settings for static and skeletal meshes.

  5. In the build process, it’s used to determine certain behaviors, such as stripping LOD data during cooking for desktop platforms.

  6. It plays a crucial role in the per-platform property override system, allowing developers to set different values for properties based on platform groups rather than individual platforms.

When using PlatformGroupName, developers should be aware that:

  1. Changes to this value can have wide-ranging effects across the engine, potentially affecting how assets are processed, how LODs are managed, and how certain platform-specific optimizations are applied.

  2. It’s important to maintain consistency in platform group naming across different parts of the engine to ensure proper functionality of the override systems.

  3. Custom platforms or platform groups may need to be properly configured to work correctly with existing systems that rely on PlatformGroupName.

Best practices when working with PlatformGroupName include:

  1. Always refer to the official Unreal Engine documentation for the most up-to-date information on platform groups and their intended uses.

  2. When creating custom platforms, ensure that the PlatformGroupName is set appropriately to leverage existing group-based functionality.

  3. Use the per-platform property system consistently when developing features that need to behave differently across platform groups.

  4. Be cautious when modifying existing platform group assignments, as this can have far-reaching consequences in terms of how the engine processes assets and applies settings.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/Android/DataDrivenPlatformInfo.ini:21, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Config/IOS/DataDrivenPlatformInfo.ini:25, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Config/Linux/DataDrivenPlatformInfo.ini:25, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Config/LinuxArm64/DataDrivenPlatformInfo.ini:28, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Config/Mac/DataDrivenPlatformInfo.ini:24, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Config/TVOS/DataDrivenPlatformInfo.ini:17, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Config/Windows/DataDrivenPlatformInfo.ini:31, section: [DataDrivenPlatformInfo]

Location: <Workspace>/Engine/Platforms/VisionOS/Config/DataDrivenPlatformInfo.ini:17, section: [DataDrivenPlatformInfo]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/ChaosClothAsset/Source/ChaosClothAssetEngine/Private/ChaosClothAsset/ClothAsset.cpp:764

Scope (from outer to inner):

file
function     FString UChaosClothAsset::BuildDerivedDataKey

Source code excerpt:

	//}

	//if (TargetPlatform->GetPlatformInfo().PlatformGroupName == TEXT("Desktop")
	//	&& GStripSkeletalMeshLodsDuringCooking != 0
	//	&& GSkeletalMeshKeepMobileMinLODSettingOnDesktop != 0)
	//{
	//	KeySuffix += TEXT("_MinMLOD");
	//}

#Loc: <Workspace>/Engine/Source/Developer/DesktopPlatform/Private/PlatformInfo.cpp:99

Scope (from outer to inner):

file
namespace    PlatformInfo
function     FTargetPlatformInfo::FTargetPlatformInfo

Source code excerpt:


	// update various arrays
	if (DataDrivenPlatformInfo->PlatformGroupName != NAME_None)
	{
		AllPlatformGroupNames.AddUnique(DataDrivenPlatformInfo->PlatformGroupName);
	}

	AllPlatformInfoArray.Add(this);
	if (VanillaInfo == this)
	{
		VanillaPlatformInfoArray.Add(this);

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:57

Scope (from outer to inner):

file
function     void FPerPlatformPropertyCustomization<PerPlatformType>::CustomizeChildren
lambda-function

Source code excerpt:

	Args.OnAddPlatformOverride = FOnPlatformOverrideAction::CreateSP(this, &FPerPlatformPropertyCustomization<PerPlatformType>::AddPlatformOverride, StructPropertyHandle);
	Args.OnRemovePlatformOverride = FOnPlatformOverrideAction::CreateSP(this, &FPerPlatformPropertyCustomization<PerPlatformType>::RemovePlatformOverride, StructPropertyHandle);
	Args.OnGenerateWidgetForPlatformRow = FOnGenerateWidget::CreateLambda([this, StructPropertyHandle, &StructBuilder](FName PlatformGroupName)
	{
		return GetWidget(PlatformGroupName, StructPropertyHandle, StructBuilder);
	});
	Args.IsEnabled = TAttribute<bool>::CreateLambda([StructPropertyHandle]()
	{		
		return StructPropertyHandle->IsEditable();
	});		
	

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:71

Scope (from outer to inner):

file
function     TSharedRef<SWidget> FPerPlatformPropertyCustomization<PerPlatformType>::GetWidget

Source code excerpt:


template<typename PerPlatformType>
TSharedRef<SWidget> FPerPlatformPropertyCustomization<PerPlatformType>::GetWidget(FName PlatformGroupName, TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder) const
{
	TSharedPtr<IPropertyHandle>	EditProperty;

	if (PlatformGroupName == NAME_None)
	{
		EditProperty = StructPropertyHandle->GetChildHandle(FName("Default"));
	}
	else
	{
		TSharedPtr<IPropertyHandle>	MapProperty = StructPropertyHandle->GetChildHandle(FName("PerPlatform"));

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:95

Scope (from outer to inner):

file
function     TSharedRef<SWidget> FPerPlatformPropertyCustomization<PerPlatformType>::GetWidget

Source code excerpt:

					{
						FName KeyName;
						if(KeyProperty->GetValue(KeyName) == FPropertyAccess::Success && KeyName == PlatformGroupName)
						{
							EditProperty = ChildProperty;
							break;
						}
					}
				}

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:138

Scope (from outer to inner):

file
function     bool FPerPlatformPropertyCustomization<PerPlatformType>::AddPlatformOverride

Source code excerpt:


template<typename PerPlatformType>
bool FPerPlatformPropertyCustomization<PerPlatformType>::AddPlatformOverride(FName PlatformGroupName, TSharedRef<IPropertyHandle> StructPropertyHandle)
{
	FScopedTransaction Transaction(LOCTEXT("AddPlatformOverride", "Add Platform Override"));

	TSharedPtr<IPropertyHandle>	PerPlatformProperty = StructPropertyHandle->GetChildHandle(FName("PerPlatform"));
	TSharedPtr<IPropertyHandle>	DefaultProperty = StructPropertyHandle->GetChildHandle(FName("Default"));
	if (PerPlatformProperty.IsValid() && DefaultProperty.IsValid())

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:164

Scope (from outer to inner):

file
function     bool FPerPlatformPropertyCustomization<PerPlatformType>::AddPlatformOverride

Source code excerpt:

						{
							// Set Key
							KeyProperty->SetValue(PlatformGroupName);

							// Set Value
							FString PropertyValueString;
							DefaultProperty->GetValueAsFormattedString(PropertyValueString);
							ChildProperty->SetValueFromFormattedString(PropertyValueString);

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:182

Scope (from outer to inner):

file
function     bool FPerPlatformPropertyCustomization<PerPlatformType>::RemovePlatformOverride

Source code excerpt:


template<typename PerPlatformType>
bool FPerPlatformPropertyCustomization<PerPlatformType>::RemovePlatformOverride(FName PlatformGroupName, TSharedRef<IPropertyHandle> StructPropertyHandle)
{
	FScopedTransaction Transaction(LOCTEXT("RemovePlatformOverride", "Remove Platform Override"));

	TSharedPtr<IPropertyHandle>	MapProperty = StructPropertyHandle->GetChildHandle(FName("PerPlatform"));
	if (MapProperty.IsValid())
	{

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:199

Scope (from outer to inner):

file
function     bool FPerPlatformPropertyCustomization<PerPlatformType>::RemovePlatformOverride

Source code excerpt:

			for (FName PlatformName : KeyArray)
			{
				if (PlatformName == PlatformGroupName)
				{
					PerPlatformMap->Remove(PlatformName);

					return true;
				}
			}

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/PerPlatformPropertyCustomization.cpp:288

Scope (from outer to inner):

file
function     void FPerPlatformPropertyCustomNodeBuilder::GenerateHeaderRowContent

Source code excerpt:

		{
			BasePlatformNameArray.AddUnique(DDPI->IniPlatformName);
			GroupToPlatform.AddUnique(DDPI->PlatformGroupName, DDPI->IniPlatformName);
			PlatformGroupNameArray.AddUnique(DDPI->PlatformGroupName);
		}
	}

	// Create section for platform groups 
	const FName PlatformGroupSection(TEXT("PlatformGroupSection"));
	AddPlatformMenuBuilder.BeginSection(PlatformGroupSection, FText::FromString(TEXT("Platform Groups")));

#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Public/PerPlatformPropertyCustomization.h:100

Scope (from outer to inner):

file
class        class FPerPlatformPropertyCustomization : public IPropertyTypeCustomization

Source code excerpt:


protected:
	TSharedRef<SWidget> GetWidget(FName PlatformGroupName, TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder) const;
	TArray<FName> GetPlatformOverrideNames(TSharedRef<IPropertyHandle> StructPropertyHandle) const;
	bool AddPlatformOverride(FName PlatformGroupName, TSharedRef<IPropertyHandle> StructPropertyHandle);
	bool RemovePlatformOverride(FName PlatformGroupName, TSharedRef<IPropertyHandle> StructPropertyHandle);

private:
	/** Cached utils used for resetting customization when layout changes */
	TWeakPtr<IPropertyUtilities> PropertyUtilities;
};

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4041

Scope (from outer to inner):

file
function     float FLevelOfDetailSettingsLayout::GetLODScreenSize

Source code excerpt:

}

float FLevelOfDetailSettingsLayout::GetLODScreenSize(FName PlatformGroupName, int32 LODIndex) const
{
	check(LODIndex < MAX_STATIC_MESH_LODS);
	UStaticMesh* Mesh = StaticMeshEditor.GetStaticMesh();
	const FPerPlatformFloat& LODScreenSize = LODScreenSizes[FMath::Clamp(LODIndex, 0, MAX_STATIC_MESH_LODS - 1)];
	float ScreenSize = LODScreenSize.Default;
	if (PlatformGroupName != NAME_None)
	{
		const float* PlatformScreenSize = LODScreenSize.PerPlatform.Find(PlatformGroupName);
		if (PlatformScreenSize != nullptr)
		{
			ScreenSize = *PlatformScreenSize;
		}
	}

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4059

Scope (from outer to inner):

file
function     float FLevelOfDetailSettingsLayout::GetLODScreenSize

Source code excerpt:

	{
		ScreenSize = Mesh->GetRenderData()->ScreenSize[LODIndex].Default;
		const float* PlatformScreenSize = Mesh->GetRenderData()->ScreenSize[LODIndex].PerPlatform.Find(PlatformGroupName);
		if (PlatformScreenSize != nullptr)
		{
			ScreenSize = *PlatformScreenSize;
		}

	}

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4069

Scope (from outer to inner):

file
function     float FLevelOfDetailSettingsLayout::GetLODScreenSize

Source code excerpt:

	{
		ScreenSize = Mesh->GetSourceModel(LODIndex).ScreenSize.Default;
		const float* PlatformScreenSize = Mesh->GetSourceModel(LODIndex).ScreenSize.PerPlatform.Find(PlatformGroupName);
		if (PlatformScreenSize != nullptr)
		{
			ScreenSize = *PlatformScreenSize;
		}
	}
	return ScreenSize;

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4088

Scope (from outer to inner):

file
function     TSharedRef<SWidget> FLevelOfDetailSettingsLayout::GetLODScreenSizeWidget

Source code excerpt:

}

TSharedRef<SWidget> FLevelOfDetailSettingsLayout::GetLODScreenSizeWidget(FName PlatformGroupName, int32 LODIndex) const
{
	return SNew(SSpinBox<float>)
		.Font(IDetailLayoutBuilder::GetDetailFont())
		.MinDesiredWidth(60.0f)
		.MinValue(0.0f)
		.MaxValue(static_cast<float>(WORLD_MAX))
		.SliderExponent(2.0f)
		.Value(this, &FLevelOfDetailSettingsLayout::GetLODScreenSize, PlatformGroupName, LODIndex)
		.OnValueChanged(const_cast<FLevelOfDetailSettingsLayout*>(this), &FLevelOfDetailSettingsLayout::OnLODScreenSizeChanged, PlatformGroupName, LODIndex)
		.OnValueCommitted(const_cast<FLevelOfDetailSettingsLayout*>(this), &FLevelOfDetailSettingsLayout::OnLODScreenSizeCommitted, PlatformGroupName, LODIndex)
		.IsEnabled(this, &FLevelOfDetailSettingsLayout::CanChangeLODScreenSize);
}

TArray<FName> FLevelOfDetailSettingsLayout::GetLODScreenSizePlatformOverrideNames(int32 LODIndex) const
{
	TArray<FName> KeyArray;

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4115

Scope (from outer to inner):

file
function     bool FLevelOfDetailSettingsLayout::AddLODScreenSizePlatformOverride

Source code excerpt:

}

bool FLevelOfDetailSettingsLayout::AddLODScreenSizePlatformOverride(FName PlatformGroupName, int32 LODIndex)
{
	FScopedTransaction Transaction(LOCTEXT("AddLODScreenSizePlatformOverride", "Add LOD Screen Size Platform Override"));
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	if (LODScreenSizes[LODIndex].PerPlatform.Find(PlatformGroupName) == nullptr)
	{
		if(!StaticMesh->bAutoComputeLODScreenSize && StaticMesh->IsSourceModelValid(LODIndex))
		{
			StaticMesh->Modify();
			float Value = StaticMesh->GetSourceModel(LODIndex).ScreenSize.Default;
			StaticMesh->GetSourceModel(LODIndex).ScreenSize.PerPlatform.Add(PlatformGroupName, Value);
			OnLODScreenSizeChanged(Value, PlatformGroupName, LODIndex);
			return true;
		}
	}
	return false;
}

bool FLevelOfDetailSettingsLayout::RemoveLODScreenSizePlatformOverride(FName PlatformGroupName, int32 LODIndex)
{
	FScopedTransaction Transaction(LOCTEXT("RemoveLODScreenSizePlatformOverride", "Remove LOD Screen Size Platform Override"));
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	if (!StaticMesh->bAutoComputeLODScreenSize && StaticMesh->IsSourceModelValid(LODIndex))
	{
		StaticMesh->Modify();
		if (StaticMesh->GetSourceModel(LODIndex).ScreenSize.PerPlatform.Remove(PlatformGroupName) != 0)
		{
			OnLODScreenSizeChanged(StaticMesh->GetSourceModel(LODIndex).ScreenSize.Default, PlatformGroupName, LODIndex);
			return true;
		}
	}
	return false;
}

void FLevelOfDetailSettingsLayout::OnLODScreenSizeChanged( float NewValue, FName PlatformGroupName, int32 LODIndex )
{
	check(LODIndex < MAX_STATIC_MESH_LODS);
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	if (!StaticMesh->bAutoComputeLODScreenSize)
	{
		// First propagate any changes from the source models to our local scratch.

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4164

Scope (from outer to inner):

file
function     void FLevelOfDetailSettingsLayout::OnLODScreenSizeChanged

Source code excerpt:

		const float MinimumDifferenceInScreenSize = KINDA_SMALL_NUMBER;
		
		if (PlatformGroupName == NAME_None)
		{
			LODScreenSizes[LODIndex].Default = NewValue;

			// Make sure we aren't trying to overlap or have more than one LOD for a value
			for (int32 i = 1; i < MAX_STATIC_MESH_LODS; ++i)
			{

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4178

Scope (from outer to inner):

file
function     void FLevelOfDetailSettingsLayout::OnLODScreenSizeChanged

Source code excerpt:

		{
			// Per-platform overrides don't have any restrictions
			float* PlatformScreenSize = LODScreenSizes[LODIndex].PerPlatform.Find(PlatformGroupName);
			if (PlatformScreenSize != nullptr)
			{
				*PlatformScreenSize = NewValue;
			}
		}

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4209

Scope (from outer to inner):

file
function     void FLevelOfDetailSettingsLayout::OnLODScreenSizeCommitted

Source code excerpt:

}

void FLevelOfDetailSettingsLayout::OnLODScreenSizeCommitted( float NewValue, ETextCommit::Type CommitType, FName PlatformGroupName, int32 LODIndex )
{
	OnLODScreenSizeChanged(NewValue, PlatformGroupName, LODIndex);
}

void FLevelOfDetailSettingsLayout::UpdateLODNames()
{
	LODNames.Empty();
	LODNames.Add( MakeShareable( new FString( LOCTEXT("BaseLOD", "LOD 0").ToString() ) ) );

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4543

Scope (from outer to inner):

file
function     TSharedRef<SWidget> FLevelOfDetailSettingsLayout::GetMinLODWidget

Source code excerpt:

}

TSharedRef<SWidget> FLevelOfDetailSettingsLayout::GetMinLODWidget(FName PlatformGroupName) const
{
	return SNew(SSpinBox<int32>)
		.Font(IDetailLayoutBuilder::GetDetailFont())
		.Value(this, &FLevelOfDetailSettingsLayout::GetMinLOD, PlatformGroupName)
		.OnValueChanged(const_cast<FLevelOfDetailSettingsLayout*>(this), &FLevelOfDetailSettingsLayout::OnMinLODChanged, PlatformGroupName)
		.OnValueCommitted(const_cast<FLevelOfDetailSettingsLayout*>(this), &FLevelOfDetailSettingsLayout::OnMinLODCommitted, PlatformGroupName)
		.MinValue(0)
		.MaxValue(MAX_STATIC_MESH_LODS)
		.ToolTipText(this, &FLevelOfDetailSettingsLayout::GetMinLODTooltip)
		.IsEnabled(FLevelOfDetailSettingsLayout::GetLODCount() > 1);
}

bool FLevelOfDetailSettingsLayout::AddMinLODPlatformOverride(FName PlatformGroupName)
{
	FScopedTransaction Transaction(LOCTEXT("AddMinLODPlatformOverride", "Add Min LOD Platform Override"));
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	check(StaticMesh);
	StaticMesh->Modify();
	if (StaticMesh->GetMinLOD().PerPlatform.Find(PlatformGroupName) == nullptr)
	{
		FPerPlatformInt MinLOD = StaticMesh->GetMinLOD();
		int32 Value = MinLOD.Default;
		MinLOD.PerPlatform.Add(PlatformGroupName, Value);
		StaticMesh->SetMinLOD(MoveTemp(MinLOD));
		OnMinLODChanged(Value, PlatformGroupName);
		return true;
	}
	return false;
}

bool FLevelOfDetailSettingsLayout::RemoveMinLODPlatformOverride(FName PlatformGroupName)
{
	FScopedTransaction Transaction(LOCTEXT("RemoveMinLODPlatformOverride", "Remove Min LOD Platform Override"));
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	check(StaticMesh);
	StaticMesh->Modify();
	FPerPlatformInt MinLOD = StaticMesh->GetMinLOD();
	if (MinLOD.PerPlatform.Remove(PlatformGroupName) != 0)
	{
		int32 Value = MinLOD.Default;
		StaticMesh->SetMinLOD(MoveTemp(MinLOD));
		OnMinLODChanged(Value, PlatformGroupName);
		return true;
	}
	return false;
}

TArray<FName> FLevelOfDetailSettingsLayout::GetMinLODPlatformOverrideNames() const

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.cpp:4899

Scope (from outer to inner):

file
function     TSharedRef<SWidget> FLevelOfDetailSettingsLayout::GetNumStreamedLODsWidget

Source code excerpt:

}

TSharedRef<SWidget> FLevelOfDetailSettingsLayout::GetNumStreamedLODsWidget(FName PlatformGroupName) const
{
	return SNew(SSpinBox<int32>)
		.Font(IDetailLayoutBuilder::GetDetailFont())
		.Value(this, &FLevelOfDetailSettingsLayout::GetNumStreamedLODs, PlatformGroupName)
		.OnValueChanged(const_cast<FLevelOfDetailSettingsLayout*>(this), &FLevelOfDetailSettingsLayout::OnNumStreamedLODsChanged, PlatformGroupName)
		.OnValueCommitted(const_cast<FLevelOfDetailSettingsLayout*>(this), &FLevelOfDetailSettingsLayout::OnNumStreamedLODsCommitted, PlatformGroupName)
		.MinValue(-1)
		.MaxValue(MAX_STATIC_MESH_LODS)
		.ToolTipText(this, &FLevelOfDetailSettingsLayout::GetNumStreamedLODsTooltip)
		.IsEnabled(FLevelOfDetailSettingsLayout::GetLODCount() > 1);
}

bool FLevelOfDetailSettingsLayout::AddNumStreamedLODsPlatformOverride(FName PlatformGroupName)
{
	FScopedTransaction Transaction(LOCTEXT("AddNumStreamedLODsPlatformOverride", "Add NumStreamdLODs Platform Override"));
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	check(StaticMesh);
	StaticMesh->Modify();
	if (StaticMesh->NumStreamedLODs.PerPlatform.Find(PlatformGroupName) == nullptr)
	{
		int32 Value = StaticMesh->NumStreamedLODs.Default;
		StaticMesh->NumStreamedLODs.PerPlatform.Add(PlatformGroupName, Value);
		OnNumStreamedLODsChanged(Value, PlatformGroupName);
		return true;
	}
	return false;
}

bool FLevelOfDetailSettingsLayout::RemoveNumStreamedLODsPlatformOverride(FName PlatformGroupName)
{
	FScopedTransaction Transaction(LOCTEXT("RemoveNumStreamedLODsPlatformOverride", "Remove NumStreamedLODs Platform Override"));
	UStaticMesh* StaticMesh = StaticMeshEditor.GetStaticMesh();
	check(StaticMesh);
	StaticMesh->Modify();
	if (StaticMesh->NumStreamedLODs.PerPlatform.Remove(PlatformGroupName) != 0)
	{
		OnNumStreamedLODsChanged(StaticMesh->NumStreamedLODs.Default, PlatformGroupName);
		return true;
	}
	return false;
}

TArray<FName> FLevelOfDetailSettingsLayout::GetNumStreamedLODsPlatformOverrideNames() const

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.h:561

Scope (from outer to inner):

file
class        class FLevelOfDetailSettingsLayout : public TSharedFromThis<FLevelOfDetailSettingsLayout>

Source code excerpt:

	int32 GetMinLOD(FName Platform) const;
	FPerPlatformInt GetMinLOD() const;
	TSharedRef<SWidget> GetMinLODWidget(FName PlatformGroupName) const;
	bool AddMinLODPlatformOverride(FName PlatformGroupName);
	bool RemoveMinLODPlatformOverride(FName PlatformGroupName);
	TArray<FName> GetMinLODPlatformOverrideNames() const;

	void OnMinQualityLevelLODChanged(int32 NewValue, FName QualityLevel);
	void OnMinQualityLevelLODCommitted(int32 InValue, ETextCommit::Type CommitInfo, FName QualityLevel);
	int32 GetMinQualityLevelLOD(FName QualityLevel) const;
	TSharedRef<SWidget> GetMinQualityLevelLODWidget(FName QualityLevelName) const;

#Loc: <Workspace>/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditorTools.h:586

Scope (from outer to inner):

file
class        class FLevelOfDetailSettingsLayout : public TSharedFromThis<FLevelOfDetailSettingsLayout>

Source code excerpt:

	void OnNumStreamedLODsCommitted(int32 InValue, ETextCommit::Type CommitInfo, FName Platform);
	int32 GetNumStreamedLODs(FName Platform) const;
	TSharedRef<SWidget> GetNumStreamedLODsWidget(FName PlatformGroupName) const;
	bool AddNumStreamedLODsPlatformOverride(FName PlatformGroupName);
	bool RemoveNumStreamedLODsPlatformOverride(FName PlatformGroupName);
	TArray<FName> GetNumStreamedLODsPlatformOverrideNames() const;

	bool CanRemoveLOD(int32 LODIndex) const;
	FReply OnRemoveLOD(int32 LODIndex);

	float GetLODScreenSize(FName PlatformGroupName, int32 LODIndex)const;
	FText GetLODScreenSizeTitle(int32 LODIndex) const;
	bool CanChangeLODScreenSize() const;
	TSharedRef<SWidget> GetLODScreenSizeWidget(FName PlatformGroupName, int32 LODIndex) const;
	TArray<FName> GetLODScreenSizePlatformOverrideNames(int32 LODIndex) const;
	bool AddLODScreenSizePlatformOverride(FName PlatformGroupName, int32 LODIndex);
	bool RemoveLODScreenSizePlatformOverride(FName PlatformGroupName, int32 LODIndex);
	void OnLODScreenSizeChanged(float NewValue, FName PlatformGroupName, int32 LODIndex);
	void OnLODScreenSizeCommitted(float NewValue, ETextCommit::Type CommitType, FName PlatformGroupName, int32 LODIndex);
	float GetScreenSizeWidgetWidth(int32 LODIndex) const;

	FString GetSourceImportFilename(int32 LODIndex) const;
	void SetSourceImportFilename(const FString& SourceFileName, int32 LODIndex) const;

	void OnBuildSettingsExpanded(bool bIsExpanded, int32 LODIndex);

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/Misc/DataDrivenPlatformInfoRegistry.cpp:367

Scope (from outer to inner):

file
function     static void LoadDDPIIniSettings

Source code excerpt:

	DDPIGetString(IniFile, TEXT("AutoSDKPath"), Info.AutoSDKPath);
	DDPIGetString(IniFile, TEXT("TutorialPath"), Info.SDKTutorial);
	DDPIGetName(IniFile, TEXT("PlatformGroupName"), Info.PlatformGroupName);
	DDPIGetName(IniFile, TEXT("PlatformSubMenu"), Info.PlatformSubMenu);


	DDPIGetString(IniFile, TEXT("NormalIconPath"), Info.IconPaths.NormalPath);
	DDPIGetString(IniFile, TEXT("LargeIconPath"), Info.IconPaths.LargePath);
	DDPIGetString(IniFile, TEXT("XLargeIconPath"), Info.IconPaths.XLargePath);

#Loc: <Workspace>/Engine/Source/Runtime/Core/Public/Misc/DataDrivenPlatformInfoRegistry.h:195

Scope: file

Source code excerpt:


	/** An identifier to group similar platforms together, such as "Mobile" and "Console". Used for Per-Platform Override Properties. */
	FName PlatformGroupName;

	/** Submenu name to group similar platforms together in menus, such as "Linux" and "LinuxArm64".  */
	FName PlatformSubMenu;

	/** An identifier that corresponds to UBT's UnrealTargetPlatform enum (and by proxy, FGenericPlatformMisc::GetUBTPlatform()), as well as the directory Binaries are placed under */
	FName UBTPlatformName;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PerQualityLevelProperties.cpp:87

Scope (from outer to inner):

file
namespace    QualityLevelProperty
function     FSupportedQualityLevelArray PerPlatformOverrideMapping

Source code excerpt:

			{
				// gather all platform related to the platform group
				if (DataDrivenPlatformInfo->PlatformGroupName == FName(*InPlatformName))
				{
					EnginePlatforms.AddUnique(DataDrivenPlatformInfo->IniPlatformName);
				}
			}
		}
		else

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SkeletalMesh.cpp:4930

Scope (from outer to inner):

file
function     FString USkeletalMesh::BuildDerivedDataKey

Source code excerpt:

	}

	if (TargetPlatform->GetPlatformInfo().PlatformGroupName == TEXT("Desktop")
		&& GStripSkeletalMeshLodsDuringCooking != 0
		&& GSkeletalMeshKeepMobileMinLODSettingOnDesktop != 0)
	{
		KeySuffix += TEXT("_MinMLOD");
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SkeletalMeshRenderData.cpp:546

Scope (from outer to inner):

file
function     void FSkeletalMeshRenderData::Serialize

Source code excerpt:

		if (Ar.IsSaving())
		{
			if (Ar.CookingTarget()->GetPlatformInfo().PlatformGroupName == TEXT("Desktop")
				&& GStripSkeletalMeshLodsDuringCooking != 0
				&& GSkeletalMeshKeepMobileMinLODSettingOnDesktop != 0)
			{
				// Serialize 0 value when per quality level properties are used
				if (!Owner->IsMinLodQualityLevelEnable())
				{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp:1687

Scope (from outer to inner):

file
function     void FStaticMeshRenderData::Serialize

Source code excerpt:

		if (Ar.IsSaving())
		{
			if (Ar.CookingTarget()->GetPlatformInfo().PlatformGroupName == TEXT("Desktop")
				&& CVarStripMinLodDataDuringCooking.GetValueOnAnyThread() != 0
				&& CVarStaticMeshKeepMobileMinLODSettingOnDesktop.GetValueOnAnyThread() != 0)
			{
				// Serialize 0 value when per quality level properties are used
				if (!Owner->IsMinLodQualityLevelEnable())
				{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp:2876

Scope (from outer to inner):

file
function     static FString BuildStaticMeshDerivedDataKeySuffix

Source code excerpt:

	IMeshBuilderModule::GetForPlatform(TargetPlatform).AppendToDDCKey(KeySuffix, false);

	if (TargetPlatform->GetPlatformInfo().PlatformGroupName == TEXT("Desktop")
		&& CVarStripMinLodDataDuringCooking.GetValueOnAnyThread() != 0
		&& CVarStaticMeshKeepMobileMinLODSettingOnDesktop.GetValueOnAnyThread() != 0)
	{
		KeySuffix += TEXT("_MinMLOD");
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/PerPlatformProperties.h:136

Scope (from outer to inner):

file
function     _ValueType GetValueForPlatform

Source code excerpt:

		{
			const FDataDrivenPlatformInfo& Info = FDataDrivenPlatformInfoRegistry::GetPlatformInfo(PlatformName);
			if (Info.PlatformGroupName != NAME_None)
			{
				Ptr = This->PerPlatform.Find(KeyFuncs::NameToKey(Info.PlatformGroupName));
			}
		}

		return Ptr ? *Ptr : This->Default;
	}
#endif