I am working on a project that is an old school doom/quake style FPS and I was wondering what was the best way to go about managing character inventory for available weapons. I have been modifying an existing FPS tutorial where you hide unequipped weapons while keeping them attached to the player and then hiding and unhiding them as you switch them around. The inventory of these weapons are managed in the BP_FirstPersonCharacter blueprint and controlled by gameplay tags that keep said weapons locked and unlocked as needed.
My question was if this was the best way to go about it or is it better to manage character inventory through a separate class that controls both weapons and ammo and then managing interactions between BP_Inventory and BP_FirstPersonCharacter via interfaces?
Is generally considered best to make an actor component to handle it, and add that to your character (and enemies, containers, etc.. that can have items). To start, create a new blueprint class with ActorComponent as the parent class, and add the component to player char the same way you would add a mesh or whatever to an actor class. Since it would be a component of char, you don’t really need an interface for character to use it, as you can call component functions from the owner without needing a cast. Though you may want an interface later for other actors to give you items (like a shop or something) or so weapon actors attached to player can communicate with inventory (like to ask for ammo in a reload function)
I store and manage inventory in the Player State via actor component. Communication via interface. Zero class specific references. Simple Actor, Pawn, AC etc.
My project is multiplayer, so I have to consider connection disconnects and rejoins preserving the players inventory and stats. The GM auto copies and stores PS for default 300s on discos and handles rejoins.
Working with inventory on the PS is a bit more complex, but worth the gains.
This is how you are confusing me, I asked if there were multiple component class types. For purely the inventory system, do you have multiple classes? If no, why use an interface for something that is a singular class?
Say I have a player and a chest. Both of them have Inventory Comp. I do not need an interface to “Get Inventory Comp”, because I can just do Get Component By Class (Inventory Comp).
In both ways of doing that I have the starting reference I would call an interface on vs just getting the component directly. If you have multiple types of inventory classes I could see why you’d use an interface.
You’d still want to use an interface if you want to tell a pawn to do something which may have class specific implementations on on different pawn types. For example, a wolf pawn might have a different idea of what an “Equip Weapon” command means than a humanoid character. On teh wolf, it might be just setting a bool used by anim blueprint and attaching an invisible weapon actor from inv to head socket, while a humanoid would probably ask inventory to spawn a sword/gun actor and attach it to a hand socket and maybe look for ammo in inventory.
My AC_Inventory (PS) works directly with simple Actor references for primary gear and items. The rest of inventory is struct data.
Weapon class has it’s own inventory for attachments and loaded ammo. These are handled via gameplay tags for slots and simple types for other data.
All my interactible world assets work via gameplay tags. Which doesn’t require me to know anything about the class itself or any internal components. From doors, switches, vehicles, elevators, weapons, gear, meds etc.
All communication across the board uses interfaces. Pawn to controller, inventory to item etc.
Yes, but that is a different reference to what I was meaning. Your interface example is from Inventory → Multiple Actor classes. My topics were mostly oriented towards not interfacing to a single class such as one singular inventory component class since we already are contextually aware. I agree that if you are not contextually aware of what any class wants to do with something, you would need an interface.
I’m trying to reduce redundancy as @Auran131 states above. If we only have one inventory component class, calling Add Item to Inventory on the Inventory class is always the same call and requires no interface. Interacting with the component through an interface only makes sense if you are unaware of the final class type or need to account for multiple class types implementing something. If I know where to invoke an interface call, I have a reference to something that has a class. If I know this is the only class that can be called here, then there is no need for an interface to add another layer to something that’s already been solved.
So then you would manage all the ammunition storage in the actor component as well? Some tutorials I am watching are having ammunition managed in the class of the weapon.
Probably a hybrid in a way. A gun (or some magic weapon that feeds on crystals or whatevs) will probably want at least an int for how many rounds are in the mag ( could use a full inv comp here if you want to swap between, say, incendiary ammo and hollow points/fmj). Extra non-loaded ammo would typically go into character’s inv component. Be it as a raw item in main backpack array, or in specific int vars counting how many of each ammo type you have. EG, you might have an array struct called backpack of type struct (using your Item structure), and int vars called 9mmAmmo, ShotgunAmmo, and so on. It would be easier/faster on weapon side just to query an int var, but adding it to inventory would require some fancy switches. There you could use an Item type enum with Weapon, HealingItem, 9mmAmmo, ShotgunAmmo, and such to define item an when calling you switch on enum and either add to backpack array or add incoming count to the matching int.
Personally, I’m about to update my inventory system to put unloaded ammo into the main item array, since it require less fiddling later if I need new ammo flavors lol.