Download

Change StaticMesh runtime via C++

Immediately apologize for my english.
I have some interesting problem.
I have task to change static meshes in runtime via C++.
And I found 2 ways to implement this task:

  1. Create direct object references via the method “ConstructorHelpers::FObjectFinder” in Constructor of Class:


UStaticMesh *MeshForLoad;
auto Mesh = ConstructorHelpers::FObjectFinder<UStaticMesh>( TEXT( "StaticMesh' PathToObject'"));
if ( Mesh.Object )
  {
       MeshForLoad = Mesh.Object;
  }

Then in Component start method SetStaticMesh( MeshForLoad);

That way is hardway to designers - I created code, but designers cannot have access for reference change without editing code.

  1. Create DataTable via struct, and via TAssetPtr load objects. So. It way very cool and easy for architecture, but I have problem.
  • I create struct MeshList with Property TAssetPtr <UStaticMesh> MeshPtr;
  • I create DataTable from struct MeshList.
  • Designer setup some meshes (like 2-3 references).
  • Via Code I find references, try to **SetStaticMesh( MeshPtr.Get() ). **But. Mesh does not want to load. Method “Get()” return null. As far as I understand - TAssetPtr stores a link to the location of the object (in my case - location of the Static Mesh).

Okey, I found information about AssetManager (and StreamableManager). That objects can help me to load my assets.
BUT.

I Cannot find informantion about how create that objects (how initialize instance for work with it). In Documentation all examples are based on the fact that the object of AM (or SM) has already been created.
Or, in some case we have singleton, which (like witch) not work in 4.22.1 =(

Please help me =(((

https://wiki.unrealengine.com/TAssetPtr_and_Asynchronous_Asset_Loading i think u should read this.

@**hien27021990 ** On this page just talking about how use a AssetManager, but not have any information, how create that object, or where it can find.

You can do something like this:



#include "Runtime/CoreUObject/Public/UObject/SoftObjectPtr.h"




UPROPERTY( Category="MyCategory", EditAnywhere, BlueprintReadWrite, meta=( DisplayName="My Custom Mesh", **AllowedClasses="StaticMesh"** ) )
**FSoftObjectPath **CustomMesh;




MeshForLoad = Cast<UStaticMesh>( CustomMesh.ResolveObject() );

if ( MeshForLoad == nullptr )
{
    MeshForLoad = Cast<UStaticMesh>( CustomMesh.TryLoad() );  // Load asset if not already loaded, this is slow...
}



That way people using the editor can just set the value of CustomMesh and in code you can use whatever mesh they inserted there.
Note: This is Unreal 4.20 ~ 4.22 API, in older versions this might not work at all.

[USER=“434”]BrUnO XaVIeR[/USER]

Yes! Finally! =) That was my headache for a week! =)
Thanks a lot! =)

This way is much easier than all the others that I try to use.
Do I understand correctly that in this way I can load materials, textures, etc.?

Yes, I do that to load lots of different things.
Including textures for loading screens, images for Slate UI and etc.

Cool! =) Thanks again =) You super =)

That is not load, FSoftObjectPath only store infomation about the path to the object that is already loaded, if u want to load obj, u should use TAssetPtr and AssetManager. Pls correct me if i wrong but ue’s documentation wrote that.

It’s more than enough lol.

@Hiengs2702 , Do you try initialize StreamableMeneger like in that documentation? It was on 4.22? Or you just read it and say - “that enough lol” ?

There’s a link to the API page there. You could, maybe, read it…

Wiki pages are written by users, they are not official documentation.

[USER=“434”]BrUnO XaVIeR[/USER] Hi. Can you help me again?

I need to load U**UserWidget **to my WidgetComponent in AActor.
I set link to file via FSoftObjectPath.
File found, worked (I mean, if branch see him). Its not nullptr.
BUT. I can’t Cast UObject to UUserWidget (Or my type like UWidgetTest which parant for my Widget that I tryed to load(If you understand my bad english =)) ))

So. How can I setup my Widget to Component (via c++, of course).

To spawn widgets from asset, after loaded, don’t cast the UUserWidget to your asset.
Instead get class from asset:



class UMyWidgetType* Widget;




Widget = CreateWidget<UMyWidgetType>( GetWorld(), WidgetAsset.Class );


Turns out that asset must be like auto WidgetAsset = ConstructorHelpers::FObjectFinder<UUserWidget>?

Something like that?

In constructor:



auto WidgetAsset = ConstructorHelpers::FObjectFinder<UUserWidget>( TEXT( "WidgetBlueprint' " %PathTo% /BP_Widget_Menu.BP_Widget_Menu'" ) );

    if ( WidgetAsset.Succeeded() )
        {
            UDepartMenuWidget_Base *Widget = CreateWidget<UDepartMenuWidget_Base>( GetWorld(), WidgetAsset.Class );
            WidgetComponent_DepartmentMenu->SetWidget( Widget );
        }


If all you need from it is just to know the class, you can use TSubclassOf<UUserWidget> instead.
Works the same.

Thanks a lot =) But I still have problem. There I wrote some interesting behavior, when I try to use TSubclassOf.
In Short - its works wile I have open Editor. When it close and restart - I have problem - crash and errors =(

https://forums.unrealengine.com/deve…n-aactor-via-c