Setup Inventory and Crafting

Niroan

Member
Hello

I bought this asset

I have read the documentation. But im still very lost on how to implement the inventory in my game. I can so far that i have added the GAME object. then i found out by mistake how to enable a Gameobject so it gets the inventory and it then creates the inventory...

My game i extreme simpel. I want the user to be able to equip a weapon in weaponslot armor in armor boots in boots and so one.
But to my understanding this inventory system does not allow me to equip anything unless i have a character inside the game?

My inventory is being used from the main menu, this is also here i want to use the crafting to let the user go into a map. Collect resources update the inventory with those.
Then after mission is completed come back to main menu and craft new gear. Then repeat same procedure to get stronger and stronger.

How can i archive this?

The documentation says nothing about setting it up custom, only the demo scene.

I want to be able to choose "Inventory" from main menu,
Crafting from main menu
Mayby shop from main menu
 
Hi @Niroan

Sorry for the delay, I was trying to come up with a solution for this in a new scene. And I realised it was more complicated than I thought to set it up.
I changed a few scripts so hopefully it will be much easier starting from the next patch.

In the meantime I'll share my work with you right now so that you don't need to wait for the next patch to arrive.

So if I understand correctly you would like something like this where you can access the inventory, shop and crafting from the main menu:
1601282740688.png

So in this test scene I stripped out pretty much everything leaving you simply with UI and nothing else.
The inventory should work just fine, no changes needed.

