Generic item class, UObject or AActor?

Hello,

I’m trying to make an item/inventory system and I need to make some generic/base classes that all items will build out of. Therefore, I was wondering what’s the best way to make these items?

Firstly, I though making an empty class the generic one, but realized I also need some of my items to be visible in-game (so they need to be actors). But as far as I know, it’s not possible to have an actor derive from an empty class, right? Atleast not without any major engine reconfigurations.

Then I was thinking about making all items derive from AActor, but isn’t this very expensive? I mean, not even 5% of my items will ever need to be visible in the world (so they don’t need the actor-implementation).

Lastly, and my most resonable solution in my mind, is to make one empty class, which will be the generic item class. Then whenver I would want my items to be displayed in the world I could make an actor class, link it to its respective item class, and go from there.

These are just a couple of thoughts and solutions I had, but I’ve never really done this before so I’m posting this question here to get some help from this amazing community. My question is then, how would I go about making such a class hierarchy? Any help would be greatly appreciated, thanks in advance! :slight_smile:

~Stefan

Yeah, this seems to be the most resonable. So I guess I’ll make one empty class “ItemBase”, and one actor class “ItemActorBase” or something and build from there. Although, I actually don’t think I’ll be using structs for my case, I have a lot of variables in my item class and it doesn’t really struggle being human-readable. But otherwise a good idea :slight_smile:

Please convert this to an answer. :slight_smile: Although I kind of mentioned your solution already in my question it was worth getting it clarified that this is by best bet. Thanks for the help! :slight_smile:

You could use structs for this kind of thing. Have all the information about an item in a struct, and have an optional TSubclassOf<AMyActor> property inside the struct. The AMyActor class would be the items that you need to display, and you could spawn these items be getting the class from the struct. Hope this makes sense.

It not that expensive as you may think, we really talking here about memory usage difference, as for CPU any class inherent directly from AActor has tick disabled from PrimaryActorTick by default. Extra code not make difference, there only single copy of class code which permanently exist in memory (as long as module with that code i loaded) and it’s executed on specific object, object it self only stores variables, and if code is not executed… it is not executed at all.

At lowest level there 2 main difference between UObject and AActor and it’s not ability to render in to world:

1.Actor is tied to the UWorld instance and becomes part of it’s life cycle, when World dies the Actors also dies. Inherently it means that Actor can be part of the level.

2.Ability to contain components and components are once that define physicality of actor. Actor it self don’t even have positional information as that is defined by RootComponent, just look in to source code of GetActorLocation:

bool AActor::SetActorLocation(const FVector& NewLocation, bool bSweep, FHitResult* OutSweepHitResult, ETeleportType Teleport)
{
	if (RootComponent)
	{
		const FVector Delta = NewLocation - GetActorLocation();
		return RootComponent->MoveComponent(Delta, GetActorQuat(), bSweep, OutSweepHitResult, MOVECOMP_NoFlags, Teleport);
	}
	else if (OutSweepHitResult)
	{
		*OutSweepHitResult = FHitResult();
	}

	return false;
}

I don’t know if you realize this yet… but AGameMode and APlayerController, have A as prefix for a reason. They are AActors not UObjects regardless of there non-physicality, because reason mentioned in point 1. This also includes level blueprint as well as world settings as it’s only way to save them.

Because of reason 1 you also need to remember that pure UObject you create will exist after world gets destroyed and you need to remember to cut any reference to each other to destroy them

So it’s only matter if you need items to be tied to the world. Reminder here is that world “gets destroyed” on every level change and reset, so all actors in the world get’s wiped on those moments, UObject unlike AActors are persistent with entire process of your game and will exist as long other object reference it or application gets closed.