Nireexen
(Nireexen)
1
Hi, i’m looking for a way to automatically assign static meshes to actors. Its a imported datasmith with thousands of meshes.
They all have the same name just different numbers.
I want to automatically assign a static mesh to each one of them.
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.
3dRaven
(3dRaven)
2
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