QualityLevels

QualityLevels

#Overview

name: QualityLevels

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

It is referenced in 55 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of QualityLevels is to define and manage different quality settings for various aspects of the game or engine, such as graphics, audio, and performance. This variable is typically used to store an array of quality level configurations that can be applied to adjust the game’s visual fidelity, performance, and other characteristics based on the user’s hardware capabilities or preferences.

QualityLevels is primarily used by the Scalability system in Unreal Engine, which is responsible for adjusting game performance and visual quality across different hardware configurations. It’s also utilized by various subsystems and modules, including:

  1. Audio system
  2. Niagara VFX system
  3. Landscape system
  4. Movie Render Pipeline
  5. Automation and testing tools

The value of this variable is typically set in the project settings, specifically in the Audio Settings and Engine Scalability Settings. It can also be modified at runtime through various functions in the Scalability namespace.

QualityLevels often interacts with other variables and systems, such as:

  1. Device profiles
  2. Platform-specific settings
  3. Scalability CVars (Console Variables)
  4. Various rendering and performance-related settings

Developers should be aware of the following when using this variable:

  1. Changing quality levels can have a significant impact on performance and visual fidelity.
  2. Quality levels should be tested across various hardware configurations to ensure a consistent experience.
  3. Some systems, like Niagara, use quality levels for optimization and may behave differently at different quality settings.

Best practices when using this variable include:

  1. Provide a reasonable range of quality options to accommodate different hardware capabilities.
  2. Test thoroughly across all quality levels to ensure gameplay and visuals remain consistent and acceptable.
  3. Use the Scalability system’s functions to modify quality levels rather than directly changing the variable.
  4. Consider platform-specific quality level mappings for consistent experiences across different devices.
  5. Implement a user-friendly way for players to adjust quality settings in-game.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Plugins/FX/Niagara/Config/BaseNiagara.ini:54, section: [/Script/Niagara.NiagaraSettings]

Location: <Workspace>/Engine/Plugins/FX/Niagara/Config/BaseNiagara.ini:55, section: [/Script/Niagara.NiagaraSettings]

Location: <Workspace>/Engine/Plugins/FX/Niagara/Config/BaseNiagara.ini:56, section: [/Script/Niagara.NiagaraSettings]

Location: <Workspace>/Engine/Plugins/FX/Niagara/Config/BaseNiagara.ini:57, section: [/Script/Niagara.NiagaraSettings]

