bSnapToGrid

bSnapToGrid

#Overview

name: bSnapToGrid

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 11 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of bSnapToGrid is to control whether samples in a BlendSpace or BlendSpace1D should be automatically aligned to a grid when added, moved, or when the axes are changed. This setting is primarily used in the animation system of Unreal Engine 5, specifically for blend spaces.

The Unreal Engine subsystems that rely on this setting variable are the Animation system and the Editor system. It is used in the Persona editor (for animation editing) and in the UnrealEd core.

The value of this variable is set in several places:

  1. It is initialized to false in the FBlendParameter constructor in BlendSpace.h.
  2. It can be modified through the Unreal Editor interface, as it is marked with UPROPERTY(EditAnywhere).
  3. It is parsed from command-line arguments in some UnrealEd functions.

This variable interacts with other BlendParameter properties such as Min, Max, and GridNum. When bSnapToGrid is true, these other properties are used to calculate the grid points to which samples are snapped.

Developers must be aware that:

  1. Changing this value can affect the positioning of existing samples in a blend space.
  2. It can impact the behavior of blend space editing tools in the Persona editor.
  3. When true, it enforces a more structured layout of samples but may limit precise positioning.

Best practices when using this variable include:

  1. Consider the needs of your specific animation setup when deciding whether to enable or disable grid snapping.
  2. Be consistent across similar blend spaces in your project to maintain a uniform editing experience.
  3. If enabling grid snapping, ensure that the grid size (controlled by GridNum) is appropriate for your use case.
  4. Be aware that changing this value after samples have been placed may require readjustment of your blend space.
  5. Use in conjunction with other BlendParameter properties to achieve the desired sample distribution and behavior.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:564, section: [UnrealEd.UIEditorOptions]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Editor/Persona/Private/SAnimationBlendSpaceGridWidget.cpp:2409

Scope (from outer to inner):

file
function     void SBlendSpaceGridWidget::UpdateCachedBlendParameterData

Source code excerpt:

		SampleGridDelta.Y /= (BlendParameterY.GridNum);

		bSampleSnapToGrid[0] = BlendParameterX.bSnapToGrid;
		bSampleSnapToGrid[1] = BlendParameterY.bSnapToGrid;

		SampleGridDivisions.X = BlendParameterX.GridNum;
		SampleGridDivisions.Y = BlendParameterY.GridNum;

		ParameterXName = FText::FromString(BlendParameterX.DisplayName);
		ParameterYName = FText::FromString(BlendParameterY.DisplayName);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdSrv.cpp:2006

Scope (from outer to inner):

file
function     bool UUnrealEdEngine::Exec_Actor

Source code excerpt:

		InWorld->GetDefaultBrush()->Modify(false);

		bool bSnapToGrid=0;
		FParse::Bool( Str, TEXT("SNAPTOGRID="), bSnapToGrid );

		// Create a bounding box for the selected static mesh triangles and set the builder brush to match it

		TArray<FPoly*> SelectedPolys = GetSelectedPolygons();
		CreateBoundingBoxBuilderBrush( InWorld, SelectedPolys, bSnapToGrid );

		// Create the blocking volume

		GUnrealEd->Exec( InWorld, TEXT("BRUSH ADDVOLUME CLASS=BlockingVolume") );

		// Clean up memory

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdSrv.cpp:2037

Scope (from outer to inner):

file
function     bool UUnrealEdEngine::Exec_Actor

Source code excerpt:

		InWorld->GetDefaultBrush()->Modify(false);

		bool bSnapToGrid=0;
		FParse::Bool( Str, TEXT("SNAPTOGRID="), bSnapToGrid );

		// The rejection tolerance.  When figuring out which planes to cut the blocking volume cube with
		// the code will reject any planes that are less than "NormalTolerance" different in their normals.
		//
		// This cuts down on the number of planes that will be used for generating the cutting planes and,
		// as a side effect, eliminates duplicates.

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdSrv.cpp:2057

Scope (from outer to inner):

file
function     bool UUnrealEdEngine::Exec_Actor

Source code excerpt:


		TArray<FPoly*> SelectedPolys = GetSelectedPolygons();
		CreateBoundingBoxBuilderBrush( InWorld, SelectedPolys, bSnapToGrid );

		// Get a list of the polygons that make up the builder brush

		FPoly* poly;
		TArray<FPoly>* BuilderBrushPolys = new TArray<FPoly>( InWorld->GetDefaultBrush()->Brush->Polys->Element );

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Animation/BlendSpace.h:131

Scope: file

