Download

Creating an instance of a class from another class constructor - why am I crashing?!

I have this class:



UCLASS()
class SHOOTHERTEST_API AWeapon : public AActor
{
    GENERATED_BODY()

public:    
    // Sets default values for this actor's properties
    AWeapon();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:    
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(EditAnywhere,BlueprintReadWrite)
    uint8 AmmoCount;

private:

    UFUNCTION(BlueprintCallable, meta = (AllowPrivateAccess = "true"))
    void Shoot();
};


and I would like to be able to create a AWeapon instance from the MyCharacter class constructor, by calling:


Weapon = NewObject<AWeapon>();

But this crashed the engine.

Though, the same call from MyCharacter::BeginPlay after Super::BeginPlay, works fine and cause no crashes.

Why is this?! There is a way to construct AWeapon instance from MyCharacter constructor?

You don’t want to use NewObject for Actors (only UObjects). Instead you want to do grab the world (GetWorld()) and call SpawnActor.



Weapon = GetWorld()->SpawnActor<AWeapon>();


EDIT: Also constructors in UE4 are strange and not the best way to do member initialization, just use OnBeginPlay / PostLoad / etc.

Thanks :slight_smile:

I was watching the documentation → http://api.unrealengine.com/INT/API/…/SpawnActor/4/

How come the example call in that page doesn’t respect the function signature at the top of the page? Shouldn’t the first argument be an FVector?!

Furthermore, If I want my Weapon constructor to take additional parameters, there is a way to pass said parameters to the Actor constructor at construction time? (like a version of SpawnActor that take a variadic list of arguments to forward to the AWeapon constructor)

There are multiple overloads of the method available, the one taking an UClass* first can be used to spawn instances of blueprint classes that derive from the class you put in the template argument.

Unfortunately, there is not. You’ll have to assign them after creating the object, or set up default values for them in blueprints.

That is really unfortunate.
Thanks for clearing things up :slight_smile:

You don’t really need to pass custom parameters to the constructor anyway, since you wlil have a two-step construction process. First is the usual c++ constructor and second is the BeginPlay function. Lot’s of stuff depend on a proper initialization of the environment, so many gameplay related things should be initialized in BeginPlay

Is a convenience matter, with the current method you have to declare



FActorSpawnParameters Params{};
Params.Owner = this;


And then pass that Params variable to the SpawnActor function, I would rather save myself those 2 lines and have it setup in a way that my weapon takes ACharacter* Owner from the constructor and I pass just this in a hypothetical implementation which takes a variadic argument list (along with other stuff that could change how the weapon is built), and assigning the Owner to the Weapon from inside the Weapon constructor.
Not to mention that in my case since said constructor is meant to be called from the BeginPlay of another class, said Environment initialization you mention has already took place (I mean we have a UWorld and such, I guess).