Finding references to collision presets

Hi,

We have some project-added collision presets which I’d like to remove. Is there any way of finding all references to a collision preset so I can make sure I’m not breaking anything by doing so? Find In Blueprints doesn’t seem to find collision preset overrides in blueprints’ mesh components.

This talk mentions a small engine mod that exposes collision presets to the reference viewer (which would be ideal). Has that been published anywhere, or could you provide instructions for how to implement it?

Thanks,

Alick

[Attachment Removed]

Hi Alick,

I’ve been assigned this ticket and I’m looking into it. I should get back to you soon.

My initial idea is to implement an Editor Utility to list actors and components that use a given collision preset. I’ll try it out to see if it is really feasible and provide you a starting point and more detailed instructions soon. I’ll also see if I find any information about the method you mentioned.

Best regards

Vitor

[Attachment Removed]

Hi Alick,

About the engine modifications presented in the Unreal Fest talk, unfortunately most of them don’t seem to be publicly available. The studio that gave the talk does have a public GitHub, but the only related repository that can be found there includes just an actor for testing collision queries and some debug draw helper functions.

Going back to your original need, I don’t think I can help with exposing Collision Profile Names to the Reference Viewer, but I thought of some other approaches you can try. Let me go over them starting with some simple, but limited built-in features:

Property Matrix for Actors in a level

  1. Select all desired actors in the level editor
  2. Right-click, select “Bulk Editing -- Edit Components in the Property Matrix -- <ComponentName>”
  3. In the “Pinned Columns” tab, expand category “Collision” and pin property “Body Instance -- Collision Profile Name”
  4. In the main property matrix tab, sort components by the “Collision Profile Name” column

Note: Bulk-editing the collision profile name in the property matrix might not work as expected (UE-224076).

Property Matrix for Static Mesh Assets

  1. Select all desired StaticMesh assets in the content browser
  2. Right-click, select “Asset Actions -- Advanced -- Edit Selection in Property Matrix”
  3. In the “Pinned Columns” tab, expand category “StaticMesh” and pin property “Body Setup -- Default Instance -- Collision Profile Name”
  4. In the main property matrix tab, sort components by the “Collision Profile Name” column

Note: Bulk-editing the collision profile name in the property matrix might not work as expected (UE-224076).

Content Browser Filters for Static Mesh Assets

  1. Enter the desired root folder
  2. In the Search Bar, type “DefaultCollision:BlockAll” (without the quotes, with any collision profile name)
  3. The content browser should only show StaticMesh assets that pass this filter

---

Now, lets move on to some more powerful approaches that require some implementation.

Analyzing blueprint assets using the Subobject Data Subsystem

One idea is to implement an Asset Action Utility that lets you select some blueprint assets and, with a context-menu action, print the Collision Presets used by their primitive components (or, alternatively, print the names of the assets that use a given Collision Preset). This is illustrated here and in the image below:

[Image Removed]

Adding Collision Presets as Asset Registry Tags on Blueprint Assets

This is a very interesting approach, because once all blueprint assets have been re-saved, you will be able to filter them directly in the Content Browser by typing “CollisionPreset_BlockAllDynamic:Yes” or something similar in the search bar. For that, you need to implement the following method override on AActor itself (if you can edit the Engine source code) or on a subclass that all your blueprints derive from:

#if WITH_EDITOR
  virtual void GetAssetRegistryTags(FAssetRegistryTagsContext Context) const override;
#endif

The implementation would be something similar to this:

#include "UObject/AssetRegistryTagsContext.h"
#include "Engine/SimpleConstructionScript.h"
#include "Engine/SCS_Node.h"
 
#if WITH_EDITOR
 
void MyActorBase::GetAssetRegistryTags (FAssetRegistryTagsContext Context) const
{
	Super::GetAssetRegistryTags(Context);
 
	// Process Components added in C++
	TInlineComponentArray<TObjectPtr<UPrimitiveComponent>> PrimitiveComponents;
	GetComponents<UPrimitiveComponent>(PrimitiveComponents);
	for (const auto& PrimitiveComponent : PrimitiveComponents)
	{
		FName CollisionProfileName = PrimitiveComponent->GetCollisionProfileName();
		Context.AddTag(FAssetRegistryTag(
			FName(*FString::Printf(TEXT("CollisionPreset_%s"), *CollisionProfileName.ToString())),
			TEXT("Yes"),
			FAssetRegistryTag::TT_Alphabetical
		));
	}
 
	// Process Components added in BP
	if (const UBlueprintGeneratedClass* BGClass = Cast<UBlueprintGeneratedClass>(GetClass()))
	{
		if (const USimpleConstructionScript* SCS = BGClass->SimpleConstructionScript)
		{
			for (const USCS_Node* Node : SCS->GetAllNodes())
			{
				if (Node && Node->ComponentClass && Node->ComponentClass->IsChildOf(UPrimitiveComponent::StaticClass()))
				{
					UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(Node->ComponentTemplate);
					FName CollisionProfileName = PrimitiveComponent->GetCollisionProfileName();
 
					Context.AddTag(FAssetRegistryTag(
						FName(*FString::Printf(TEXT("CollisionPreset_%s"), *CollisionProfileName.ToString())),
						TEXT("Yes"),
						FAssetRegistryTag::TT_Alphabetical
					));
				}
			}
		}
	}
}
 
