inventory.MainItemCollection.RemoveItem(item);
m_ItemPickup = ObjectPool.Instantiate(m_PickUpItemPrefab,
m_PlayerCharacter.transform.position +
new Vector3(Random.value*2-1,Random.value*2,Random.value*2-1),
Quaternion.identity).GetComponent<ItemPickup>();
if (m_ItemPickup == null) {
Debug.LogWarning("Item Pickup is null");
return;
}
var itemObject = m_ItemPickup.ItemObject;
itemObject.SetItem(item);
//Get an ItemCategory by name
var category = InventorySystemManager.GetItemCategory("MyItemCategory");
//Get an ItemCategory by id
category = InventorySystemManager.GetItemCategory(97201);
//Get all the Item Categories
var allCategories = InventorySystemManager.ItemCategoryRegister.GetAll();
//Get an ItemDefinitions by name
var itemDef = InventorySystemManager.GetItemDefinition("MyItemDefinition");
//Get an ItemDefinitions by id
itemDef = InventorySystemManager.GetItemDefinition(123809);
//Get all the ItemDefinitions
var allItemDef = InventorySystemManager.ItemDefinitionRegister.GetAll();
//Get an ItemDefinitions by name
var itemDef = InventorySystemManager.GetItemDefinition("MyItemDefinition");
//Create an item equivalent to the default item.
var item = InventorySystemManager.CreateItem(itemDef);
//Create an item copy.
var itemCopy = InventorySystemManager.CreateItem(item);
//Create an item equivalent to the default item.
var itemWithOverrideAttribute =
InventorySystemManager.CreateItem(itemDef, new []{new Attribute<int>("MyAttributeInt", 100) });
//Create an item copy.
var itemCopyWithOverrideAttribute =
InventorySystemManager.CreateItem(item, new []{new Attribute<bool>("MyAttributeBool", false) });
var item = InventorySystemManager.GetItem(12345);
//Get the itemCategory parents
myItemCategory.GetDirectParents();
//Get all the itemCategory parents, it uses a non-alloc pattern.
ItemCategory[] allParents = new ItemCategory[0];
var count = myItemCategory.GetAllParents(ref allParents);
//Get the itemCategories children itemDefinitions
ItemDefinition[] allChildrenItemDefinitions = new ItemDefinition[0];
count = myItemCategory.GetAllChildrenElements(ref allChildrenItemDefinitions);
//Check if a category contains an itemCategory
myItemCategory.InherentlyContains(myOtherItemCategory);
//Check if a category contains an itemDefinition
myItemCategory.InherentlyContains(myItemDefinition);
//Check if a category contains an item
myItemCategory.InherentlyContains(myItem);
//Get the itemDefinition category
var category = myItemDefinition.Category;
//Check if a category contains an itemDefinition
myItemDefinition.InherentlyContains(myOtherItemDefinition);
//Check if a category contains an item
myItemDefinition.InherentlyContains(myItem);
//Get all the itemDefinition family, includes parents and children, it uses a non-alloc pattern.
ItemDefinition[] itemDefinitionFamily = new ItemDefinition[0];
count = myItemDefinition.GetAllFamily(ref itemDefinitionFamily);
//Get Item ItemCategory
myItem.Category;
//Get Item ItemDefinition
myItem.ItemDefinition;
//Get the last itemObject that was bound to this item, (there can be multiple itemObject per item)
myItem.GetLastItemObject();
var myItemCategory = InventorySystemManager.GetItemCategory("MyItemCategory");
//Get all the itemCategory parents, it uses a non-alloc pattern.
//Do it right this time!
//First get the pooled array from the Generic Object Pool.
var pooledAllParents = GenericObjectPool.Get<ItemCategory[]>();
//Feed the array with the parents and get the count of parents.
var count = myItemCategory.GetAllParents(ref pooledAllParents);
//IMPORTANT: The array might be bigger than the amount of parents! DO NOT use pooledAllParents.Length !
for (int i = 0; i < count; i++) {
Debug.Log(pooledAllParents[i]);
}
//IMPORTANT: Do not forget to return the pooled array once you are done with it.
//This way the array can be reused somewhere else.
GenericObjectPool.Return(pooledAllParents);
[Serializable]
public class Stats
{
[SerializeField] protected int m_MaxHp;
[SerializeField] protected int m_Attack;
[SerializeField] protected int m_Defence;
public int MaxHp => m_MaxHp;
public int Attack => m_Attack;
public int Defence => m_Defence;
}
//Get an attribute from an item. This includes itemCategory and ItemDefinition attributes.
var attributeInt = myItem.GetAttribute<Attribute<int>>("MyAttributeInt");
//Returns the attribute value.
attributeInt.GetValue();
//Get the inherited value.
attributeInt.GetInheritedValue();
//Set the override value (automatically sets the variant type to Override).
attributeInt.SetOverrideValue(100);
//Set a modify expression (automatically sets the variant type to Modify).
attributeInt.SetModifyExpression("42 + 42",true);
//Change the variant type to inherit.
attributeInt.SetVariantType(VariantType.Inherit);
//If you are only interested in the attribute Value you can use TryGetAttributeValue.
if (myItem.TryGetAttributeValue("MyAttributeInt", out int attributeValue)) {
Debug.Log(attributeValue);
}
//List of item attributes (does not include itemCategory or itemDefinition attributes.)
var itemAttributes = myItem.GetAttributeList();
for (int i = 0; i < itemAttributes.Count; i++) {
//Attribute base class does not know the attribute type, this can cause boxing.
itemAttributes[i].GetValueAsObject();
}
//Iterate through all the item attributes including the itemCategory and ItemDefinition attributes.
var attributeCount = myItem.GetAttributeCount(true,true);
for (int i = 0; i < attributeCount; i++) {
myItem.GetAttributeAt(i,true,true);
}
//This File is Auto-Generated by the editor window
//Date of creation: 04/03/2020 16:59:02
public static class DemoInventoryDatabaseNames
{
//ItemCategories
public static class Viewable
{
public const string name = "Viewable"; //ItemCategory
//Attributes
public const string categoryIcon = "CategoryIcon"; //Sprite
public const string description = "Description"; //String
public const string icon = "Icon"; //Sprite
//Item Definitions
}
public static class Pickupable
{
public const string name = "Pickupable"; //ItemCategory
//Attributes
public const string pickupPrefab = "PickupPrefab"; //GameObject
//Item Definitions
}
//….etc….
//Get the viewable Item category from the database names.
var viewableCategory = InventorySystemManager.GetItemCategory(DemoInventoryDatabaseNames.Viewable.name);
var potionItemDefinition = InventorySystemManager.GetItemDefinition(DemoInventoryDatabaseNames.potion);
var potionItem = InventorySystemManager.CreateItem(potionItemDefinition);
//Check if potion is part of the viewable category.
if (viewableCategory.InherentlyContains(potionItem)) {
//If potion is part of viewable category it must have all the attributes of viewable
//Get the description.
potionItem.GetAttribute<Attribute<string>>(DemoInventoryDatabaseNames.Viewable.description).GetValue();
//Get the item Icon.
potionItem.GetAttribute<Attribute<string>>(DemoInventoryDatabaseNames.Viewable.icon).GetValue();
//Of course you can also get the category attribute from the item directly.
potionItem.GetAttribute<Attribute<string>>(DemoInventoryDatabaseNames.Viewable.categoryIcon).GetValue();
}
//Get a collection by ID.
var myItemCollection = myInventory.GetItemCollection(0);
//Or get it by name.
myInventory.GetItemCollection("My Item Collection");
//Check if itemCollection has the item.
myItemCollection.HasItem(myItem);
//Add an item amount to a collection.
myItemCollection.AddItem(myItem, 5);
//Remove an item amount to a collection
myItemCollection.RemoveItem(myItem, 2);
//Get the amount of an item
myItemCollection.GetItemAmount(myItem);
//Get the amount of an item with itemDefinition
myItemCollection.GetItemDefinitionAmount(myItemDefinition);
//Get the amount of an item with ItemCategory
myItemCollection.GetItemCategoryAmount(myItemCategory);
//Get all the itemAmounts in the collection
var allItemsAmounts = myItemCollection.GetAllItemsAmounts();
for (int i = 0; i < allItemsAmounts.Count; i++) {
allItemsAmounts[i].Item;
allItemsAmounts[i].Amount;
}
var pooledItemAmount = GenericObjectPool.Get<ItemAmount[]>();
//Get all item amounts with definition (the 'true' parameter is used to check inherit relation)
var count = myItemCollection.GetItemAmountsWithDefinition(myItemDefinition, ref pooledItemAmount,true);
for (int i = 0; i < count; i++) {
pooledItemAmount[i];
}
//Get all item amounts with category (the 'true' parameter is used to check inherit relation)
count = myItemCollection.GetItemAmountsWithCategory(myItemCategory, ref pooledItemAmount, true);
for (int i = 0; i < count; i++) {
pooledItemAmount[i];
}
//Get item amounts wil a custom filter and sort function.
//Get all items with an amount bigger than 10 and sorts by name.
//Note: Create the comparer before as to not create garbage like in this example.
//If you are unfamiliar with this syntax learn about Lambda functions.
myItemCollection.GetItemAmounts(
ref pooledItemAmount,
(itemAmount) =>
{
return itemAmount.Amount == 10;
},
Comparer<ItemAmount>.Create(
(i1, i2) =>
{
return i1.Item.name.CompareTo(i2.Item.name);
}));
for (int i = 0; i < count; i++) {
pooledItemAmount[i];
}
//If you need items from all the itemCollection in the inventory
//You can use the same function on the inventory instead of the itemCollection.
myInventory.GetItemAmounts(
ref pooledItemAmount,
(itemAmount) =>
{
return itemAmount.Amount == 10;
},
Comparer<ItemAmount>.Create(
(i1, i2) =>
{
return i1.Item.name.CompareTo(i2.Item.name);
}));
for (int i = 0; i < count; i++) {
pooledItemAmount[i];
}
GenericObjectPool.Return(pooledItemAmount);
I'm wondering if they will be unified with the new Inventory system so that we don't have to use two different systems.
For attachments and or sockets you should be able to use the demo item upgrade as an example to create your own system. There are better ways to add this functionality than to modify the existing API. If a lot of people request a more advanced attachements/socket system then what is available in the demo I'll look into adding a feature for it. Using attributes as slot and making a component that lets you set the attahcments in the inspector should do the trick.Attachment/Socket system.
(a) In relation to the item binding (binding item attributes to fields or(?) properties in monobehaviour components on the same(?) GameObject, what if my component script has within it a class and within that class is a public float field? Is there a way to bind through the component => class => public float field?
public int myProperty {get;set;}
public int myProperty2 {get => m_MyField; set => m_MyField = value;}
public int myProperty3 {get => m_MyClass.Field; set => m_MyClass.Field = value;}
Yes that should work(b) In relation to calculated Item Attribute fields (rather than inherited or overridden) - although I see an excellent example of returning a combined $"{attribute} {attributeB}" string, can the the calculation formula cope with adding strings together?
You can use spaces if you want. For the ItemCategory and ItemDefinitions names I suggest putting the name as you want it to appear in game. For attributes I usually suggest Pascal case but you can do whatever you want, as long as you use only letters, numbers, spaces and underscores.(c) Another question. In terms of naming and naming conventions for Item Categories, Item Definitions and Item Attributes (etc) in setting them up in the Editor, can I name an Item Attribute say "Base Name" or is it that I should not use spaces ie. "BaseName"?
A suggested feature for after first release - being able to recolour sprite or mesh/gameobject at runtime. That would allow a huge reduction in the need for assets, potentially?
So if you had say a nice silver/grey sword, shifting the hue to yellow could make it 'gold' or similar?
Here's another one for you - a simple API method to sort items in any Category-based (as they all are) Inventory by their sub-Categories, whatever they are? (unless you've made that method already!).
We plan to pre-release the Ultimate Inventory System (UIS) on the Opsive store in May. The Unity store version will be released as soon as the pre-release version is stable.
If you have any questions feel free to ask, I’ll try to answer the best I can.