I want to implement a generic method to create instance of ItemComponents from Items. Here is my design.
Item Implementation
class UItemBase : public UObject
{
UPROPERTY(...) TSubclassOf<UItemComponentBase> ComponentClass;
}
class UItemClassA: public UItemBase;
class UUtemClassB: public UItemBase;
Component Implementation
class UItemComponentBase: public UActorComponent
{
UPROPERTY(...) UItem* ItemInstance;
}
class UItemComponentA: public UItemComponentBase;
class UItemComponentB: public UItemComponentBase;
Now, I want to instantiate specific component for specific item.
bool ASomeActor::AddItemComponent(TSubclassOf<UItemBase> ItemClass)
{
UItemBase* ItemTemplate = ItemClass.GetDefaultObject();
UItemComponentBase* ItemComponent = NewObject<UItemComponentBase>(this, ItemTemplate ->Name, EObjectFlags::RF_NoFlags, ItemTemplate ->ComponentClass.GetDefaultObject());
ItemComponent ->ItemInstance = NewObject<UItemBase>(ItemComponent , ItemTemplate ->Name, EObjectFlags::RF_NoFlags, ItemTemplate);
ItemComponent ->RegisterComponent();
return true;
}
Of course, the code is not instantiating the child classes, they are just instances of UItemComponentBase. How can I achieve this? Is it possible to implement a generic method for that or do I need to check the type and write different code for each class type?
Edit:
I can only achieve this by type checking and writing different methods for each UItemComponent subclass.
bool ASomeActor::AddItemComponent(TSubclassOf<UItemBase> ItemClass)
{
UItemBase* ItemTemplate = ItemClass.GetDefaultObject();
if (ItemTemplate ->IsA<UItemClassA>())
{
UItemComponentA* ItemComponent = NewObject<UItemComponentA>(this, ItemTemplate ->Name, EObjectFlags::RF_NoFlags, ItemTemplate ->ComponentClass.GetDefaultObject());
ItemComponent ->ItemInstance = NewObject<UItemClassA>(ItemComponent , ItemTemplate ->Name, EObjectFlags::RF_NoFlags, ItemTemplate);
ItemComponent ->RegisterComponent();
}
else if (ItemTemplate ->IsA<UItemClassB>())
{
UItemComponentB* ItemComponent = NewObject<UItemComponentB>(this, ItemComponentTemplate ->Name, EObjectFlags::RF_NoFlags, ItemComponentTemplate ->ComponentClass.GetDefaultObject());
ItemComponent ->ItemInstance = NewObject<UItemClassB>(ItemComponent , ItemTemplate ->Name, EObjectFlags::RF_NoFlags, ItemTemplate);
ItemComponent ->RegisterComponent();
}
//... so on
}