Automatically assign thousands of Static Meshes to Actor

Hi, i’m looking for a way to automatically assign static meshes to actors. Its a imported datasmith with thousands of meshes.

image
They all have the same name just different numbers.

image
I want to automatically assign a static mesh to each one of them.

image
The static meshes have the same name as the actors “ON_Brep_number”.

What’s the way to do this? Automatically with a script or in any other ways?
Thank you in advance. :slight_smile:

Static Library to gather meshes
header file .h

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "AssetFunctionLibrary.generated.h"

/**
 * 
 */
UCLASS()
class YOUR_API UAssetFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

	UFUNCTION(BlueprintCallable)
	static TArray<UStaticMesh*> ImportStaticMeshArray(const FString directory, const FString onlyFilesStartingWith, bool IncludeSubdirectories);

	UFUNCTION()
		static TArray<FString> GetAllFilesInDirectory(const FString directory, const bool fullPath, const FString onlyFilesStartingWith, const FString onlyFilesWithExtension, bool skipRecursionSelf);

	UFUNCTION()
		static FString filterDirectory(FString& path);
};

CPP file

#include "AssetFunctionLibrary.h"
#include "Engine/StaticMesh.h" 
#include "Misc/LocalTimestampDirectoryVisitor.h" 

TArray<UStaticMesh*> UAssetFunctionLibrary::ImportStaticMeshArray(const FString directory, const FString onlyFilesStartingWith, bool IncludeSubdirectories)
{
	TArray<UStaticMesh*> returnFiles;
	FString directoryCut = directory;
	filterDirectory(directoryCut);

	FString contentPath = FPaths::ProjectContentDir();
	FString fullPath = FPaths::ConvertRelativePathToFull(contentPath);
	FString fullProjPath = fullPath + directory;
	TArray<FString> files = GetAllFilesInDirectory(fullProjPath, true, onlyFilesStartingWith, "uasset", !IncludeSubdirectories);

	for (int i = 0; i < files.Num(); i++) {

		files[i].RemoveFromStart(fullPath);
		files[i].RemoveFromEnd(".uasset");
		
		FString filePath = "/Game/" + files[i];
		FSoftObjectPath MeshPath(TEXT("UStaticMesh'" + filePath + "'"));

		auto resolve = MeshPath.ResolveObject();
		
		UStaticMesh* mesh = Cast<UStaticMesh>(resolve);
		if (mesh == nullptr)
		{
			UObject* testObj = MeshPath.TryLoad();
			if (testObj != nullptr) {
				UClass* c = testObj->GetClass();
				if (c == UStaticMesh::StaticClass()) {
					mesh = CastChecked<UStaticMesh>(testObj);
					returnFiles.Add(mesh);
				}
			}
		}
	}
	return returnFiles;
}

TArray<FString> UAssetFunctionLibrary::GetAllFilesInDirectory(const FString directory, const bool fullPath, const FString onlyFilesStartingWith, const FString onlyFilesWithExtension, bool skipRecursionSelf = true)
{
	FString directoryCut = directory;
	filterDirectory(directoryCut);

	// Get all files in directory
	TArray<FString> directoriesToSkip;
	TArray<FString> directoriesToSkipRecurse;
	if (skipRecursionSelf == true) {
		directoriesToSkipRecurse.Add(directoryCut);
	}
	IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
	FLocalTimestampDirectoryVisitor Visitor(PlatformFile, directoriesToSkip, directoriesToSkipRecurse, false);
	PlatformFile.IterateDirectory(*directoryCut, Visitor);
	TArray<FString> files;

	for (TMap<FString, FDateTime>::TIterator TimestampIt(Visitor.FileTimes); TimestampIt; ++TimestampIt)
	{
		const FString filePath = TimestampIt.Key();
		const FString fileName = FPaths::GetCleanFilename(filePath);
		bool shouldAddFile = true;

		// Check if filename starts with required characters
		if (!onlyFilesStartingWith.IsEmpty())
		{
			const FString left = fileName.Left(onlyFilesStartingWith.Len());

			if (!(fileName.Left(onlyFilesStartingWith.Len()).Equals(onlyFilesStartingWith)))
				shouldAddFile = false;
		}

		// Check if file extension is required characters
		if (!onlyFilesWithExtension.IsEmpty())
		{
			if (!(FPaths::GetExtension(fileName, false).Equals(onlyFilesWithExtension, ESearchCase::IgnoreCase)))
				shouldAddFile = false;
		}

		// Add full path to results
		if (shouldAddFile)
		{
			files.Add(fullPath ? filePath : fileName);
		}
	}

	return files;
}

FString UAssetFunctionLibrary::filterDirectory(FString& path)
{
	if (path.Len() > 0) {
		path.ReplaceInline(TEXT("\\"), TEXT("/"), ESearchCase::CaseSensitive);
		path.ReplaceInline(TEXT("//"), TEXT("/"), ESearchCase::CaseSensitive);
		path.RemoveFromStart(TEXT("/"));
		path.RemoveFromEnd(TEXT("/"));
		FPlatformMisc::NormalizePath(path);
		path.RemoveFromEnd(FPaths::GetExtension(path, true));
	}
	return path;
}

Editor tool

AssignStaticMesh.uasset (217.6 KB)

Replace YOUR_API with your project _API

Once compiled go into content browser and right click tool “AssignStaticMesh” & select “Run Editor Utility Widget”

Follow instructions