Download

How do you load a static mesh at runtime?

Hello everyone,

I am trying to create a prop class that is a lot like the one in Garrysmod. I think I know how to do everything needed to make one except for loading the dang mesh. I know I can set the static mesh component’s mesh in the component tab but I want to be able to set it while the game is running. If someone can provide an example, that would be awesome. Also, I am trying to make a menu where I can choose which model to use when I spawn the prop. Do you guys have any tips? I have never done UI programming and making a dynamic UI seems pretty difficult to me.

You should be able to just use the Set Static Mesh node to change the mesh:

SetMesh.JPG

What I mean is, how do I create a mesh object (using a string that’s the path) to pass to the “Set Static Mesh” node? By the way, it is cool that a lead programmer is helping a little newbie like me. :o

Ah, I’m afraid you can’t load an object from a string in a Blueprint, you will need to use C++ for this.

Is there a way to create a blueprint node that will do that?

Certainly, you would just create a C++ function that uses the LoadObject function, and then expose that to blueprints in the normal way (the BlueprintCallable keyword inside the UPROPERTY declaration).

This work?

I tried doing that before but I don’t know how to go about doing it. Do I make a utility header file like this that I include in my main project file?


// Utility.h

#pragma once

#include "Utility.generated.h"

//Get Path
static FORCEINLINE FName GetObjPath(const UObject* Obj)
{
	if (!Obj) return NAME_None;
	if (!Obj->IsValidLowLevel()) return NAME_None;
	//~

	FStringAssetReference ThePath = FStringAssetReference(Obj);

	if (!ThePath.IsValid()) return NAME_None;

	//The Class FString Name For This Object
	FString Str = Obj->GetClass()->GetDescription();

	Str += "'";
	Str += ThePath.ToString();
	Str += "'";

	return FName(*Str);
}


//TEMPLATE Load Obj From Path
template <typename ObjClass>
static FORCEINLINE ObjClass* LoadObjFromPath(const FName& Path)
{
	if (Path == NAME_None) return NULL;
	//~

	return Cast<ObjClass>(StaticLoadObject(ObjClass::StaticClass(), NULL, *Path.ToString()));
}

/*
// Load PS From Path 
static FORCEINLINE UParticleSystem* LoadPSFromPath(const FName& Path)
{
	if (Path == NAME_None) return NULL;
	//~

	return LoadObjFromPath<UParticleSystem>(Path);
}


// Load Material From Path 
static FORCEINLINE UMaterialInterface* LoadMatFromPath(const FName& Path)
{
	if (Path == NAME_None) return NULL;
	//~

	return LoadObjFromPath<UMaterialInterface>(Path);
}

// Load Static Mesh From Path 
static FORCEINLINE UStaticMesh* LoadMeshFromPath(const FName& Path)
{
	if (Path == NAME_None) return NULL;
	//~

	return LoadObjFromPath<UStaticMesh>(Path);
}
*/

//note about UBlueprintFunctionLibrary
// This class is a base class for any function libraries exposed to blueprints.
// Methods in subclasses are expected to be static

UCLASS()
class UUtility : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

	UFUNCTION(BlueprintCallable, Category = "Utility")
	static UStaticMesh LoadMeshFromPath(const FName& path);

	
	//UFUNCTION(BlueprintCallable, Category = "Utility")
	//	static bool SaveStringTextToFile(FString SaveDirectory, FString FileName, FString SaveText, bool AllowOverWriting = false);
};

And the .cpp file


// Utility.cpp

#include "GameName.h"
#include "Utility.h"


UUtility::UUtility(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{

}


UStaticMesh UUtility::LoadMeshFromPath(FName& path)
{
	if (path == NAME_None) return NULL;
	//~

	return LoadObjFromPath<UStaticMesh>(path);
}

I tried using the code above and my editor started to crash when launched. I don’t know if that is what caused it, but recreating the project fixed it. Is there something wrong with my code?

I haven’t tested your code, but aren’t you missing a pointer?

UStaticMesh UUtility::LoadMeshFromPath(FName& path)
should be UStaticMesh*

I tried the above code with a static mesh from the startercontent but based on the path, I can’t get a mesh of it.
I didn’t use the “GetObjPath” but my own function to get the path to the file as a FString.
Must the file in a specific type, other than uasset?