Forum rules - please read before posting.

Possible to use inventory item categories as tags?

edited February 2021 in Technical Q&A

Kia Ora,

Would it be possible to utilise the existing inventory item categories as a sort of tag that could determine what options are displayed in the inventory menu UI when a particular item is highlighted? (I'm using keyboard and controller.)

The idea is that I want to give the player the ability to discard stuff like you can in early resident evil games (health and ammo mostly) and don't want careless players to be able to accidentally discard key items.
At the moment when you select an item in the inventory, it moves your selection to little menu with "use/ combine / discard" from which you select what you'd like to do with it. Use just attempts to use the item at the current hotspot, combine lets you essentially use it on another item, like practically every adventure game, and discard lets you straight up destroy the object entirely!)

To prevent careless soft-locking through destruction of private property, I was thinking of simply giving each item a series of tags or the like and having the discard option be greyed out if the item is tagged as a key item - then I saw that there are inventory item categories built into AC.

My question then is;
Can you display all of the categories together in the same inventory, but modify the menu UI based on the currently highlighted item's category, or have I totally misunderstood what the categories are for?

If using them in this way isn't possible, is it possible to give each inventory object a set of tags? I'm not sure how they are actually stored within AC.
If they can contain data (i assume they do, so you can give them names, descriptions, relevant art and the like) is it accessible through script, so that I could instead write a little script that disables and enables the UI elements based on those tags instead - same basic principle I guess, but not sure what exactly is possible within AC.

Cheers.

Comments

  • You could feasibly use Categories, since an item's recorded category is essentially just an Integer variable mapped to it's intended category ID value.

    However, Categories as a feature are more intended for separating inventory items into different menu elements. For giving individual items additional data, have a look at Properties instead.

    Properties can be defined in the tab next to Categories, and essentially behave like Variables that each item has it's own value for. So it's here that you could define a Text property for a description, or an Integer property for a tag, etc.

    Properties are chiefly intended to be accessed through script, though it is possible to use the Inventory: Property to Variable Action to transfer an item's property to a Variable that can then be read using Variable: Check.

    To get an API reference to a property, right-click the property label for a given item. For example, the 2nd property of item 3 will be:

    AC.KickStarter.runtimeInventory.GetItem (3).GetProperty (2);
    

    You can also refer to properties of e.g. the currently-hovered-over item:

    AC.KickStarter.runtimeInventory.HoverItem.GetProperty (2);
    

    If you're specifically dealing with Interaction menus, it's also possible to extract the inventory item for which such a menu was enabled for - at the time the menu was enabled. This can be done by hooking into the OnMenuTurnOn custom event:

    using UnityEngine;
    using AC;
    
    public class ExtractInteractionInventoryItem : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnMenuTurnOn += OnMenuTurnOn; }
        private void OnDisable () { EventManager.OnMenuTurnOn -= OnMenuTurnOn; }
    
        private void OnMenuTurnOn (AC.Menu menu, bool isInstant)
        {
            if (menu.title == "Interaction")
            {
                InvInstance targetInvInstance = menu.TargetInvInstance;
                if (InvInstance.IsValid (targetInvInstance))
                {
                    // Now get property ID 3's integer value:
                    int tag = targetInvInstance.InvItem.GetProperty (3).IntegerValue;
                }
            }
        }
    
    }
    

    InvInstance vs InvItem gets a little tricky, but have a look through the Manual's "Inventory scripting" chapter for an overview.

  • Awesome!
    Thanks so much for this Chris, I’m astounded at how much you’ve packed into this asset - just when I think I might have to build something from scratch, there it is!
    I’ll have a fiddle around with what you’ve suggested there and have a read over the chapter - it’s already looking like you’ve given me exactly what I was after right there.
    As always, cheers mate!
  • edited February 2021
    Hi Chris, I have a follow-up query, that’s tangentially related.
    What would be the best way to create an inventory system using the built in menu system that functions like this:

    https://imgur.com/EfzTJwl

    1) You press the inventory button to pause the game and bring up a "background" menu, that has other menus nested in the screen in the middle - pressing the controller bumpers switches these screens out. (I've got this working with AC)

    2) Within the inventory screen, when you move the selection box around slots, the currently highlighted item displays its name, description and an image to the left. (This is where I'd use the "properties" - though can these be associated with additional images similar to how you would with scriptable objects in unity?)

    3) Selecting an item with the "select button" moves the selection box/cursor to a small menu off to the side, from which you select an inventory interaction

    - If you select use then the item is used (equipped if a weapon etc)

    - On selecting combine, the cursor once more returns to the item boxes, and allows you to select another item to run those items' combine actions.

    - Selecting discard, will pop up a confirmation prompt, and confirming will remove items from your inventory altogether (if allowed, based on "properties.")

    4) At any point, pressing the "back button" will move you back to the previous step.

    I've managed to create a semi-functional version of this using unity's ui and completely independent of AC's inventory system, however I am trying to figure out how I could replicate it within AC's menu system.

    Is it actually possible to nest inventory actions (use, combine etc) within a menu if the rest of your game is controlled with context-sensitive controls?

    I saw that you can choose CHTA controls, at which point you will be able to use an interaction menu, but that's fiddly due to cursors and the fact that I only want a single interaction button for in-game hotspots.

    I'd rather be able to make use of AC's inventory system and tie it to unity's UI where possible since the saving and loading you've implemented works really well!

    ------

    A side issue I noticed is that if you have enabled the ability to move items within the inventory, and also have stackable items, if you grab one item from a stack, then once you've put it somewhere else, you can't re-stack it back where it came from! (though you can build a combine action with itself to add it to the stack and remove the one you have selected - it's a weird workaround)
  • Thanks for the elaboration.

    when you move the selection box around slots, the currently highlighted item displays its name, description and an image to the left

    For this, you'd want to hook into the OnMouseOverMenu custom event and use it to extract data from the currently-selected inventory item:

    private void OnEnable () { EventManager.OnMouseOverMenu += OnMouseOverMenu; }
    private void OnDisable () { EventManager.OnMouseOverMenu -= OnMouseOverMenu; }
    
    private void OnMouseOverMenu (AC.Menu _menu, MenuElement _element, int _slot)
    {
        if (_element.title == "InventoryBox")
        {
            MenuInventoryBox inventoryBox = _element as MenuInventoryBox;
            InvInstance invInstance = inventoryBox.GetInstance (_slot);
            if (InvInstance.IsValid (invInstance))
            {
                // For example:
                string description = invInstance.GetProperty ("Description").TextValue;
            }
        }
    }
    

    It's not possible to assign asset files in item properties, but you could use a String property to use e.g. Resources.Load to bring up a texture with that property's name.

    Is it actually possible to nest inventory actions (use, combine etc) within a menu if the rest of your game is controlled with context-sensitive controls?

    The easiest way would be rely on the Choose Hotspot Then Interaction option, since each of these operations would need to exist as a separate icon/interaction that can appear automatically when selecting an item.

    What you could then do is script the functionality of an interaction by referencing that icon's ID. For example:

    private void OnEnable () { EventManager.OnInventoryInteract_Alt += OnInventoryInteract; }
    private void OnEnable () { EventManager.OnInventoryInteract_Alt -= OnInventoryInteract; }
    
    private void OnInventoryInteract (InvInstance invInstance, int iconID)
    {
        if (iconID == 0) // Use
        {
        }
        else if (iconID == 1) // Combine
        {
        }
    }
    

    To use this in conjunction with single-click Hotspots, you can either change the Interaction method when opening/closing the Inventory menu, or check Single 'Use' interaction? in your Hotspot Inspectors to make them act as though they use Context Sensitive mode.

    Then again, if you've already got things working in a non-AC menu, it may be easiest to instead focus on populating your UI with AC's Inventory data by custom means - rathen than making use of AC elements to handle this automatically.

    For example, you can get a list of all items currently held by the Player with:

    AC.KickStarter.runtimeInventory.PlayerInvCollection.InvInstances;
    

    You could then conceivably iterate through them to update your own, non-AC UI system, and similarly update the Player's inventory when necessary.

    if you have enabled the ability to move items within the inventory, and also have stackable items, if you grab one item from a stack, then once you've put it somewhere else, you can't re-stack it back where it came from!

    Can you share steps so that I can recreate this? What's your AC version now?

  • edited February 2021

    Thanks for the response - I'm liable to do as you suggest and primarily focus on unity's UI system - it's definitely useful to know that I can fall back on AC for prototyping since UI design is a huge weakpoint for me! I'll see what I can come up with using cursors for submenus though, since that seems like a really neat workaround.

    Can you share steps so that I can recreate this? What's your AC version now?

    AC version is 1.72.4

    I just managed to recreate the issue in a new project.

    https://imgur.com/mHBQBE8
    https://imgur.com/Frzjh6n
    https://imgur.com/OaicNY1

    Those are the settings. Only thing I really changed were navigating menus directly, allowing multiple item stacks, and being able to rearrange stuff.
    I also added "InteractionA" to let AC select and move stuff. No combinations or usage actions have been defined either, though I can easily add re-stacking through an actionlist attached to a combination of an item with itself.

    Without doing that though, if you select an object in a stack and grab, say 2 of them - then place them in another slot, you can't add the second slot's item or stack back to the original.

    Edit - Just had a thought: Is it something to do with the fact that once an item has been placed in a slot, AC treats that as a wholly new "thing" ? I noticed that if you select one item from a stack then click on the stack it puts it back, but it's the placing of the item in another slot that causes the issue so figured it was something to do with the way slots themselves are read.

  • edited February 2021

    Thanks - actually, I addressed a similar issue in time for 1.73.0. Back up / duplicate your project first, but have a look see it the update solves it.

    once an item has been placed in a slot, AC treats that as a wholly new "thing"?

    Correct. At runtime, the InvInstance class is used to store information about a current item slot - i.e. which InvItem it represents, how many of that item, etc. When an item is selected, a portion of that amount moves to the cursor - but it's still technically the same entity.

    When part of that item is moved to a new slot, it's copied so becomes separate. v1.73.0, however, looks for the specific case that two instances that represent the same InvItem are combined.

  • Holy crap dude! You are so ahead of the curve with this toolkit. I feel like most unity asset devs could really learn a thing or two from how quickly you respond on your forum, and how rapidly you remedy even the most niche issues. I can't rate AC high enough and take every opportunity to offer it as an all-in-one solution to pretty much every aspiring game dev I interact with.
    Thank you so much for your continued support, and the sage advice you offer - it means a hell of a lot! :)

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.