Creating an equipment slot that can hold multiple types of items

,

Here’s the rundown, I’m using the Inventory system developed in the RPG course, but for the game I’m hoping to build you are able to hold 2 one handed weapons, so the shield slot would also function to hold weapon items. Another case is I’m making swappable jobs/classes I’ve implemented the system from the thread Equipment slots and multiple rings/trinkets/etc. I’ve already butchered the code to create theses Job slots but my plan down the line is to sort the jobs into tiers (Basic, Advanced, Specialized, and Ultimate) but I only want you to be able to put certain jobs in certain slots. For example Slot 1 [All Jobs], Slot 2 [Basic, Advanced, Specialized], Slot 3 [Basic, Advanced]. I’d consider myself a beginner at coding (mostly because I have a hard time remembering what things do, and it takes me forever to figure out some simple ways of implementing certain things, and I know my methods I’m able to come up with on my own are horribly unoptimized)

What I have working Rn, In images




Its really bland and ugly Rn, cauz im just using this to block out my ideas

This may not be the best way, but what I would do is to change the EquipmentLocation enum into a Flags enum. This is quite simple, just add a [Flags] attribute to it, but you will also need to supply values to the entries. The values should be in powers of 2 so the easiest (but strangest to read if you’re new) would be to just bit shift a 1

[Flags]
public enum EquipLocation : byte
{
    Helmet = 1 << 0,
    Necklace = 1 << 1,
    Body = 1 << 2,
    Trousers = 1 << 3,
    Boots = 1 << 4,
    Weapon = 1 << 5,
    Shield = 1 << 6,
    Gloves = 1 << 7,
}

To explain, the bit shift here (<<) is a left shift and moves all the bits to the left by the specified amount. I have specified here that the enum holds byte values (it’s sufficient for the enum above, but you can leave it out because it will not be sufficient anymore when you add more values to the enum).
In a byte, 1 in binary is 0000 0001. The first value shifts it left by 0 (this one don’t need a shift but I added it anyway) so nothing happens. The next value shifts left by 1 so it becomes 0000 0010 (2), next is shifted by 2 so 0000 0100 (4), then shift by 3 = 0000 1000 (8), etc.

Now, with these as flags, you can combine the enums by or'ing (| is a bitwise ‘or’) them together
EquipLocation.Weapon | EquipLocation.Shield
This value will now combine the two EquipLocations into the values for Weapon and Shield giving you

   0010 0000 (weapon)
or 0100 0000 (shield)
=====================
   0110 0000 (weapon and shield)

or’ returns 1 where any of the values is 1 and 0 otherwise

When we check to see if the item is valid (in the EquipmentSlotUI), you can now use the HasFlag method to check if the slot can take the item, for example
You have a slot the can hold a weapon and a shield (as above - but Unity will give you a nice dropdown where you can check all the valid items). When you try to drop an item in this slot (EquipmentSlotUI), the slot checks

if (equipableItem.GetAllowedEquipLocation() != equipLocation) return 0;

but this will not work. You need to change it to

if (!equipLocation.HasFlag(equipableItem.GetAllowedEquipLocation())) return 0;

Now you can set the ‘Shield’ slot to also hold ‘Weapons’ but be aware that you can also set an item to go into multiple slots, so you can also have a ‘Sword’ that go into the ‘Helmet’ slot (if you set it to do that)

To be honest, I’ve never used the HasFlag method. I always do the check manually. This is done by And'ing the values (& is a bitwise ‘and’) and seeing if you get something

bool HasFlag(EquipLocation flags, EquipLocation value)
{
    return ((flags & value) != 0);
}
// Usage
if (!HasFlag(equipLocation, equipableItem.GetAllowedEquipLocation())) return 0;

This takes the values above and sees if it matches
Assume we have the Weapon-Shield slot from above and want to test a Weapon we’ll get

    0110 0000 (weapon and shield)
and 0010 0000 (weapon)
=======================
    0010 0000 (weapon)

and’ returns 1 where both of the values are 1 and 0 otherwise

if we tried a Helmet in that slot

    0110 0000 (weapon and shield)
and 0000 0001 (helmet)
=======================
    0000 0000 (nothing)

Now you’ll be able to define slots that can hold items of different types - like Weapon and Shield as you requested. It will allow any weapon in that slot, though


Edit
If you want to set the enum explicitly instead of shifting you can, but it gets ugly when there are many values

[Flags]
public enum EquipLocation : byte
{
    Helmet = 1,   // 0000 0001
    Necklace = 2, // 0000 0010
    Body = 4,     // 0000 0100
    Trousers = 8, // 0000 1000
    Boots = 16,   // 0001 0000
    Weapon = 32,  // 0010 0000
    Shield = 64,  // 0100 0000
    Gloves = 128, // 1000 0000
}
1 Like

I was actually experimenting with flags myself so its nice to know that I was at least on a path that would work.
One thing I don’t understand is where to put this or statement

   0010 0000 (weapon)
or 0100 0000 (shield)
=====================
   0110 0000 (weapon and shield)
1 Like

You don’t have to put it anywhere. I was explaining how the or works. The Unity inspector also has a built-in property drawer for flags, so once you’ve changed it to flags, the inspector dropdown will change, allowing you to select multiple values. It’s not necessary to do that in code

1 Like

Ok this method looks like it works! Hopefully I don’t break it accidentally while I continue to add features.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms