I am trying to code a modular weapon system. The weapon is an Actor with a number of components that are responsible for different parts of the weapon.
class ARangedWeapon : public AWeapon
{
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Ammo, meta=(AllowPrivateAccess = "true"))
class UWeaponVisualsComponent* VisualsComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Ammo, meta=(AllowPrivateAccess = "true"))
class UWeaponAmmoComponent* AmmoComponent;
....
}
Each component would have events that are fired when, say the weapon is fired, or reloaded etc.
Ideally I would like to be able to subclass each component in blueprints to allow for custom behaviour and then just put them together in the Weapon blueprint, but I know that you cannot change the class of a Component.
Instead I decided that each component would have a assignable sub-object that actually did the heavy lifting of the class.
class UWeaponAmmoComponent : public UActorComponent
{
public:
UPROPERTY(EditAnywhere)
TSubclassOf<UWeaponAmmoManager> AmmoManagerClass;
protected:
UPROPERTY(BlueprintReadOnly)
class UWeaponAmmoManager AmmoManager;
}
That way I could just subclass the manager in blueprints, and set the “AmmoManagerClass” variable to be the blueprint that I want to use.
I now have two questions:
- Is this the best way of doing this? Is there a way that I can bypass having to have another sub-object, and just subclass the ActorComponents?
- How can I spawn an object of the AmmoManagerClass?
I can’t spawn it in the constructor as the value of AmmoManagerClass wouldn’t have been set in the editor yet. I tried creating the Manager in the PostInitProperty() and InitializeComponent() functions, but the normal ways of creating UObjects (ConstructObject()) caused the engine to crash with the error: “class object none was created in UWeaponAmmoComponent instead of package”.
I’m sort of all out of ideas at the moment, any help would be much appreciated.
Edit:
The two errors I’m getting are:
Object BlueprintGeneratedClass None created in WeaponAmmoComponent instead of Package
Which happens when I use this in InitializeComponent() in the AmmoComponent:
NewObject<UWeaponAmmoManager>(this, AmmoManagerClass->GetClass())
And:
Assertion failed: ClassAddReferencedObjects != NULL
Which happens when I use this in the same function:
ConstructObject<UWeaponAmmoManager>(AmmoManagerClass->GetClass())
But this one happens after I stop the test whereas the first one is a soon as I start it.