Item Set & Rules

The Item Set, Rules and Manager are responsible for choosing what items get to be equipped together. Such as choosing to equip the Sword and Shield together.

 

ItemSets represent a set of CharacterItems that can be equipped at the same time. The ItemSetManager is the component responsible for switching which ItemSets are active. When a new item is added to the character the ItemSetRules automatically creates ItemSets by matching any valid permutations of CharacterItems. More than one ItemSet can be active at the same time by using multiple ItemSetGroups.

Having multiple ItemSet Groups can allow some advanced features such as having grenades that can be thrown from the left or right hand, without having to completely unequip the main Item Set.

Item Set Manager

The ItemSetManager manages what ItemSet gets activated and when. The Equip Unequip Item Ability works with the ItemSetManager to decide what item gets equipped. At edit time the ItemSetManager shows the ItemSetGroups with their ItemSetRules.

At runtime the ItemSetManager shows the ItemSets and their state:

The colored dot next to the ItemSet name shows the current state of the ItemSet:

  • Green: Active.
  • Yellow: Enabled.
  • Red: Invalid or Disabled.
In the screenshot above the DualPistols is invalid because the character only has picked up a single pistol and the relevant ItemSetRule assigned it as invalid.
Clicking on an ItemSet shows more information about it:
Looking at the ItemSetManager inspector at runtime is the first thing to do if your Items do not equip as expected.
Notice the little icon next to the ItemSetRule and ItemSet Slots. This will open a property window with the selected object such that you do not lose focus of the ItemSetManager window while looking through them.

Inspected Fields

On Add Item Update Item Sets Options

Choose if and when the item sets get updated when a character Item is spawned or removed on the character.

  • Immediately:  The ItemSet should be updated immediately.
  • ScheduleToLateUpdate: The ItemSets should be updated within LateUpdate.
  • Manual: The ItemSets should be updated manually with the UpdateItemSets method.
Item Collection

The ItemCollection containing all the items the character can equip. It is mainly used to initialize the ItemTypes on awake and checking the ItemType categories.

Item Set Group

The Item Set groups containing the rules to create ItemSets at runtime.

API

Update the ItemSets

Update the ItemSets manually:

m_ItemSetManager.UpdateItemSets(characterItems);

Or:

m_ItemSetManager.UpdateItemSets(characterItemsBySlot);
Get a specific ItemSet

Get first matching ItemIndentifier ItemSet:

ItemSet itemSet = m_ItemSetManager.GetItemSet(itemIdentifier, groupIndex, checkIfValid);

Get ItemSet matching list of ItemIndentifier (ordered by slot):

ItemSet itemSet = m_ItemSetManager.GetItemSet(itemIdentifierList, groupIndex);

Get ItemSet by state name:

ItemSet itemSet = m_ItemSetManager.GetItemSet(itemSetName, groupIndex);

Get ItemSet by index:

ItemSet itemSet = m_ItemSetManager.GetItemSet(itemSetIndex, groupIndex);
Get active and next ItemSet

Get active ItemSet:

ItemSet itemSet = m_ItemSetManager.GetActiveItemSet(groupIndex);

Get active ItemSet index:

int itemSetIndex = m_ItemSetManager.GetActiveItemSetIndex(groupIndex);

Get next ItemSet:

ItemSet itemSet = m_ItemSetManager.GetNextItemSet(groupIndex);

Get next ItemSet index:

int itemSetIndex = m_ItemSetManager.GetNextItemSetIndex(groupIndex);
Equipping and Unequiping

Try equipping an ItemSet using its main state name:

bool success = m_ItemSetManager.TryEquipItemSet(itemSetName, groupIndex, forceEquipUnequip, immediateEquipUnequip);

Try equipping an ItemSet:

bool success = m_ItemSetManager.TryEquipItemSet(itemSet, forceEquipUnequip, immediateEquipUnequip);

Equip or unequip an item using the first matching ItemSet:

m_ItemSetManager.EquipUnequipItem(itemIdentifier, equip, groupIndex, forceEquipUnequip, immediateEquipUnequip);