Location: <Workspace>/Engine/Plugins/FX/Niagara/Config/BaseNiagara.ini:58, section: [/Script/Niagara.NiagaraSettings]

Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:259, section: [/Script/Engine.AudioSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Experimental/AutomationUtils/Source/AutomationUtils/Private/AutomationUtilsBlueprintLibrary.cpp:139

Scope (from outer to inner):

file
function     FAutomationUtilsGameplayAutomationScreenshotInstance::FAutomationUtilsGameplayAutomationScreenshotInstance

Source code excerpt:

		JsonObject->SetStringField(TEXT("uniqueDeviceId"), FPlatformMisc::GetDeviceId());
		//Quality
		Scalability::FQualityLevels QualityLevels = Scalability::GetQualityLevels();
		JsonObject->SetNumberField(TEXT("resolutionQuality"), QualityLevels.ResolutionQuality);
		JsonObject->SetNumberField(TEXT("viewDistanceQuality"), QualityLevels.ViewDistanceQuality);
		JsonObject->SetNumberField(TEXT("antiAliasingQuality"), QualityLevels.AntiAliasingQuality);
		JsonObject->SetNumberField(TEXT("shadowQuality"), QualityLevels.ShadowQuality);
		JsonObject->SetNumberField(TEXT("globalIlluminationQuality"), QualityLevels.GlobalIlluminationQuality);
		JsonObject->SetNumberField(TEXT("reflectionQuality"), QualityLevels.ReflectionQuality);
		JsonObject->SetNumberField(TEXT("postProcessQuality"), QualityLevels.PostProcessQuality);
		JsonObject->SetNumberField(TEXT("textureQuality"), QualityLevels.TextureQuality);
		JsonObject->SetNumberField(TEXT("effectsQuality"), QualityLevels.EffectsQuality);
		JsonObject->SetNumberField(TEXT("foliageQuality"), QualityLevels.FoliageQuality);
		JsonObject->SetNumberField(TEXT("shadingQuality"), QualityLevels.ShadingQuality);
		//ComparisonOptions
		JsonObject->SetBoolField(TEXT("bHasComparisonRules"), true);
		JsonObject->SetNumberField(TEXT("toleranceRed"), 8);
		JsonObject->SetNumberField(TEXT("toleranceGreen"), 8);
		JsonObject->SetNumberField(TEXT("toleranceBlue"), 8);
		JsonObject->SetNumberField(TEXT("toleranceAlpha"), 8);

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraEmitter.cpp:964

Scope (from outer to inner):

file
function     void UNiagaraEmitter::GetAssetRegistryTags

Source code excerpt:

	if (const UNiagaraSettings* Settings = GetDefault<UNiagaraSettings>())
	{
		int32 NumQualityLevels = Settings->QualityLevels.Num();
		TArray<int32> QualityLevelsNumActive;
		QualityLevelsNumActive.AddZeroed(NumQualityLevels);

		// Keeping structure from UNiagaraSystem for easy code comparison
		for (int32 i = 0; i < NumQualityLevels; i++)
		{

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraEmitter.cpp:979

Scope (from outer to inner):

file
function     void UNiagaraEmitter::GetAssetRegistryTags

Source code excerpt:

		for (int32 i = 0; i < NumQualityLevels; i++)
		{
			FString QualityLevelKey = Settings->QualityLevels[i].ToString() + TEXT("Emitters");
			Context.AddTag(FAssetRegistryTag(*QualityLevelKey, LexToString(QualityLevelsNumActive[i]), FAssetRegistryTag::TT_Numerical));
		}
	}

	TMap<FName, uint32> NumericKeys;
	TMap<FName, FString> StringKeys;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:301

Scope (from outer to inner):

file
function     FText FNiagaraPlatformSet::GetQualityLevelText

Source code excerpt:

	check(Settings);

	if (Settings->QualityLevels.IsValidIndex(QualityLevel))
	{
		return Settings->QualityLevels[QualityLevel];
	}	
	else
	{
		return FText::AsNumber(QualityLevel);
	}
}

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:380

Scope (from outer to inner):

file
function     int32 FNiagaraPlatformSet::GetEnabledMaskForDeviceProfile

Source code excerpt:


	int32 RetQLMask = 0;
	for (int32 i = 0; i < Settings->QualityLevels.Num(); ++i)
	{
		FNiagaraPlatformSetEnabledState EnabledState = IsEnabled(DeviceProfile, i, false);
		if (EnabledState.bCanBeActive)
		{
			RetQLMask |= CreateQualityLevelMask(i);
		}

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:398

Scope (from outer to inner):

file
function     int32 FNiagaraPlatformSet::IsEnabledForDeviceProfile

Source code excerpt:


	int32 RetQLMask = 0;
	for (int32 i = 0; i < Settings->QualityLevels.Num(); ++i)
	{
		FNiagaraPlatformSetEnabledState Enabled = IsEnabled(DeviceProfile, i, false);
		if (Enabled.bCanBeActive)
		{
			RetQLMask |= CreateQualityLevelMask(i);
		}

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:1203

Scope (from outer to inner):

file
function     bool FNiagaraPlatformSet::GatherConflicts

Source code excerpt:

	const UNiagaraSettings* Settings = GetDefault<UNiagaraSettings>();
	check(Settings);
	int32 NumLevels = Settings->QualityLevels.Num();

	FNiagaraPlatformSetConflictInfo* CurrentConflict = nullptr;
	for (int32 A = 0; A < PlatformSets.Num(); ++A)
	{
		for (int32 B = A + 1; B < PlatformSets.Num(); ++B)
		{

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraSystem.cpp:1565

Scope (from outer to inner):

file
function     void UNiagaraSystem::GetAssetRegistryTags

Source code excerpt:

	if (Settings)
	{
		int32 NumQualityLevels = Settings->QualityLevels.Num();
		TArray<int32> QualityLevelsNumActive;
		QualityLevelsNumActive.AddZeroed(NumQualityLevels);

		for (const FNiagaraEmitterHandle& Handle : EmitterHandles)
		{
			if (Handle.GetIsEnabled())

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraSystem.cpp:1590

Scope (from outer to inner):

file
function     void UNiagaraSystem::GetAssetRegistryTags

Source code excerpt:

		for (int32 i = 0; i < NumQualityLevels; i++)
		{
			FString QualityLevelKey = Settings->QualityLevels[i].ToString() + TEXT("Emitters");
			Context.AddTag(FAssetRegistryTag(*QualityLevelKey, LexToString(QualityLevelsNumActive[i]), FAssetRegistryTag::TT_Numerical));
		}
	}


	TMap<FName, uint32> NumericKeys;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Public/NiagaraSettings.h:219

Scope (from outer to inner):

file
class        class UNiagaraSettings : public UDeveloperSettings

Source code excerpt:

	/** The quality levels Niagara uses. */
	UPROPERTY(config, EditAnywhere, Category = Scalability)
	TArray<FText> QualityLevels;

	/** Info texts that the component renderer shows the user depending on the selected component class. */
	UPROPERTY(config, EditAnywhere, Category = Renderer)
	TMap<FString, FText> ComponentRendererWarningsPerClass;

	/** The default render target format used by all Niagara Render Target Data Interfaces unless overridden. */

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Commandlets/NiagaraSystemAuditCommandlet.cpp:337

Scope (from outer to inner):

file
function     bool UNiagaraSystemAuditCommandlet::ProcessNiagaraSystems

Source code excerpt:

					if (DeviceQualityLevelMask != 0)
					{
						for (int32 iQualityLevel = 0; iQualityLevel < NiagaraSettings->QualityLevels.Num(); ++iQualityLevel)
						{
							if ( (DeviceQualityLevelMask & (1 << iQualityLevel)) != 0 )
							{
								EmitterData->Platforms.SetDeviceProfileState(DeviceProfile, iQualityLevel, ENiagaraPlatformSelectionState::Disabled);
							}
						}

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Commandlets/NiagaraSystemAuditCommandlet.cpp:358

Scope (from outer to inner):

file
function     bool UNiagaraSystemAuditCommandlet::ProcessNiagaraSystems

Source code excerpt:

				GpuEmitterBuilder.Append(EmitterData->bInterpolatedSpawning ? TEXT(",true") : TEXT(",false"));

				for (int32 iQualityLevel=0; iQualityLevel < NiagaraSettings->QualityLevels.Num(); ++iQualityLevel)
				{
					const bool bEnabled = EmitterData->Platforms.IsEffectQualityEnabled(iQualityLevel);

					TArray<UDeviceProfile*> EnabledProfiles;
					TArray<UDeviceProfile*> DisabledProfiles;
					EmitterData->Platforms.GetOverridenDeviceProfiles(iQualityLevel, EnabledProfiles, DisabledProfiles);

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Commandlets/NiagaraSystemAuditCommandlet.cpp:545

Scope (from outer to inner):

file
function     void UNiagaraSystemAuditCommandlet::DumpResults

Source code excerpt:

		TStringBuilder<512> HeaderString;
		HeaderString.Append(TEXT("Emitter Name,Interpolated Spawn"));
		for (const FText& QualityLevelName : GetDefault<UNiagaraSettings>()->QualityLevels)
		{
			HeaderString.Append(TEXT(","));
			HeaderString.Append(QualityLevelName.ToString());
		}
		HeaderString.Append(TEXT(",CVar Conditions,System Path"));
		DumpSimpleSet(NiagaraSystemsWithGPUEmitters, TEXT("NiagaraSystemsWithGPUEmitters"), HeaderString.ToString());

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Customizations/NiagaraPlatformSetCustomization.cpp:168

Scope (from outer to inner):

file
function     void FNiagaraPlatformSetCustomization::GenerateQualityLevelSelectionWidgets

Source code excerpt:

	check(Settings);

	int32 NumQualityLevels = Settings->QualityLevels.Num();
	
	QualityLevelMenuAnchors.Reset();
	QualityLevelMenuContents.Reset();
	QualityLevelMenuAnchors.SetNum(NumQualityLevels);
	QualityLevelMenuContents.SetNum(NumQualityLevels);

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Customizations/NiagaraPlatformSetCustomization.cpp:721

Scope (from outer to inner):

file
function     void FNiagaraPlatformSetCustomization::CreateDeviceProfileTree

Source code excerpt:

	check(Settings);

	int32 NumQualityLevels = Settings->QualityLevels.Num();
	FilteredDeviceProfileTrees.Reset();
	FilteredDeviceProfileTrees.SetNum(NumQualityLevels);
	
	for (TSharedPtr<FNiagaraDeviceProfileViewModel>& FullDeviceRoot : FullDeviceProfileTree)
	{
		for (int32 QualityLevel = 0; QualityLevel < NumQualityLevels; ++QualityLevel)

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Customizations/NiagaraPlatformSetCustomization.cpp:785

Scope (from outer to inner):

file
function     TSharedRef<ITableRow> FNiagaraPlatformSetCustomization::OnGenerateDeviceProfileTreeRow

Source code excerpt:

	check(Settings);

	int32 NumQualityLevels = Settings->QualityLevels.Num();
	
	
	//Top level profile. Look for a platform icon.
	if (InItem->Profile->Parent == nullptr)
	{
		if (const PlatformInfo::FTargetPlatformInfo* Info = PlatformInfo::FindPlatformInfo(*InItem->Profile->DeviceType))

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/ViewModels/NiagaraBakerViewModel.cpp:651

Scope (from outer to inner):

file
function     FNiagaraBakerFeedbackContext FNiagaraBakerViewModel::RenderBaker

Source code excerpt:

		{
			const UNiagaraSettings* NiagaraSettings = GetDefault<UNiagaraSettings>();
			for (int32 i=0; i < NiagaraSettings->QualityLevels.Num(); ++i)
			{
				if (FName(NiagaraSettings->QualityLevels[i].ToString()) == BakerSettings->BakeQualityLevel)
				{
					FNiagaraPlatformSet::SetNiagaraQualityLevelOverride(i);
					break;
				}
			}
		}

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Widgets/SNiagaraBakerWidget.cpp:832

Scope (from outer to inner):

file
function     void SNiagaraBakerWidget::MakeBakeQualityLevelMenu

Source code excerpt:

	MenuBuilder.BeginSection("QualityLevel", LOCTEXT("QualityLevel", "QualityLevel"));
	{
		for (const FText& QualityLevelText : GetDefault<UNiagaraSettings>()->QualityLevels)
		{
			const FName QualityLevel(*QualityLevelText.ToString());

			MenuBuilder.AddMenuEntry(
				QualityLevelText,
				FText::GetEmpty(),

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditorWidgets/Private/SNiagaraOverviewStackNode.cpp:895

Scope (from outer to inner):

file
function     EVisibility SNiagaraOverviewStackNode::GetScalabilityIndicatorVisibility

Source code excerpt:

		{
			bool bIsQualityLevelMaskSetup = EmitterData->Platforms.QualityLevelMask != INDEX_NONE;
			bool bIsScalabilitySetup = EmitterData->ScalabilityOverrides.Overrides.Num() != 0 || (bIsQualityLevelMaskSetup && EmitterData->Platforms.QualityLevelMask != FNiagaraPlatformSet::GetFullQualityLevelMask(GetDefault<UNiagaraSettings>()->QualityLevels.Num())); 
			return bIsScalabilitySetup ? EVisibility::Visible : DisplayMode == EDisplayMode::Summary ? EVisibility::Hidden : EVisibility::Collapsed;
		}
	}

	if(UNiagaraSystem* System = OverviewStackNode->GetOwningSystem())
	{

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditorWidgets/Private/SNiagaraScalabilityPreviewSettings.cpp:69

Scope (from outer to inner):

file
function     TSharedRef<SWidget> SNiagaraScalabilityPreviewSettings::CreatePreviewQualityLevelWidgets

Source code excerpt:

	.UseAllottedSize(true);
	
	int32 NumQualityLevels = Settings->QualityLevels.Num();

	for (int32 QualityLevel = 0; QualityLevel < NumQualityLevels; ++QualityLevel)
	{
		bool First = QualityLevel == 0;
		bool Last = QualityLevel == (NumQualityLevels - 1);
		

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditorWidgets/Private/SNiagaraScalabilityPreviewSettings.cpp:296

Scope (from outer to inner):

file
function     void SNiagaraScalabilityPreviewSettings::CreateDeviceProfileTree

Source code excerpt:

	check(Settings);

	int32 NumQualityLevels = Settings->QualityLevels.Num();
	FilteredDeviceProfileTrees.SetNum(NumQualityLevels);
	
	for (TSharedPtr<FNiagaraDeviceProfileViewModel>& FullDeviceRoot : FullDeviceProfileTree)
	{
		for (int32 QualityLevel = 0; QualityLevel < NumQualityLevels; ++QualityLevel)
		{			

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/Graph/Nodes/MovieGraphGlobalGameOverrides.cpp:27

Scope (from outer to inner):

file
function     void UMovieGraphGlobalGameOverridesNode::BuildNewProcessCommandLineArgsImpl

Source code excerpt:

	
	{
		Scalability::FQualityLevels QualityLevels;
		QualityLevels.SetFromSingleQualityLevel(static_cast<int32>(ScalabilityQualityLevel));

		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.ViewDistanceQuality={0}"), {QualityLevels.ViewDistanceQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.AntiAliasingQuality={0}"), {QualityLevels.AntiAliasingQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.ShadowQuality={0}"), {QualityLevels.ShadowQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.GlobalIlluminationQuality={0}"), {QualityLevels.GlobalIlluminationQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.ReflectionQuality={0}"), {QualityLevels.ReflectionQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.PostProcessQuality={0}"), {QualityLevels.PostProcessQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.TextureQuality={0}"), {QualityLevels.TextureQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.EffectsQuality={0}"), {QualityLevels.EffectsQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.FoliageQuality={0}"), {QualityLevels.FoliageQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.ShadingQuality={0}"), {QualityLevels.ShadingQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.LandscapeQuality={0}"), {QualityLevels.LandscapeQuality}));
	}

	if (bDisableTextureStreaming)
	{
		InOutDeviceProfileCvars.Add(TEXT("r.TextureStreaming=0"));
	}

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/Graph/Nodes/MovieGraphGlobalGameOverrides.cpp:96

Scope (from outer to inner):

file
function     void UMovieGraphGlobalGameOverridesNode::ApplySettings

Source code excerpt:


		// Set to the chosen scalability quality level
		Scalability::FQualityLevels QualityLevels;
		QualityLevels.SetFromSingleQualityLevel(static_cast<int32>(ScalabilityQualityLevel));

		// Apply
		Scalability::SetQualityLevels(QualityLevels);
	}
	else
	{
		// We re-apply old scalability settings at the end of the function during teardown
		// so that any values that are also specified in Scalability don't get overwritten
		// with the wrong values from the ones below restoring.

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/MoviePipelineGameOverrideSetting.cpp:34

Scope (from outer to inner):

file
function     void UMoviePipelineGameOverrideSetting::ApplyCVarSettings

Source code excerpt:


			// Create a copy and override to the maximum level for each Scalability category
			Scalability::FQualityLevels QualityLevels = PreviousQualityLevels;
			QualityLevels.SetFromSingleQualityLevelRelativeToMax(0);

			// Apply
			Scalability::SetQualityLevels(QualityLevels);
		}
		else
		{
			// We re-apply old scalability settings at the end of the function during teardown
			// so that any values that are also specified in Scalability don't get overwritten
			// with the wrong values from the ones below restoring.

#Loc: <Workspace>/Engine/Plugins/Runtime/SoundCueTemplates/Source/SoundCueTemplates/Private/SoundCueTemplateSettings.cpp:78

Scope (from outer to inner):

file
function     int32 USoundCueTemplateSettings::GetQualityLevelSettingsNum

Source code excerpt:

int32 USoundCueTemplateSettings::GetQualityLevelSettingsNum() const
{
	return QualityLevels.Num();
}

const FSoundCueTemplateQualitySettings& USoundCueTemplateSettings::GetQualityLevelSettings(int32 Index) const
{
	return QualityLevels[Index];
}

void USoundCueTemplateSettings::PostInitProperties()
{
	Super::PostInitProperties();

#Loc: <Workspace>/Engine/Plugins/Runtime/SoundCueTemplates/Source/SoundCueTemplates/Private/SoundCueTemplateSettings.cpp:150

Scope (from outer to inner):

file
function     bool USoundCueTemplateSettings::RebuildQualityLevels

Source code excerpt:

	bool bHasChanged = false;

	while (QualityLevels.Num() > AudioSettings->GetQualityLevelSettingsNum())
	{
		bHasChanged = true;
		QualityLevels.RemoveAt(QualityLevels.Num() - 1);
	}

	while (QualityLevels.Num() < AudioSettings->GetQualityLevelSettingsNum())
	{
		bHasChanged = true;
		QualityLevels.Add(FSoundCueTemplateQualitySettings());
	}

	for (int i = 0; i < AudioSettings->GetQualityLevelSettingsNum(); ++i)
	{
		FText& QualityName = QualityLevels[i].DisplayName;
		const FText& AudioSettingsQualityName = AudioSettings->GetQualityLevelSettings(i).DisplayName;
		QualityName = AudioSettingsQualityName;
	}

	return bHasChanged;
}

#Loc: <Workspace>/Engine/Plugins/Runtime/SoundCueTemplates/Source/SoundCueTemplates/Public/SoundCueTemplateSettings.h:42

Scope (from outer to inner):

file
class        class USoundCueTemplateSettings : public UDeveloperSettings

Source code excerpt:

#if WITH_EDITORONLY_DATA
	UPROPERTY(config, EditAnywhere, Category = "Quality")
	TArray<FSoundCueTemplateQualitySettings> QualityLevels;
#endif // WITH_EDITORONLY_DATA

#if WITH_EDITOR
	virtual void PostEditChangeChainProperty( struct FPropertyChangedChainEvent& PropertyChangedEvent) override;
	virtual void PostInitProperties() override;

#Loc: <Workspace>/Engine/Source/Developer/AudioSettingsEditor/Private/TargetPlatformAudioCustomization.cpp:354

Scope (from outer to inner):

file
function     void FAudioPluginWidgetManager::BuildAudioCategory
lambda-function

Source code excerpt:

				FOnGetPropertyComboBoxStrings::CreateLambda([](TArray<TSharedPtr<FString>>& OutComboBoxStrings, TArray<TSharedPtr<SToolTip>>& OutToolTips, TArray<bool>& OutRestrictedItems) -> void  
				{									
					for (const FAudioQualitySettings& i : GetDefault<UAudioSettings>()->QualityLevels)
					{
						OutComboBoxStrings.Add(MakeShared<FString>(i.DisplayName.ToString()));
						OutRestrictedItems.Add(false);
						OutToolTips.Add(SNew(SToolTip).Text(i.DisplayName));
					}
				}), 

#Loc: <Workspace>/Engine/Source/Developer/AudioSettingsEditor/Private/TargetPlatformAudioCustomization.cpp:369

Scope (from outer to inner):

file
function     void FAudioPluginWidgetManager::BuildAudioCategory
lambda-function

Source code excerpt:

				FOnPropertyComboBoxValueSelected::CreateLambda([SoundQualityNamePropHandle](FString Value) -> void
				{
					const TArray<FAudioQualitySettings>& Values = GetDefault<UAudioSettings>()->QualityLevels;
					int32 Index = Values.IndexOfByPredicate([TextValue = FText::FromString(Value)](const FAudioQualitySettings& i) -> bool { return i.DisplayName.CompareTo(TextValue) == 0; });
					SoundQualityNamePropHandle->SetValue(Index);
				})
			)
		];
}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Settings/LevelEditorPlaySettingsCustomization.cpp:637

Scope (from outer to inner):

file
function     void FLevelEditorPlaySettingsCustomization::HandleQualityLevelComboBoxOpening

Source code excerpt:

{
	const UAudioSettings* AudioSettings = GetDefault<UAudioSettings>();
	AvailableQualityLevels.Empty( AudioSettings->QualityLevels.Num() );
	for ( const FAudioQualitySettings& AQSettings : AudioSettings->QualityLevels )
	{
		AvailableQualityLevels.Add( MakeShareable( new FString( AQSettings.DisplayName.ToString() ) ) );
	}
	QualityLevelComboBox->RefreshOptions();
}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Settings/LevelEditorPlaySettingsCustomization.cpp:656

Scope (from outer to inner):

file
function     void FLevelEditorPlaySettingsCustomization::HandleQualityLevelSelectionChanged

Source code excerpt:

	{
		const UAudioSettings* AudioSettings = GetDefault<UAudioSettings>();
		for ( int32 QualityLevel = 0; QualityLevel < AudioSettings->QualityLevels.Num(); ++QualityLevel )
		{
			if ( AudioSettings->QualityLevels[QualityLevel].DisplayName.ToString() == *InSelection )
			{
				PIESoundQualityLevelHandle->SetValue( QualityLevel );
				break;
			}
		}
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Settings/LevelEditorPlaySettingsCustomization.cpp:672

Scope (from outer to inner):

file
function     FText FLevelEditorPlaySettingsCustomization::GetSelectedQualityLevelName

Source code excerpt:

	PIESoundQualityLevelHandle->GetValue( QualityLevel );
	const UAudioSettings* AudioSettings = GetDefault<UAudioSettings>();
	return (QualityLevel >= 0 && QualityLevel < AudioSettings->QualityLevels.Num() ? AudioSettings->QualityLevels[QualityLevel].DisplayName : FText::GetEmpty());
}

FText FLevelEditorPlaySettingsCustomization::GetPreviewText() const
{
	const ULevelEditorPlaySettings* LevelEditorPlaySettings = GetDefault<ULevelEditorPlaySettings>();
	float SafeZone = FDisplayMetrics::GetDebugTitleSafeZoneRatio();

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Sound/AudioSettings.h:197

Scope (from outer to inner):

file
class        class UAudioSettings : public UDeveloperSettings

Source code excerpt:


	UPROPERTY(config, EditAnywhere, Category="Quality")
	TArray<FAudioQualitySettings> QualityLevels;

	/** Allows sounds to play at 0 volume. */
	UPROPERTY(config, EditAnywhere, Category = "Audio", AdvancedDisplay)
	uint32 bAllowPlayWhenSilent:1;

	/** Disables master EQ effect in the audio DSP graph. */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:35

Scope (from outer to inner):

file
function     void UAudioSettings::AddDefaultSettings

Source code excerpt:

	FAudioQualitySettings DefaultSettings;
	DefaultSettings.DisplayName = LOCTEXT("DefaultSettingsName", "Default");
	QualityLevels.Add(DefaultSettings);
	bAllowPlayWhenSilent = true;
	DefaultReverbSendLevel_DEPRECATED = 0.0f;
	VoiPSampleRate = EVoiceSampleRate::Low16000Hz;
	NumStoppingSources = 8;
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:51

Scope (from outer to inner):

file
function     void UAudioSettings::PreEditChange

Source code excerpt:


	// Cache at least the first entry in case someone tries to clear the array
	CachedQualityLevels = QualityLevels;
}

void UAudioSettings::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
{
	if (PropertyChangedEvent.Property)
	{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:105

Scope (from outer to inner):

file
function     void UAudioSettings::PostEditChangeChainProperty

Source code excerpt:

			}
		}
		else if (PropertyName == GET_MEMBER_NAME_CHECKED(UAudioSettings, QualityLevels))
		{
			if (QualityLevels.Num() == 0)
			{
				QualityLevels.Add(CachedQualityLevels[0]);
			}
			else if (QualityLevels.Num() > CachedQualityLevels.Num())
			{
				for (FAudioQualitySettings& AQSettings : QualityLevels)
				{
					if (AQSettings.DisplayName.IsEmpty())
					{
						bool bFoundDuplicate;
						int32 NewQualityLevelIndex = 0;
						FText NewLevelName;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:124

Scope: file

Source code excerpt:

							bFoundDuplicate = false;
							NewLevelName = FText::Format(LOCTEXT("NewQualityLevelName","New Level{0}"), (NewQualityLevelIndex > 0 ? FText::FromString(FString::Printf(TEXT(" %d"),NewQualityLevelIndex)) : FText::GetEmpty()));
							for (const FAudioQualitySettings& QualityLevelSettings : QualityLevels)
							{
								if (QualityLevelSettings.DisplayName.EqualTo(NewLevelName))
								{
									bFoundDuplicate = true;
									break;
								}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:183

Scope (from outer to inner):

file
function     const FAudioQualitySettings& UAudioSettings::GetQualityLevelSettings

Source code excerpt:

const FAudioQualitySettings& UAudioSettings::GetQualityLevelSettings(int32 QualityLevel) const
{
	check(QualityLevels.Num() > 0);
	return QualityLevels[FMath::Clamp(QualityLevel, 0, QualityLevels.Num() - 1)];
}

int32 UAudioSettings::GetDefaultCompressionQuality() const
{
	return FMath::Clamp(DefaultCompressionQuality,1,100);
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:194

Scope (from outer to inner):

file
function     int32 UAudioSettings::GetQualityLevelSettingsNum

Source code excerpt:

int32 UAudioSettings::GetQualityLevelSettingsNum() const
{
	return QualityLevels.Num();
}

void UAudioSettings::LoadDefaultObjects()
{
	UE_LOG(LogAudio, Display, TEXT("Loading Default Audio Settings Objects..."));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:308

Scope (from outer to inner):

file
function     int32 UAudioSettings::GetHighestMaxChannels

Source code excerpt:

int32 UAudioSettings::GetHighestMaxChannels() const
{
	check(QualityLevels.Num() > 0);

	int32 HighestMaxChannels = -1;
	for (const FAudioQualitySettings& Settings : QualityLevels)
	{
		HighestMaxChannels = FMath::Max(Settings.MaxChannels, HighestMaxChannels);
	}

	return HighestMaxChannels;
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/AudioSettings.cpp:321

Scope (from outer to inner):

file
function     FString UAudioSettings::FindQualityNameByIndex

Source code excerpt:

FString UAudioSettings::FindQualityNameByIndex(int32 Index) const
{
	return QualityLevels.IsValidIndex(Index) ?
		   QualityLevels[Index].DisplayName.ToString() :
		   TEXT("");
}

#undef LOCTEXT_NAMESPACE

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

Scope (from outer to inner):

file
namespace    QualityLevelProperty
function     FSupportedQualityLevelArray PerPlatformOverrideMapping

Source code excerpt:

		}

		FSupportedQualityLevelArray QualityLevels;

		for (const FName& EnginePlatformName : EnginePlatforms)
		{
			//load individual platform ini files
			FConfigFile EngineSettings;
			 FConfigCacheIni::LoadLocalIniFile(EngineSettings, TEXT("Engine"), true, *EnginePlatformName.ToString());

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

Scope (from outer to inner):

file
namespace    QualityLevelProperty
function     FSupportedQualityLevelArray PerPlatformOverrideMapping

Source code excerpt:

					continue;
				}		
				QualityLevels.Add(Value);
			}
			else
			{
				UE_LOG(LogCore, Warning, TEXT("Didnt found QualityLevelMapping in the %sEngine.ini. Need to define QualityLevelMapping under the [SystemSettings] section. All perplatform MinLOD will not be converted to PerQuality"), *EnginePlatformName.ToString());
			}
		}

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

Scope (from outer to inner):

file
namespace    QualityLevelProperty
function     FSupportedQualityLevelArray PerPlatformOverrideMapping

Source code excerpt:

		{
			FScopeLock ScopeLock(&MappingCriticalSection);
			CachedMappingQualitLevelInfo = &CachedPerPlatformToQualityLevels.Add(InPlatformName, QualityLevels);
			return *CachedMappingQualitLevelInfo;
		}
	}
#endif
}

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

Scope (from outer to inner):

file
function     FString FPerQualityLevelInt::ToString

Source code excerpt:


#if WITH_EDITORONLY_DATA
	TArray<int32> QualityLevels;
	PerQuality.GetKeys(QualityLevels);
	QualityLevels.Sort();

	for (int32 QL : QualityLevels)
	{
		Result = FString::Printf(TEXT("%s, %s=%d"), *Result, *QualityLevelProperty::QualityLevelToFName(QL).ToString(), PerQuality.FindChecked(QL));
	}
#endif

	return Result;

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

Scope (from outer to inner):

file
function     FString FPerQualityLevelFloat::ToString

Source code excerpt:


#if WITH_EDITORONLY_DATA
	TArray<int32> QualityLevels;
	PerQuality.GetKeys(QualityLevels);
	QualityLevels.Sort();

	for (int32 QL : QualityLevels)
	{
		Result = FString::Printf(TEXT("%s, %s=%d"), *Result, *QualityLevelProperty::QualityLevelToFName(QL).ToString(), PerQuality.FindChecked(QL));
	}
#endif

	return Result;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:771

Scope (from outer to inner):

file
namespace    Scalability
function     void ProcessCommand

Source code excerpt:

		else if (Token == TEXT("cine"))
		{
			FQualityLevels QualityLevels;			
			QualityLevels.SetFromSingleQualityLevel(MAX_int32);
			SetQualityLevels(QualityLevels);
			Scalability::SaveState(GIsEditor ? GEditorSettingsIni : GGameUserSettingsIni);

			bPrintUsage = false;
		}
		else if (Token.IsNumeric())
		{
			FQualityLevels QualityLevels;

			int32 RequestedQualityLevel = FCString::Atoi(*Token);
			QualityLevels.SetFromSingleQualityLevel(RequestedQualityLevel);
			SetQualityLevels(QualityLevels);
			Scalability::SaveState(GIsEditor ? GEditorSettingsIni : GGameUserSettingsIni);

			bPrintUsage = false;
		}
		else
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:855

Scope (from outer to inner):

file
namespace    Scalability
function     void SetQualityLevels

Source code excerpt:

}

void SetQualityLevels(const FQualityLevels& QualityLevels, bool bForce/* = false*/)
{
	// The setter functions clamp these values internally
	FQualityLevels ClampedLevels;
	ClampedLevels.ResolutionQuality = QualityLevels.ResolutionQuality;
	ClampedLevels.SetViewDistanceQuality(QualityLevels.ViewDistanceQuality);
	ClampedLevels.SetAntiAliasingQuality(QualityLevels.AntiAliasingQuality);
	ClampedLevels.SetShadowQuality(QualityLevels.ShadowQuality);
	ClampedLevels.SetGlobalIlluminationQuality(QualityLevels.GlobalIlluminationQuality);
	ClampedLevels.SetReflectionQuality(QualityLevels.ReflectionQuality);
	ClampedLevels.SetPostProcessQuality(QualityLevels.PostProcessQuality);
	ClampedLevels.SetTextureQuality(QualityLevels.TextureQuality);
	ClampedLevels.SetEffectsQuality(QualityLevels.EffectsQuality);
	ClampedLevels.SetFoliageQuality(QualityLevels.FoliageQuality);
	ClampedLevels.SetShadingQuality(QualityLevels.ShadingQuality);
	ClampedLevels.SetLandscapeQuality(QualityLevels.LandscapeQuality);

#if WITH_EDITOR
	bForce = bForce || bScalabilityShaderPlatformHasBeenChanged;
#endif

	if (GScalabilityUsingTemporaryQualityLevels && !bForce)

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

Scope (from outer to inner):

file
function     void USkeletalMesh::FinishPostLoadInternal

Source code excerpt:

				for (const TPair<FName, int32>& Pair : SortedPerPlatforms)
				{
					FSupportedQualityLevelArray QualityLevels;
					FString PlatformEntry = Pair.Key.ToString();

					QualityLevels = QualityLevelProperty::PerPlatformOverrideMapping(PlatformEntry);

					// we now have a range of quality levels supported on that platform or from that group
					// note: 
					// -platform group overrides will be applied first
					// -platform override sharing the same quality level will take the smallest MinLOD value between them
					// -ex: if XboxOne and PS4 maps to high and XboxOne MinLOD = 2 and PS4 MINLOD = 1, MINLOD 1 will be selected
					for (int32& QLKey : QualityLevels)
					{
						int32* Value = PerQualityLevelData.PerQuality.Find(QLKey);
						if (Value != nullptr)
						{
							*Value = FMath::Min(Pair.Value, *Value);
						}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SoundNodeQualityLevel.cpp:99

Scope (from outer to inner):

file
function     int32 USoundNodeQualityLevel::GetMaxChildNodes

Source code excerpt:

int32 USoundNodeQualityLevel::GetMaxChildNodes() const
{
	return GetDefault<UAudioSettings>()->QualityLevels.Num();
}

int32 USoundNodeQualityLevel::GetMinChildNodes() const
{
	return GetDefault<UAudioSettings>()->QualityLevels.Num();
}

void USoundNodeQualityLevel::ParseNodes( FAudioDevice* AudioDevice, const UPTRINT NodeWaveInstanceHash, FActiveSound& ActiveSound, const FSoundParseParameters& ParseParams, TArray<FWaveInstance*>& WaveInstances )
{
#if WITH_EDITOR
	int32 QualityLevel = 0;

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

Scope (from outer to inner):

file
function     void UStaticMesh::ExecutePostLoadInternal

Source code excerpt:

					for (const TPair<FName, int32>& Pair : SortedPerPlatforms)
					{
						FSupportedQualityLevelArray QualityLevels;
						FString PlatformEntry = Pair.Key.ToString();

						QualityLevels = QualityLevelProperty::PerPlatformOverrideMapping(PlatformEntry);

						// we now have a range of quality levels supported on that platform or from that group
						// note: 
						// -platform group overrides will be applied first
						// -platform override sharing the same quality level will take the smallest MinLOD value between them
						// -ex: if XboxOne and PS4 maps to high and XboxOne MinLOD = 2 and PS4 MINLOD = 1, MINLOD 1 will be selected
						for (int32& QLKey : QualityLevels)
						{
							int32* Value = PerQualityLevelData.PerQuality.Find(QLKey);
							if (Value != nullptr)
							{
								*Value = FMath::Min(Pair.Value, *Value);
							}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Tests/AutomationCommon.cpp:131

Scope (from outer to inner):

file
namespace    AutomationCommon
function     FAutomationScreenshotData BuildScreenshotData

Source code excerpt:

		Data.UniqueDeviceId = FPlatformMisc::GetDeviceId();

		Scalability::FQualityLevels QualityLevels = Scalability::GetQualityLevels();

		Data.ResolutionQuality = QualityLevels.ResolutionQuality;
		Data.ViewDistanceQuality = QualityLevels.ViewDistanceQuality;
		Data.AntiAliasingQuality = QualityLevels.AntiAliasingQuality;
		Data.ShadowQuality = QualityLevels.ShadowQuality;
		Data.GlobalIlluminationQuality = QualityLevels.GlobalIlluminationQuality;
		Data.ReflectionQuality = QualityLevels.ReflectionQuality;
		Data.PostProcessQuality = QualityLevels.PostProcessQuality;
		Data.TextureQuality = QualityLevels.TextureQuality;
		Data.EffectsQuality = QualityLevels.EffectsQuality;
		Data.FoliageQuality = QualityLevels.FoliageQuality;
		Data.ShadingQuality = QualityLevels.ShadingQuality;
		
		//GRHIDeviceId

		// TBD - 
		// Device's native resolution (we want to use a hardware dump of the frontbuffer at the native resolution so we compare what we actually output rather than what we think we rendered)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/Scalability.h:172

Scope (from outer to inner):

file
namespace    Scalability

Source code excerpt:


	/** This is the only suggested way to set the current state - don't set CVars directly **/
	ENGINE_API void SetQualityLevels(const FQualityLevels& QualityLevels, bool bForce = false);

#if WITH_EDITOR
	ENGINE_API void ApplyCachedQualityLevelForShaderPlatform(const EShaderPlatform& ShaderPlatform);
#endif

	/** This is the only suggested way to get the current state - don't get CVars directly */

#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Private/LandscapeSubsystem.cpp:195

Scope (from outer to inner):

file
function     void ULandscapeSubsystem::Initialize
lambda-function

Source code excerpt:

#endif
	
	OnScalabilityChangedHandle = Scalability::OnScalabilitySettingsChanged.AddLambda([](const Scalability::FQualityLevels& QualityLevels)
    {
    	for (auto* LandscapeComponent : TObjectRange<ULandscapeComponent>(RF_ClassDefaultObject | RF_ArchetypeObject, true, EInternalObjectFlags::Garbage))
    	{
    		LandscapeComponent->MarkRenderStateDirty();
    	}
    });

#Loc: <Workspace>/Engine/Source/Runtime/MovieSceneCapture/Private/MovieSceneCapture.cpp:452

Scope (from outer to inner):

file
function     void UMovieSceneCapture::Initialize

Source code excerpt:

	{
		CachedQualityLevels = Scalability::GetQualityLevels();
		Scalability::FQualityLevels QualityLevels = CachedQualityLevels;
		QualityLevels.SetFromSingleQualityLevelRelativeToMax(0);
		Scalability::SetQualityLevels(QualityLevels);
	}

	if (!HasAnyFlags(RF_ClassDefaultObject))
	{
		FActiveMovieSceneCaptures::Get().Add(this);
	}