Forum rules - please read before posting.

Custom Inventory Issues Via Direct Control

Hi everyone!

I'm building out a direct-control game at the moment, keyboard and controller only. You can only have one active hotspot visible at a time and can cycle through them with a button press--a bit like Brok: The Investigator. The hotspot interaction method is set to Context Sensitive, with Use and Examine prompts set accordingly to InteractionA and InteractionB.

I've also built a custom inventory that you can toggle via a button press and it pauses the game when it's opened. I'm using direct control for menus, and when you open the inventory it currently auto-selects the first item in the inventory and lets you move left and right to highlight inventory items.

There are a couple of issues I'm running into here as a result of this implementation, so I'm hoping the community can help guide me in the right direction!

First, I'd like to be able to have the "Use" functionality in the Inventory pop-up correlate to the currently active hotspot. In other words, if I'm standing next to a locked door and have the hotspot highlighted, then I open my inventory and select "Use" with the key object, it triggers the "Use key on locked door" interaction for that hotspot.

Second, I'm experiencing a bit of oddness with the 'examine' action in the Inventory pop-up. Right now I have the protagonist's dialogue portrait appearing to describe items (it is set to be able to appear on paused menus to accommodate this), but after examining an item, I have to close and re-open the inventory screen to select items again. Is there a better way I could be handling this? I'm noticing that even though the dialogue menu is set to show when paused, it's unpausing the game to scroll text and then re-pausing after it's done, and not re-selecting the inventory menu item.

Thanks for the help!

-Alex

«1