#endif

Alternatively, you can also get this Content Browser filtering capability by using Asset Metadata. I tested this by changing the Asset Action Utility above to call function EditorAssetLibrary.SetMetadataTag() on the selected blueprint assets. To enable Content Browser filtering, you must also go to Project Settings, on page “Game -- Asset Manager”, and add your metadata tags to “Asset Registry -- Metadata Tags For Asset Registry”.

Some notes:

  • the approaches above assume you are concerned with Blueprint assets only. If you need to analyze actor classes defined in C++, you’ll probably need to use TObjectIterator<UClass> in C++ to iterate over all existing classes and work with their CDO (ClassDefaultObject).
  • If you need to list all profile names in your project for a utility, you need to use C++, but you can expose a small helper function to BP:
void MyBPFunctionLibrary::GetCollisionProfileNames (TArray<FName>& OutProfileNames)
{
	UCollisionProfile* CollisionProfile = UCollisionProfile::Get();
	if (!CollisionProfile)
		return;
 
	TArray<TSharedPtr<FName>> ProfileNames;
	CollisionProfile->GetProfileNames(ProfileNames);
 
	for (const TSharedPtr<FName>& NamePtr : ProfileNames)
		OutProfileNames.Add(*NamePtr);
}

I hope this is helpful. Please let me know if one of the solutions above works for you, and feel free to ask if you have any further questions. Also, if you prefer to try the Reference Viewer approach, I can try to escalate this ticket to the engine devs to see if they can offer some more insight.

Best regards,

Vitor

[Attachment Removed]

Thanks [mention removed]​ for all the options!

What I’m really looking for is a way to find all references to a collision profile globally (not per level and not just in the defaultcollision property).

I tried the Asset Registry Tag change you suggested. It worked and didn’t seem to require a re-save, however it doesn’t catch components added dynamically (e.g. in a construction script).

I found an alternative method which does though: the Asset Search Plugin.

Thanks again for your help.

[Attachment Removed]

Hi Alick,

That’s perfect, I was not aware of this plugin and its capabilities. I took a look in the source code, and it seems to index the following asset types:

- DataAsset
- DataTable
- CurveTable
- Blueprint
- WidgetBlueprint
- DialogueWave
- World/Level
- Actor
- SoundCue
- Material
- MaterialFunction
- MaterialParameterCollection
- MaterialInstance

From them, it indexes the following property types:

- Name
- String
- Text
- Enum
- Gameplay Tag
- Gameplay Tag Container
- Object Reference (recursively)
- Soft Object Reference (non-recursively, just the reference itself)
- Other Structs (if they were explicitly exposed to the Asset Registry)

Moreover, it indexes all actor instances contained in each level, and for blueprint assets it indexes:

- The ClassDefaultObject (actor properties)
- The SimpleConstructionScript (BP-added components and their properties)
- Members
   - Functions
   - Events
   - Variables
   - Delegates (Event Dispatchers)
- Graphs:
   - All graph nodes
   - All literal values linked to node input pins

Very interesting indeed. From my experiments it does catch CollisionProfileNames from component properties on blueprint assets and level actors, as well as from BP nodes like SetCollisionProfileName() being used in the BP Construction Script and other BP graphs. I think it just does not catch collision profile names set in C++ functions, including in C++ constructors unless a BP asset was created from the C++ class.

Thank you for mentioning that solution, and let me know if you need any further assistance.

Best regards,

Vitor

[Attachment Removed]

[mention removed]​ yeah, it’s a useful plugin. I also didn’t know about it until I started investigating this.

In this case it found most but not all references to collision profiles by name. I don’t know what’s special about the ones it didn’t find - they looked like regular static mesh actors placed in levels (and the Asset Search plugin had indexed everything).

Thanks again for your help

[Attachment Removed]

Interesting. I did some more tests here and I noticed that the plugin does not index Static Mesh assets, which contain a default collision preset that will be missed. When used in an Actor, the component can be set to use the “Default” collision preset, meaning “Use the one from the Static Mesh asset”, and the plugin will also not know what preset will be actually in use there.

The default preset used by Static Mesh assets can be checked in the Property Matrix or by using the Content Browser filters I mentioned earlier.

All the best,

Vitor

[Attachment Removed]