Download

Is there a way to have static constant pointer to UStaticMesh?

I’m trying to create a class for quick access for various pointers to UStaticMesh objects.
I should mention that the other data-types I tried worked fine to me.
I define ‘const static’ according to Rama’s example.
May be I’m doing something horribly stupid for I am horribly unexperienced with coding.
Here’s the header:


class MyProject_API TestClass
{
public:
    TestClass();

    static UStaticMesh* QuickMesh(FString Path); //Static function that'd allow me to get a pointer whenever I want
    static UStaticMesh* const Mesh; //Static constant pointer to the mesh I intend to use

    ~TestClass();
};

And here’s the source:


UStaticMesh* TestClass::QuickMesh(FString Path)
{
    ConstructorHelpers::FObjectFinder<UStaticMesh> MeshCompAsset(*Path);
    if (MeshCompAsset.Succeeded())
        return MeshCompAsset.Object;
    else
        return NULL;
}

TestClass::TestClass()
{
}

UStaticMesh* const TestClass::Mesh = TestClass::QuickMesh("My absolutely correct path");

TestClass::~TestClass()
{
}

The compilation is going fine, but as soon as I launch the game, the unreal editor crashes and corrupts my solution so I have to regenerate the visual studio files every time, which is very frustrating.
I tried to avoid using those pointers by replacing them with paths to the mesh, but thus I cannot create the pointer to mesh in other functions, for example, in ::BeginPlay().

UPD: Tested this with non-const pointer. The same result.

I feel it is suspicious to call QuickMesh to initialize a static pointer. It might be called before the engine finished initializing, hence using ConstructorHelpers at that instance of time might cause problems. Instead, try initializing the static pointer to null, then proceed to call QuickPath in the constructor. That would necessitate your pointer declaration changes from:


UStaticMesh* const

to


UStaticMesh*

Also, can you elaborate more on why storing a path instead is not working for you? Is TestClass supposed to be associated with one, hard-coded, static mesh asset? Or is the user providing the path with every query. Basically, how do you intend to use this class.

It’s not possible. static const data is evaluated at compile time.

Aside from that, it’s a bad idea to have a raw pointer to an asset like this anyway. Reflection will not be able to keep track of it, and the mesh may therefore be unloaded, or not loaded at all.

The reason why do I need to initialize the pointers to the meshes at the very beginnig is that the pointer is a variable of my custom struct:


struct SampleData //Constant data only to copy
{
FString Type = "None";
UStaticMesh* Mesh;
/*other data*/
}

The TestClass I presented is a list of constant exemplars of these structs and it also contains various helper functions. Anyway, I don’t think it’d differ much from extern TMap of these structs. I’m glad you’re willing to help me so I’ll make an attemp to clarify as much as possible and delete the code unnecessary for my case.

In another class I’m trying to realize following:
(header)


class SDS_API InstancedObjectsManager: public AActor
{
public:    
    InstancedObjectsManager();

    TMap <FString, UHierarchicalInstancedStaticMeshComponent*> HISMCsMap;

    int CreateObject( const SampleObject* DataToCopy, FVector Where);
}

(source)


int InstancedObjectsManager::CreateObject(const SampleData* DataToCopy, FVector Where)
{
    if ((DataToCopy == NULL) | (DataToCopy->Type == TEXT("None")))
    {
        return -1;
    }
    RealData Data = DataToCopy; //I have operator that copies the data, it doesn't really matter here I guess
    UHierarchicalInstancedStaticMeshComponent* HISMC = NULL;
    FString Type = Data.Type;
    if (HISMCsMap.Contains(Type)) //If there's already HISMC of the Type
        HISMC = HISMCsMap[Type]; //Then use that very HISMC
    else
    {
        UStaticMesh* Mesh = Data.Mesh; //Get the Mesh

        if (Mesh != NULL) //If the Mesh is valid
        {
            HISMC = NewObject<UHierarchicalInstancedStaticMeshComponent>(this); //Then we create new HISMC for this Type
            HISMC->RegisterComponent();
            HISMC->SetStaticMesh(Mesh); //And Set the mesh for it
            HISMCsMap.Add(Type, HISMC); //And assign it to the map
        }
    }
    if (HISMC != NULL) //If we actually have done it and the HISMC is valid
    {
        FTransform T = FTransform(FQuat(0.0f, 0.0f, 1.0f, 0.0f), Where, FVector(1.0f, 1.0f, 1.0f));
        int ID = -1;
        ID = HISMC->AddInstance(T);//Then we add the object to its target location
        return ID;
    }
    else
        return -2;
}

The reason I can’t use mesh path is that the ConstructorHelpers::FObjectFinder<UStaticMesh> won’t work outside of constructor.
Thanks for any help.

You helped me a lot, thanks. How do I close topic?