The part I assume you are struggling with is the shop and the crafting. So here is the shop component with a custom script "ShopMenuOpener" (I'tll be part of the next patch)

1601282831306.png

Here is the crafting component with just the custom CraftingMenuOpener:
1601283004114.png

Here is the code:

Base class

C#:
 /// <summary>
    /// Base class of that open menus.
    /// </summary>
    public abstract class MenuOpenerBase : MonoBehaviour
    {
        [Tooltip("The panel manager.")]
        [SerializeField] protected DisplayPanelManager m_PanelManager;
        [Tooltip("The inventory opening the panel")]
        [SerializeField] protected Inventory m_ClientInventory;

        /// <summary>
        /// Validate the menu manager.
        /// </summary>
        protected virtual void OnValidate()
        {
            if (OnValidateUtility.IsPrefab(this)) { return; }
            if (m_PanelManager == null) {
                m_PanelManager = FindObjectOfType<DisplayPanelManager>();
            }
        }

        /// <summary>
        /// Open the menu using the client inventory field.
        /// </summary>
        public void Open()
        {
            Open(m_ClientInventory);
        }

        /// <summary>
        /// The inventory trying to open the menu.
        /// </summary>
        /// <param name="inventory">The inventory.</param>
        public abstract void Open(Inventory inventory);
    }

ShopMenu Opener:

C#:
 /// <summary>
    /// Shop interactable behavior.
    /// </summary>
    public class ShopMenuOpener : MenuOpenerBase
    {
        [Tooltip("The shop menu.")]
        [SerializeField] protected ShopMenu m_ShopMenu;
        [Tooltip("The shop.")]
        [SerializeField] protected ShopBase m_Shop;

        /// <summary>
        /// Open the menu on interaction.
        /// </summary>
        /// <param name="interactor">The interactor.</param>
        public override void Open(Inventory inventory)
        {
            Debug.Log("Open");
            m_ShopMenu.SetClientInventory(inventory);
            m_ShopMenu.SetShop(m_Shop);
            m_PanelManager.OpenMenu(m_ShopMenu);
        }
    }

Crafting Menu Opener:
C#:
/// <summary>
    /// Crafting interactable behavior.
    /// </summary>
    public class CraftingMenuOpener : MenuOpenerBase, IDatabaseSwitcher
    {
        [Tooltip("The crafting menu.")]
        [SerializeField] protected CraftingMenu m_CraftingMenu;
        [Tooltip("The recipes to display in the menu.")]
        [SerializeField] protected CraftingRecipe[] m_MiscellanousRecipes;
        [Tooltip("The recipes with the categories specified will be visible in the menu.")]
        [SerializeField] protected CraftingCategory[] m_RecipeCategories;

        protected CraftingRecipe[] m_Recipes;

        /// <summary>
        /// Initialize.
        /// </summary>
        protected void Start()
        {

            if ((this as IDatabaseSwitcher).IsComponentValidForDatabase(InventorySystemManager.Instance.Database) == false) {
                Debug.LogError("The Crafting interactable behavior has recipes and crafting categories from the wrong database, please fix it.");
                return;
            }

            var recipeList = new List<CraftingRecipe>(m_MiscellanousRecipes);

            for (int i = 0; i < m_RecipeCategories.Length; i++) {
                var pooledArray = GenericObjectPool.Get<CraftingRecipe[]>();
                var recipesCount = m_RecipeCategories[i].GetAllChildrenElements(ref pooledArray);
                for (int j = 0; j < recipesCount; j++) {
                    recipeList.Add(pooledArray[j]);
                }
                GenericObjectPool.Return(pooledArray);
            }

            m_Recipes = recipeList.ToArray();
        }

        /// <summary>
        /// Open the menu using the inventory as client.
        /// </summary>
        /// <param name="inventory">The client inventory.</param>
        public override void Open(Inventory inventory)
        {
            m_CraftingMenu.SetClientInventory(inventory);
            m_CraftingMenu.SetRecipes(m_Recipes);
            m_PanelManager.OpenMenu(m_CraftingMenu);
        }

        /// <summary>
        /// Check if the object contained by this component are part of the database.
        /// </summary>
        /// <param name="database">The database.</param>
        /// <returns>True if all the objects in the component are part of that database.</returns>
        bool IDatabaseSwitcher.IsComponentValidForDatabase(InventorySystemDatabase database)
        {
            if (database == null) { return false; }

            for (int i = 0; i < m_MiscellanousRecipes.Length; i++) {
                if (database.Contains(m_MiscellanousRecipes[i])) { continue; }

                return false;
            }

            for (int i = 0; i < m_RecipeCategories.Length; i++) {
                if (database.Contains(m_RecipeCategories[i])) { continue; }

                return false;
            }

            return true;
        }

        /// <summary>
        /// Replace any object that is not in the database by an equivalent object in the specified database.
        /// </summary>
        /// <param name="database">The database.</param>
        /// <returns>The objects that have been changed.</returns>
        ModifiedObjectWithDatabaseObjects IDatabaseSwitcher.ReplaceInventoryObjectsBySelectedDatabaseEquivalents(InventorySystemDatabase database)
        {
            if (database == null) { return null; }

            for (int i = 0; i < m_MiscellanousRecipes.Length; i++) {
                if (database.Contains(m_MiscellanousRecipes[i])) { continue; }

                m_MiscellanousRecipes[i] = database.FindSimilar(m_MiscellanousRecipes[i]);
            }

            for (int i = 0; i < m_RecipeCategories.Length; i++) {
                if (database.Contains(m_RecipeCategories[i])) { continue; }

                m_RecipeCategories[i] = database.FindSimilar(m_RecipeCategories[i]);
            }

            return null;
        }
    }
 
Last edited:
You'll want to make sure that you panel for crafting and shop are set a not standalone:
1601283251133.png

All you need to open the crafting and shop menu is to call the function

menuOpener.Open()

You can do so using a Button that calls that function on click for example.

Since you'll be taking some prefabs from the demo scene you'll need to remove some things.

Any stats comparator, Hp Slider, etc.. needs to be removed.

you may get some errors saying you are trying to use items/categories from the wrong database. If so you can run the database swapping code. Instructions can be found here: https://opsive.com/support/documentation/ultimate-inventory-system/getting-started/
under the image of the "new inventory database" section

Thank you for pointing out the flaw in how the UI where being only open from character interaction. Hopelly with the changes I made now it will help other people in the community that wish to do the same as you.

I hope that helps, let me know if you need anything else
 
Looks good.

I kinda dont want the menu on the left.
I just want to make a script that i can call so i can open each panel.

If i use the the MenuOpener you just created.
How would i open Crafting i need to pass the recipe and inventory for those.
So i cant use the MenuOpener?
 
Menu Opener is an abstract(base) class. you do not attach it to anything.

You can attache the CraftingMenuOpener to any component you want, it does not matter. All you need is to drag and drop the correct references.
Especially of the crafting menu and the client inventory (the player inventory)

The recipes are defined in the craftingMenuOpener as shown in the screen shot above (the second one) where you have Miscallenous recipes and category recipes. Assigning the category recipe will add all recipes in the category in the list of recipes to craft
 
Top