Comments

  • I'd like to be able to have the "Use" functionality in the Inventory pop-up correlate to the currently active hotspot.

    It's possible to set your InventoryBox element's type to Custom Script, to allow its click functionality to be completely overridden, but you might get by with just having a simple script that automatically combines an item with the active Hotspot, once an item becomes selected:

    using UnityEngine;
    using AC;
    
    public class AutoUseItem : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnInventorySelect += OnInventorySelect; }
        private void OnDisable () { EventManager.OnInventorySelect -= OnInventorySelect; }
    
        private void OnInventorySelect (InvItem invItem)
        {
            Hotspot hotspot = KickStarter.playerInteraction.GetActiveHotspot ();
            if (hotspot && hotspot.HasInventoryInteraction (invItem))
            {
                KickStarter.runtimeInventory.SetNull ();
                hotspot.RunInventoryInteraction (invItem);
            }
        }
    
    }
    

    I'm experiencing a bit of oddness with the 'examine' action in the Inventory pop-up

    Are you using Unity UI or AC for Menu rendering?

    If the Subtitle menu is clickable (and below the Inventory menu in the Menu Manager), then it'll override selection when it turns on. Try moving it above if not already.

    Speech can't be scrolled while the game is paused, however. Instead of pausing the game, it might be worth just disabling the Interaction and Movement systems when the Inventory menu turns on. This can be done with the Engine: Manage systems Action.

  • edited December 2022

    Oh, excellent! I'll give this script a try. What object(s) should I be attaching this script to?

    Are you using Unity UI or AC for Menu rendering?

    I'm using Unity UI right now, basically a carbon copy of the element you built in your first-person tutorial (with a canvas element and buttons hooked in to appear via an Active Input toggle).

    The dialogue portrait element is indeed above the Inventory and it was showing up properly when I examined an object in the inventory and had the portrait set to "Also show when paused." Still ran into that odd issue where after the dialogue played, the Inventory item would not re-select, requiring me to close and re-open the inventory.

    I went ahead and tried going into the Active Input for Inventory toggling to disable and re-enable interaction and movement and set the inventory menu to not pause the game when it opens, but unfortunately that doesn't enable the direct menu control I need when the inventory opens--that seems to only work if the menu is set to pause the game when it opens. I don't suppose there's a way to enable and disable direct menu control via the Active Input ActionScript?

    **Quick additional follow-up that may be tied to this inventory menu issue--I can't seem to build out separate 'examine' and 'use' actions that follow the Context Sensitive control paradigm I have elsewhere (with InteractionA and B mapped to use/examine).

    For example, I have a test inventory item with only a general-purpose Examine interaction and no Use interaction. Neither A or B inputs worked at first, but repeatedly pressing them seemed to eventually play the Examine dialogue. Once I added a general-purpose Use action, BOTH InteractionA and B would play the Use action 100% of the time.

    As mentioned above, after a dialogue, the auto-selection for direct control would not revert control back to the Inventory menu, requiring a close/re-open of the Inventory to select items again.

    Hope this helps!

  • Another follow-up! I built out the same menu using AC instead of Unity and was able to get general purpose use/examine interactions working, and control returns to the menu properly after a dialogue pop-up.

    However, I still can't seem to figure out how to make "using" an inventory item in the menu reflect on the active hotspot. I've tried adding your script to a test inventory item's "Use" ActionList via the "Call Object" action but that doesn't seem to be the way forward there.

  • I don't suppose there's a way to enable and disable direct menu control via the Active Input ActionScript?

    The ability to control in-game menus directly can be set at runtime using the Engine: Manage systems Action.

    I've tried adding your script to a test inventory item's "Use" ActionList via the "Call Object" action but that doesn't seem to be the way forward there.

    The script relies on custom events - it runs automatically without the need to run it via Actions.

    Attaching it to an empty GameObject in the scene should be enough.

  • edited December 2022

    Thank you, Chris--that ability to switch to direct control will be super helpful going forward.

    I went ahead and attached your script to an empty GameObject in the scene, but I still can't quite seem to get it working as intended. As before, the Use action on inventory items works in the inventory pop-up, but it's still not passing through to the active hotspot.

    I've tried it with the inventory pop-up pausing and not pausing the game, but if there are any other things I should have set, please let me know. I'm not familiar with AC's custom event system, so there could be something obvious I'm missing here.

    Thanks!

  • Quick update: The "Unhandled Inventory Interactions" seem to work on the hotspot with this script, but I can't get specific item interactions to function.

  • The script looks for defined Inventory interactions on the Hotspot - it can be changed if necessary, but first test it by making sure a Hotspot has an interaction for the specific Inventory item being used.

  • Happy New Year, Chris! Thanks for helping me figure this out.

    I'm not sure what the issue here could be, so I put together a quick video with my setup so you can see if I've got anything laid out incorrectly: https://dropbox.com/s/s7s4m7mwqfp6034/InvScriptTest.mp4?dl=0

    I've got the "Babbling Brook" hotspot set up with an inventory Use interact for the "Scout Blade" item, just a simple dialogue prompt right now to test the script. I also went into the item itself and removed its general-purpose "use from Inventory" ActionList to prevent any conflicts that might happen there.

    As the video shows, standard hotspot interacts work, interacting with general-purpose "use from Inventory" ActionLists work (as demonstrated with the other inventory item--trying to open the sealed letter), but trying to "Use" the sword while the brook hotspot is active doesn't initiate any action.

  • Try replacing the script's GetActiveHotspot with GetLastOrActiveHotspot - does that work?

    If not, I'll need to see screenshots of your Settings Manager and Inventory menu's properties to attempt a recreation.

  • That did in fact work!

    However, there are some unfortunate caveats to the functionality as it is now: I had to remove the item's generic Use interaction to do so, which feels a bit clunky, not having an interact available unless you're near a hotspot designed for that item.

    And also because it's now remembering the last active hotspot, I can walk away from a hotspot and still have access to its item interactions so long as I'm not in the vicinity of another hotspot.

    Is there perhaps a way to disable the script's functionality unless a hotspot is currently active?

  • I had to remove the item's generic Use interaction to do so, which feels a bit clunky, not having an interact available unless you're near a hotspot designed for that item.

    The script should only kick in as an inventory item becomes selected - it should still allow for an Item's Use interaction to run.

    Is there perhaps a way to disable the script's functionality unless a hotspot is currently active?

    I'd need to see the screenshots mentioned above, as well as a Use interaction you mentioned.

  • The script should only kick in as an inventory item becomes selected - it should still allow for an Item's Use interaction to run.

    Interesting--in that case, you'll probably want to take a look at my settings and see if there's something else afoot.

    Here's my Interface and Inventory Settings layout: https://dropbox.com/s/8fwsrq92rvut06r/Interface_Inventory.jpg?dl=0

    Here's my Hotspot Settings layout: https://dropbox.com/s/2wy1snrc5n77s76/hotspot_settings.jpg?dl=0

    Here's the main Inventory menu (I'm sticking with the AC menu for now): https://dropbox.com/s/4whmwfm8bf6tzq2/Inventory_Properties.jpg?dl=0

    And here's the Inventory Box element in that menu: https://dropbox.com/s/b82g397yykk99kf/Inventory_Element_Properties.jpg?dl=0

    And lastly, here is the Sword's general-purpose "Use" interact as it's set up now: https://dropbox.com/s/ju87fwgfyww79iq/sword_use_action.jpg?dl=0

    If there's anything else you need, please let me know. Thank you!

  • Oddly, the unmodified script above works for me - no need to refer to GetLastOrActiveHotspot.

    I'm unclear on your intent regarding "Use" item interactions, however. Is it the case that the auto-use of an item with a Hotspot should override an item's Use interaction, with the items' Use interaction only running if no Hotspot is active?

  • Interesting... I'll fiddle around with it again and see if I'm doing something wrong. For the life of me I couldn't get that unmodified script to work on my end.

    Re: the Use Interactions, that's precisely the intent yeah. The separation allows for some more interesting variety in inventory-focused interactions via the context-sensitive control scheme.

    For example, being able to "use" a key in your inventory to open a locked box you're carrying (as a check in its generic use interaction against your inventory contents), as well as being able to try using that key on a door in the scene via a hotspot interact. It just increases the possibility space and allows for some more player experimentation.

  • Yeah, I'm not sure what's different between your test project and mine, Chris--but I can't seem to get the AutoUse script to fire without the GetLastOrActiveHotspot change and if the item's generic "use" action is removed. No idea what's going on there :-\

  • I would need to examine your project, in that case.

  • Gotcha. I'll DM you a Dropbox link to a .zip of the project that you can take a look at. Thanks, Chris!

  • edited January 2023

    Thanks for the files.

    Try this alternative. It instead records the active Hotspot at the time the Inventory Menu opens, bypassing the need to check for it when using an item:

    using UnityEngine;
    using AC;
    
    public class AutoUseItem : MonoBehaviour
    {
    
        public string menuName = "Inventory Popup";
        private Hotspot inventoryHotspot;
    
        private void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnInventorySelect += OnInventorySelect;
        }
    
        private void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnInventorySelect -= OnInventorySelect;
        }
    
        private void OnMenuTurnOn (Menu menu, bool isInstant)
        {
            if (menu.title == menuName)
            {
                inventoryHotspot = KickStarter.playerInteraction.GetActiveHotspot ();
            }
        }
    
        private void OnInventorySelect (InvItem invItem)
        {
            if (inventoryHotspot && inventoryHotspot.HasInventoryInteraction (invItem))
            {
                KickStarter.runtimeInventory.SetNull ();
                inventoryHotspot.RunInventoryInteraction (invItem);
            }
        }
    
    }
    
  • Hi Chris, thanks for putting this together! I subbed out the script in my scene and gave it a go. Unfortunately for whatever reason, it's still prioritizing the default "use" action on the inventory item in the Inventory menu.

    When I remove the default "use" action, the hotspot interaction fires appropriately, however. Not sure why there's an inconsistency on my side. FWIW I'm running AC version 1.76.1

  • It's not an inconsistency - I just forgot you wanted that behaviour, sorry.

    Try this:

    using UnityEngine;
    using AC;
    
    public class AutoUseItem : MonoBehaviour
    {
    
        public string menuName = "Inventory Popup";
        private Hotspot inventoryHotspot;
    
        private void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnInventorySelect += OnInventorySelect;
            EventManager.OnBeginActionList += OnBeginActionList;
        }
    
        private void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnInventorySelect -= OnInventorySelect;
            EventManager.OnBeginActionList -= OnBeginActionList;
        }
    
        private void OnMenuTurnOn (Menu menu, bool isInstant)
        {
            if (menu.title == menuName)
            {
                inventoryHotspot = KickStarter.playerInteraction.GetActiveHotspot ();
            }
        }
    
        private void OnInventorySelect (InvItem invItem)
        {
            if (inventoryHotspot && inventoryHotspot.HasInventoryInteraction (invItem))
            {
                KickStarter.runtimeInventory.SetNull ();
                inventoryHotspot.RunInventoryInteraction (invItem);
            }
        }
    
        private void OnBeginActionList (ActionList actionList, ActionListAsset actionListAsset, int startingIndex, bool isSkipping)
        {
            foreach (InvItem invItem in KickStarter.inventoryManager.items)
            {
                if (actionListAsset && actionListAsset == invItem.useActionList)
                {
                    if (inventoryHotspot && inventoryHotspot.HasInventoryInteraction (invItem))
                    {
                        actionList.Kill ();
                        KickStarter.runtimeInventory.SetNull ();
                        inventoryHotspot.RunInventoryInteraction (invItem);
                    }
                }
            }
        }
    
    }
    
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.