Source code excerpt:

	/** If true then samples will always be snapped to the grid on this axis when added, moved, or the axes are changed. */
	UPROPERTY(EditAnywhere, DisplayName = "Snap to Grid", Category = BlendParameter)
	bool bSnapToGrid;

	/** If true then the input can go outside the min/max range and the blend space is treated as being cyclic on this axis. If false then input parameters are clamped to the min/max values on this axis. */
	UPROPERTY(EditAnywhere, DisplayName = "Wrap Input", Category = BlendParameter)
	bool bWrapInput;

	FBlendParameter()

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Animation/BlendSpace.h:142

Scope (from outer to inner):

file
function     FBlendParameter

Source code excerpt:

		, Max(100.f)
		, GridNum(4) // TODO when changing GridNum's default value, it breaks all grid samples ATM - provide way to rebuild grid samples during loading
		, bSnapToGrid(false)
		, bWrapInput(false)
	{
	}

	float GetRange() const
	{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/BlendSpace.cpp:175

Scope (from outer to inner):

file
function     void UBlendSpace::PostEditChangeProperty

Source code excerpt:

			for (int32 AxisIndex = 0; AxisIndex != 2; ++AxisIndex)
			{
				if (BlendParameters[AxisIndex].bSnapToGrid)
				{
					float GridDelta = PreviousGridSpacings[AxisIndex];
					float Range = (BlendParameters[AxisIndex].Max - BlendParameters[AxisIndex].Min);
					BlendParameters[AxisIndex].GridNum = FMath::Max(1, (int32)(0.5f + Range / GridDelta));
					BlendParameters[AxisIndex].Min = BlendParameters[AxisIndex].Max - BlendParameters[AxisIndex].GridNum * GridDelta;
				}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/BlendSpace.cpp:189

Scope (from outer to inner):

file
function     void UBlendSpace::PostEditChangeProperty

Source code excerpt:

			for (int32 AxisIndex = 0; AxisIndex != 2; ++AxisIndex)
			{
				if (BlendParameters[AxisIndex].bSnapToGrid)
				{
					float GridDelta = PreviousGridSpacings[AxisIndex];
					float Range = (BlendParameters[AxisIndex].Max - BlendParameters[AxisIndex].Min);
					BlendParameters[AxisIndex].GridNum = FMath::Max(1, (int32)(0.5f + Range / GridDelta));
					BlendParameters[AxisIndex].Max = BlendParameters[AxisIndex].Min + BlendParameters[AxisIndex].GridNum * GridDelta;
				}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/BlendSpace.cpp:2404

Scope (from outer to inner):

file
function     void UBlendSpace::SnapSamplesToClosestGridPoint

Source code excerpt:

void UBlendSpace::SnapSamplesToClosestGridPoint()
{
	if (BlendParameters[0].bSnapToGrid && BlendParameters[1].bSnapToGrid)
	{
		TArray<int32> ClosestSampleToGridPoint;

		const FVector GridMin(BlendParameters[0].Min, BlendParameters[1].Min, 0.0f);
		const FVector GridMax(BlendParameters[0].Max, BlendParameters[1].Max, 0.0f);
		const FVector GridRange(GridMax.X - GridMin.X, GridMax.Y - GridMin.Y, 0.0f);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/BlendSpace.cpp:2473

Scope (from outer to inner):

file
function     void UBlendSpace::SnapSamplesToClosestGridPoint

Source code excerpt:

		}
	}
	else if (BlendParameters[0].bSnapToGrid || BlendParameters[1].bSnapToGrid)
	{
		// We only snap on one axis, but need to make sure we don't collapse samples on top of each
		// other. Just snap to the nearest grid value, unless it would result in a duplicate

		int32 AxisIndex = BlendParameters[0].bSnapToGrid ? 0 : 1;

		float GridMin = BlendParameters[AxisIndex].Min;
		float GridMax = BlendParameters[AxisIndex].Max;
		int32 GridNum = BlendParameters[AxisIndex].GridNum;
		float GridDelta = (GridMax - GridMin) / GridNum;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/BlendSpace1D.cpp:23

Scope (from outer to inner):

file
function     void UBlendSpace1D::SnapSamplesToClosestGridPoint

Source code excerpt:

void UBlendSpace1D::SnapSamplesToClosestGridPoint()
{
	if (!BlendParameters[0].bSnapToGrid)
		return;

	TArray<int32> ClosestSampleToGridPoint;

	const float GridMin = BlendParameters[0].Min;
	const float GridMax = BlendParameters[0].Max;