Equip an Item using the first matching ItemSet:

m_ItemSetManager.EquipItem(itemIdentifier, groupIndex, forceEquipUnequip, immediateEquipUnequip);

Unequip an Item using the first matching ItemSet:

m_ItemSetManager.UnequipItem(itemIdentifier, groupIndex, forceEquipUnequip, immediateEquipUnequip);

Item Set Groups

The ItemSetManager contains a list of ItemSetGroups, each with their own rules and sets. A Category is used to identify the ItemSetGroups. Item Abilities such as EquipUnequip  will use that Category to reference the relevant group.

The rules within the ItemSetGroup do most of the work, but the ItemSetGroup does have some useful functions to get information about the ItemSets and their rules. The ItemSetRule list within the group can be changed at runtime. Strategically adding and removing ItemSetRules is a great way to ensure a clean organization. It is also the best way to add custom ItemSetRules from MonoBehaviours instead of scriptable objects since the IItemSetRule int

Inspected Fields

Serialized Item Category

The item CategoryBase to identify the ItemSetGroup.

Starting Item Set Rules

The starting array of ItemSetRules. The actual list can be changed at runtime.

API

Get ItemSetRule and ItemSets

Get the ItemSetRule from an ItemSet:

IItemSetRule itemSetRule = m_ItemSetGroup.GetItemSetRule(itemSet);

Get all ItemSets created by a rule:

ListSlice<ItemSet> itemSets = m_ItemSetGroup.GetRuleItemSetList(itemSetRule);
Add and remove rules at runtime

Insert an ItemSetRule at a specific index:

m_ItemSetGroup.InsertItemSetRule(index, itemSetRule);

Add an ItemSetRule:

m_ItemSetGroup.AddItemSetRule(itemSetRule);

Remove an ItemSetRule:

m_ItemSetGroup.RemoveItemSetRule(itemSetRule);

Set the list of ItemSetRules:

m_ItemSetGroup.SetItemSetRules(itemSetRuleList);

Item Set Rule

ItemSetRules are used to create the ItemSets given a list of Items. Usually the ItemSetRules are notified to create and delete ItemSets as items are added to and/or removed from the character.

ItemSetRules can only create ItemSets if CharacterItems have a SlotID matching the slot in which the ItemSet has it defined.
For example an ItemSetRule cannot create an ItemSet with a sword in Slot 1 if the CharacterItem has it defined as Slot 0. If an Item can be equipped in both slots then the CharacterItem must be created for each slot.

There are many types of Item Set Rules. They can be ScriptableObjects or they can be assigned to an ItemSetGroup at runtime by inheriting the IItemSetRule interface. The built-in ItemSetRules can be created by going to the project window and right-clicking Create -> Opsive -> Ultimate Character Controller -> Inventory.

The built-in ItemSetRules are:

  • Individual
  • ItemType
  • ItemCategory
  • Multi
The Inventory System Integration has an ItemSetRule that equips items relevant to the slot in which they are equipped in the UI or ItemSlotCollection? This is a great and easy way to get a similar equipment system you’ll find in most classical RPG games.
The ItemSet state name is not only used to set a state on the character but also used as a way to identify the ItemSet once it is created.
All Built-in ItemSetRules use the ‘{0}’ format to concatenate the names of the items in each slot together. For example, ‘My_{0}_State’ for an ItemSetRule with the sword and shield will set an ItemSet name of ‘My_SwordShield_State’.
More complex ItemSetRules can be created with custom code by inheriting the IItemSetRule Interface or ItemSetRuleBase class.
Individual

The simplest ItemSetRule to get started quickly. It will create ItemSets for all items and assign it the relevant slot by checking the CharacterItem. It is called “Individual” since it creates ItemSets with a single item inside.

The list of exceptions can be used to exclude certain items from getting their ItemSet automatically created. This way other ItemSetRules can be used to define how they can be combined with other items.

ItemType

The classic ItemSetRule which defines the exact item combination wanted.

This is the approach used in version 2 of the character controller.
Category

