Use an editor-selectable mesh from a different object

Hello,

I got stuck at a probably trivial problem that is however not present in any example I could find and too alien to regular C++. I have a character class. I want him to be able to select from a group of weapons (but it could be pretty much any selectable gear). So I have created a class called UWeapon, gave it editor-editable properties and created a few blueprint derived classes for various weapons. This worked fine for numeric properties, but I can’t figure out how to assign it a mesh and have the character class attach it to one of its sockets.

If I did this, I could select a mesh:

UPROPERTY(EditDefaultsOnly)
TAssetPtr<USkeletalMesh> weaponMesh;

But then I didn’t know how to create an actual instance from the resource, the following doesn’t do anything:

// In the character's class' BeginPlay
GunRight = Cast<USkeletalMeshComponent>(UAssetManager::GetStreamableManager().LoadSynchronous(rightWeapon()->weaponMesh));
MuzzleLocationRight->SetupAttachment(GunRight);

I tried to create it as a USkeletalMesh using CreateDefaultSubobject(), and attach it to the socket, but it segfaulted:

// in UWeapon's constructor
weaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));

I also tried to use NewObject, but I didn’t know how to make it choose a mesh selected in the Blueprint.

All examples use CreateDefaultSubobject in the character class, but that’s not feasible in this case. How do I instantiate a mesh chosen in a different object?

Thanks in advance.

Hi! Unreal has several things in it:

  • Assets: they are input data for editor, for example music files (USoundBase*), sprites (UTexture2D*), skeletal meshes (USkeletalMesh*). This objects shouldn’t be created with CreateDefaultSubobject. They in most cases are imported to editor

  • Components: this things that you need. For your question just use USkeletalMeshComponent with UPROPERTY like

    UPROPERTY(EditAnywhere)

    USkeletalMeshComponent MyMesh;*

class instead of TAssetPtr. With them you can easily use CreateDefaultSubobject

  • Actors: those are the ones that fill the scene. They can has some own logic and also can contain Components

Thanks for the reply. Unfortunately, I wasn’t able to use CreateDefaultSubobject in this situation (which could be because of my unfamiliarity with Unreal rather than impossibility). I tried two options:

  • Create the subobject in the weapon object, then attach it to the player that is supposed to use the weapon - I was able to choose the mesh in the editor, but it crashed when I tried to attach the object’s mesh to the character
  • Create the subobject in the character class, define it in the weapon object - I wasn’t able to choose a mesh in the data blueprint, then it crashed

I’ve also tried creating derived classes from USkeletalMeshSubobject with a few added attributes, but when I created blueprints out of them, I couldn’t make them data-only

“I was able to choose the mesh in the editor, but it crashed when I tried to attach the object’s mesh to the character” - what do you mean here? Editor crach only because of some attach action? This may be a bug, can you share some pictures?

I was doing it wrong, now it doesn’t crash, but no meshes appear instead. The hands are holding empty space.

The mesh is an a class called UWeapon, defined as this:

UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
class USkeletalMeshComponent* WeaponMesh;

It’s chosen in the constructor as follows:

WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));

The character class holds the weapons in the following:

UPROPERTY(EditDefaultsOnly, Category=Weapon)
TArray<TSoftObjectPtr<class UWeapon>> Weapons;

The meshes are grabbed from the Weapons variable using methods rightWeapon() and leftWeapon(). I attach them in BeginPlay() (in constructor, it crashes because the array isn’t initialised at that point):

MuzzleLocationRight->SetupAttachment(rightWeapon()->WeaponMesh);

When I try to attach those, they do not appear anywhere. If those meshes are created inside the character class through CreateDefaultSubobject, they appear, so the problem isn’t in the sockets.