Calling method with generic parameters


I’ve written this method to spawn a class inheriting ASpawnable, which inherits from AActor:

ASpawnable* MemoryHelper::SpawnEntity(UObject* context, TSubclassOf<ASpawnable> entityClass, std::vector<object> initParams)
    FTransform spawnArgs(FRotator::ZeroRotator, FVector::ZeroVector);
    auto entity = Cast<ASpawnable>(UGameplayStatics::BeginDeferredActorSpawnFromClass(context, entityClass.StaticClass(), spawnArgs));

    UGameplayStatics::FinishSpawningActor(entity, spawnArgs);

What it should do is this:

  1. Create an empty FTransform
  2. Begin spawning the actor, cast to the derived class which is inheriting ASpawnable
  3. Call Init() with those params. This is the tricky part, ASpawnable has a pure virtual function Init which AFuelTank, a class which inherits from ASpawnable, overrides. This pure virtual function in ASpawnable is there so this method can call the Init function of any class deriving from ASpawnable, as each of them can have different arguments for Init and I don’t know how to call this properly to pass the arguments. I believe it will have to involve reflection.

I’m getting a few errors with this;

std::vector<object> initParams;
error on 'object', undefined

error on 'StaticClass', TSubclassOf<ASpawnable> has no member 'StaticClass'

error on 'initParams' as I have no idea how to have params in the method signature

If you could help me figure out how to do this, I’d really appreciate it.

You might benefit from switching things over to UE4 idioms.
So I’d recommend trying TArray initParams instead.
TArray is Unreal’s Array/Vector approach. It’s cross platform and behaves in the same way across all platforms (iirc).
And just in case you’re not entirely familiar, UObject’s are Unreal’s base class, that all Unreal’s object system is built upon.

This one threw me when I first started with Deferred actor spawning.
The StaticClass method is accessed statically, not through an instance of an object. So ASpawnable::StaticClass() rather than ->StaticClass() or .StaticClass().

I think once you switch to using a TArray<UObject> then you should be OK to throw different types of objects, with different number of items in each array.
But one great thing with Deferred is that you could do multiple casts and depending on which one != nullptr, then call a different initialization function with different params - or multiple functions, or any hybrid you like.

Hope that helps :slight_smile:

Instead of std:vector try using TArray<???>.
Instead of entityClass.StaticClass() use (*entityClass)
Dunno what your signature is for Init, although assuming it is std:vector, try making the same change to TArray<>