The category ItemSetRule allows creating item sets by combining items by their categories.

In this example where Slot 0 corresponds to the Magic category and Slot 1 corresponds to the nothing category it will create multiple ItemSets all with magic items in slot 0. A category ItemSetRule can be used with a left hand in slot 1 and right hand in slot 0 allowing any item combination for items inheriting those categories.

Multi

In some cases you may want to share the same rules across multiple characters. This rule combines other rules inside a single ScriptableObject using a list of ItemSetRules.

The ItemSetGroup will ensure each ItemSet is mapped to the inner ItemSetRule.

Custom

You can make your own ItemSetRule. This is a great way to dynamically create ItemSets depending on the game state. There are three main ways to create a new rule:

  1. Inherit the ItemSetRule ScriptableObject which already comes predefined and can be used to easily create ItemSetRules to assign to the ItemSetGroup at edit time.
  2. Inherit ItemSetRuleBase ScriptableObject to have a ScriptableOobject that can be assigned to the ItemSetGroup at edit time.
  3. Inherit IItemSetRule interface to a class or MonoBehaviour and assign it to an ItemSetGroup at runtime.

Inheriting ItemSetRule is a bit easier as the functions to override simply returns booleans. It is also what is used for Individual, Category and ItemType ItemSetRules.

/// <summary>
/// Does the character item match this rule.
/// </summary>
/// <param name="itemSetRuleStreamData">The item set rule stream data.</param>
/// <param name="currentPermutation">The current item permutation so far.</param>
/// <param name="characterItem">The character item to check.</param>
/// <returns>True if the character item matches this rule.</returns>
public abstract bool DoesCharacterItemMatchRule(ItemSetRuleStreamData itemSetRuleStreamData, ListSlice<IItemIdentifier> currentPermutation, CharacterItem characterItem);

/// <summary>
/// Can the slot be empty for this rule.
/// </summary>
/// <param name="slotID">The slot ID to check.</param>
/// <returns>True if it can be empty.</returns>
protected abstract bool CanSlotBeNull(int slotID);

Inheriting IItemSetRule or ItemSetRuleBase gives the most flexibility, but requires more thought. Two functions must be overridden:

/// <summary>
/// From the Item Set Rule Stream Data return the next item set state info.
/// </summary>
/// <param name="itemSetRuleStreamData">The item set rule stream data.</param>
/// <returns>Return the item set state info.</returns>
public abstract ListSlice<ItemSetStateInfo> GetNextItemSetsStateInfo(ItemSetRuleStreamData itemSetRuleStreamData);

/// <summary>
/// Returns if an item set is valid for the allowed slots mask.
/// </summary>
/// <param name="itemSet">The item set to check.</param>
/// <param name="allowedSlotsMask">The allowed slots mask.</param>
/// <returns>Returns true if the item set is valid.</returns>
public abstract bool IsItemSetValid(ItemSet itemSet, int allowedSlotsMask);

The GetNextItemSetsStateInfo function takes in the current state of the ItemSets for that were created by this rule. It returns a list of ItemSets to add, keep or remove.

From there the ItemSetGroup and the Manager will ensure the ItemSets are added/kept/removed smoothly keeping in mind the ItemSets must exist while items are playing the equip/unequip animations so they cannot simply be removed on the exact frame they are no longer required. In some cases you may want to disable an ItemSet without actually removing it. This is when you would use the IsItemSetValid function.

It is recommended that you are familiar with the code from the existing ItemSetRules before making your own.

Item Set

ItemSets represent what items can be equipped at the same time in each slot. They are created by ItemSetRules.

In some cases you may want to use states to enable/disable them at runtime. This an easy way to prevent certain items to be equipped depending on the character state.

Inspected Fields

State

The state name that becomes active when the ItemSet is active. It can also be used to identify the ItemSet within an ItemSetGroup

Enabled

An ItemSet can only be active if it is enabled.

Can Switch To

Can the ItemSet be switched to by the EquipNext/EquipPrevious abilities?

Disabled Index

The ItemSet index that should be activated when the current ItemSet is active and disabled.