Forum rules - please read before posting.

Help with inventory in navigate directly mode

Hi everyone,
AC 1.70.0 + Unity 2019.2.17f1 on a 2d game.

As suggested by Chris I open a new thread (here the reference to the original one: https://adventurecreator.org/forum/discussion/10550/question-about-navigate-menus-directly-with-controller/p1)

My original game is a 2d game with movement method set to "Point And Click", input method "Mouse and Keyboard" and interaction method set to "Context Sensitive", a classica graphic adventure for PC.
Now I'm adding the controller support with the directly-navigate menus.
At the moment it's all ok for the traditional menus (Pause, Title, and so on), but I note a different behaviour with the inventory when I use the direct navigation mode.

Here a video on how inventory works with "mouse and keyboard" method: https://drive.google.com/file/d/1o_4L_gu8QwmKGi5Psm98fpGOl_yas2iJ/view?usp=sharing
As you can see I simply open the inventory (with scrollwhell or with "I" button), when the mouse go on the object I see the name, I select a object with LMB and I can use it on the hotspot in scene (with inventory open) and, with object selected I can also move my character. Then I can deselect it with the RMB.

Here also the inventory settings: https://drive.google.com/file/d/1tUzc5Glh4U4oAXvV4XvkKzU8AmXNFBnj/view?usp=sharing
and the general settings: https://drive.google.com/file/d/1TvCEyp2Gexw0N7QxjeLTuIGGA4gKoEXP/view?usp=sharing

Now I made the passage with direct menu navigation, so I'd like (if possible) to have the same user-friendly behaviour.
Here the Inventory settings: https://drive.google.com/file/d/1L5sqrPQ69JxwPUUcE_ldjGAu7aB01Yr8/view?usp=sharing
and the general settings: https://drive.google.com/file/d/1BrznWPVI8xHr38UC9eQ1_K6miyKC7lnX/view?usp=sharing
I activated the direct navigation option in Menu manager and in "ActionList when turn on I added" an action list running in "Run in background" with a Engine/Manage system/Direct-nav in-game menus enabled, while in "ActionList when turn off" I put the disabled Engine/Manage System/Direct-nav in-game menus

And this is the result on video (same scene of the previous video): https://drive.google.com/file/d/10AlY6UmGHyElamnCrHbYF68rrAoT_sPu/view?usp=sharing
pratically I open the inventory and I can select the objects with left/right Dpad (and I can see the names of the objects and for me it's correct). When I press the Xbutton I select the object (correctly), but the name of the object remains above the inventory (in the first video, when I selected an object the name disappeared). I changed the Position (in the hotspot menu) to On Hotspot (and the behaviour is as in the video02); if I change on Follow Cursor I have the name on the position of the cursor (and it could be ok), but with the object selected, I can always move on inventory, so I can have an object but, if I move the left/right Dpad, I have another name on the object selected.

Another thing is that I have the name of the object but I can't see the name of the hotspots in scene, so I can undestand on what object I'm interacting (with inventory open). If I close the inventory the name of the object disappears and I can see the name of the hotspot of the scene (correct).

Same thing if I want to move my character with an object selected and inventory open: in this case I can't because it seems as I press the button to intercat with the object, but, if I close the inventory, I can move the character and have the selectd object simultaneously (correct).

I don't know if there's a way to have the behaviour of video one, but with direct menu activated on inventory menu.

Comments

  • Thank you for the videos - that helps a lot.

    When you select an item, direct-navigation of the menu is still enabled - so it'll continue to be navigable. You need to disable navigation when the item is selected, so that you can then rely on the cursor for regular gameplay again.

    This is best done by hooking into the OnInventorySelect custom event hook.

    It's also possible to use this to dynamically switch your Hotspot menu's position type between Follow Cursor and On Hotspot.

    This may not solve everything but it should be a start. Try placing this script on a GameObject in the scene:

    using UnityEngine;
    using AC;
    
    public class DirectNavInventory : MonoBehaviour
    {
    
        void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
            EventManager.OnInventorySelect += OnInventorySelect;
            EventManager.OnInventoryDeselect += OnInventoryDeselect;
        }
    
        void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
            EventManager.OnInventorySelect -= OnInventorySelect;
            EventManager.OnInventoryDeselect -= OnInventoryDeselect;
        }
    
        void OnInventorySelect (InvItem invItem)
        {
            DisableDirectControl ();
            SetHotspotPositionType (UIPositionType.FollowCursor);
        }
    
        void OnInventoryDeselect (InvItem invItem)
        {
            if (PlayerMenus.GetMenuWithName ("Inventory"))
            {
                EnableDirectControl ();
                SetHotspotPositionType (UIPositionType.OnHotspot);
            }
        }
    
        void OnMenuTurnOn (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                EnableDirectControl ();
                SetHotspotPositionType (UIPositionType.OnHotspot);
            }
        }
    
        void OnMenuTurnOff (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                DisableDirectControl ();
                SetHotspotPositionType (UIPositionType.FollowCursor);
            }
        }
    
        void EnableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
        }
    
        void DisableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = false;
            if (KickStarter.playerMenus.EventSystem) KickStarter.playerMenus.EventSystem.SetSelectedGameObject (null);
        }
    
        void SetHotspotPositionType (UIPositionType positionType)
        {
            PlayerMenus.GetMenuWithName ("Hotspot").uiPositionType = positionType;
        }
    
    }
    
  • Thank you Chris, I'll try as soon as possible.

  • Hi Chris,
    I tested the script and it's fantastic: with this the behaviour is correct.
    The only issue I'm trying to solve is: if I have a selected object and then I close the inventory and re-open, I have the first slot of the inventory with the name of the object (as if I can select it) and, simultaneously, the previous selected object on the cursor. I'm trying to find a way to recognize that I have already a selected object when I open the inventory, in this case it maintains the current selection on the cursor without select another object in inventory.

    Here what happened: https://drive.google.com/file/d/1NilTOWjK8gLV2Wo5S6tgRovrZtCFrbRX/view?usp=sharing
    In my example I have selected tha nail file and with the script it works in fantastic way, but then, with the nail file still selected, I close the inventory and re-open, so I find the nail file selected on cursor and the letter as first element selected in inventory. Probably the correct behaviour could be that, with a already selected object, when close/open the inventory it maintains only the previous selected object, otherwise, it can select the inventory object as the first time.

  • Sure - I expect a bit of tweaking to get your exact intended behaviour.

    Give this one a try next. When the menu is opened, but an item is selected, it will no longer force direct-navigation:

    using UnityEngine;
    using AC;
    
    public class DirectNavInventory : MonoBehaviour
    {
    
        void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
            EventManager.OnInventorySelect += OnInventorySelect;
            EventManager.OnInventoryDeselect += OnInventoryDeselect;
        }
    
        void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
            EventManager.OnInventorySelect -= OnInventorySelect;
            EventManager.OnInventoryDeselect -= OnInventoryDeselect;
        }
    
        void OnInventorySelect (InvItem invItem)
        {
            DisableDirectControl ();
            SetHotspotPositionType (UIPositionType.FollowCursor);
        }
    
        void OnInventoryDeselect (InvItem invItem)
        {
            if (PlayerMenus.GetMenuWithName ("Inventory"))
            {
                EnableDirectControl ();
                SetHotspotPositionType (UIPositionType.OnHotspot);
            }
        }
    
        void OnMenuTurnOn (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory" && KickStarter.runtimeInventory.SelectedItem == null)
            {
                EnableDirectControl ();
                SetHotspotPositionType (UIPositionType.OnHotspot);
            }
        }
    
        void OnMenuTurnOff (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                DisableDirectControl ();
                SetHotspotPositionType (UIPositionType.FollowCursor);
            }
        }
    
        void EnableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
        }
    
        void DisableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = false;
            if (KickStarter.playerMenus.EventSystem) KickStarter.playerMenus.EventSystem.SetSelectedGameObject (null);
        }
    
        void SetHotspotPositionType (UIPositionType positionType)
        {
            PlayerMenus.GetMenuWithName ("Hotspot").uiPositionType = positionType;
        }
    
    }
    
  • Thank you Chris,
    I tried but it seems to have the same behaviour of the previous script.
    I noticed you add "&& KickStarter.runtimeInventory.SelectedItem == null" in line 40.
    I don't undestand code very well, so I guess this line check if a item is selected or not (null). If null it enables Direct Control.
    The issue seems that it doesn't identify when an object is still selected when I open the inventory. So actually, when I re open the inventory (with a previous object selected) I can select a new one again.

  • edited October 2020

    I guess this line check if a item is selected or not (null). If null it enables Direct Control.

    That's correct. This code handles the enabling/disabling of direct-navigation when the menu turns on and off.

    This replaces the need to rely on Actions to do this, so make sure that your "ActionList when turn on/off" assets don't conflict.

    If the issue still occurs when you unset them, let's see another video so I can see the exact behaviour.

  • Fantastic, it was the Engine/Manage system/ DIrect-nav in game menus in ActionList when turn on/off. I delete these actions and now it works correctly.

    I go on with other tests.

    Thank you very much.

  • Hello Chris,
    I'm here again, but this time I'm not sure if it'a logical behaviour or not (so I'm not sure if it a issue or not).

    When I create the game with mouse and keyboard, when I open the inventory, I can always move my character and interact with other hotspots in scene (also without selecting an inventory object). But when I use controller and open inventory I enter in Direct Navigation, so I can't move my character (for example to change scene) or interact with a hotspot till I select an object. To make it I have to close inventory.

    So I don't know if there's a possible solution or, if direct navigation on inventory excludes obligatorily interaction and movement till I close it.

  • edited October 2020

    direct navigation on inventory excludes obligatorily interaction and movement till I close it.

    It shouldn't do. It's because of this conflict that direct-control of menus during gameplay is an option you have to set via Actions.

    Are your settings still the same as above? Is there any difference if you change the "Input method" to "Keyboard Or Controller"?

    If you're using point-and-click to move, is there a conflict with inputs for moving vs the menu's Submit button - or are these mapped to separate controller buttons?

  • Both Input method "Mouse And Keyborad" or "Keyboard or Controller" have the same behaviour when I open the inventory in Direct Navigation.

    When I don't use direct navigation (both in "Mouse And Keyborad" or "Keyboard or Controller"), I can open inventory and, with it still open, I can simultaneously move the character, see the hotspots.

    When I activate the Direct Navigation (for inventory via script), when I open the inventory, with the X-button (on joystick) that usually I use as InteractionA (to click on scene to move the character or take an object) I can only select the object. So with the same button I select the objects and I should move the character when I click on a point outside the inventory.

    With the inventory open, if I move the cursor with joystick to move the character, with a first pression it select the object, and with a second pression I can move the character but with the object selected.

    With inventory closed it works.

  • Your movement method is still "Point And Click"?

    Once an item becomes selected, the menu should not longer be directly-navigable - leaving the player free to move/interact in the scene.

    What is the state of the menu after selecting an item? A video here will help see the problem.

    Does this issue occur if you switch to AC for the menu's Source?

  • Your movement method is still "Point And Click"?

    It's always Point and Click.

    Once an item becomes selected, the menu should not longer be directly-navigable - leaving the player free to move/interact in the scene.

    Correct and this is perfect.

    What is the state of the menu after selecting an item? A video here will help see the problem.

    Here the video with all the behaviours (inventory open and closed) : https://drive.google.com/file/d/1S9lcP5pSYbkdyMqQOuCE4PaiE-hedlPw/view?usp=sharing

    Does this issue occur if you switch to AC for the menu's Source?

    The inventory menu is an AC menu.

  • edited October 2020

    I may have misunderstood you, as I thought the behaviour you're getting is the behaviour you wanted.

    When you de-select an item while the Inventory menu is open, it reverts back to navigating the menu - so pressing the button will cause another item to be selected, not move the player.

    If you're using an AC menu, then the same input (InteractionA) will be used for both interacting with menus and moving the player - but clicks on the menu will be "consumed", and - by design - won't affect the player in the same frame.

    What is the exact behaviour you want?

  • Thank you Chris,
    I've rearranged my ideas and received suggestions on how the game should work with the controller and navigable inventory.

    The issue is that my character has to be free to move also if the inventory is open, but, if I undestand correctly, if InteractionA both moves the character and selects the objects in inventory it's not possible.

    So I thought to this possible (I don't know) solution:

    • The character can move freely using the standard Interaction buttons.
    • When I open the inventory, I'd like to change the mapped buttons to select/use items (only for inventory).
      So I open/close it with Y button (joystick) and I can move left/right with D-Pad (as it's now), and this part I think it's easy because it already works.

    • But with inventory open I'd like to have this possibilities:

    1. I should be able to select an object to use only on hotspots in scene (not to use with other objects in inventory) with LB button. When I deselect it I come back to the initial situation (open inventory but character can move freely). In this case the selected object can't be combined with other inventory objects (so when I select the object, it attaches to the cursor (as it does now) but it can't go (or interact) on inventory) .
    2. I should be able to examine an object using RB button.
    3. I should be able to select an object to use exclusively with other objects in inventory (and not in scene) with LT button. When I deselect it I come back to the initial situation (open inventory but character can move freely). In this case the selected object can't be used on scene's hotspots and, probably, I can move it only horizontally to combine with the other inventory objects, so not attached to the cursor.

    In my head, in this way, I can separate the character's movement from the inventory's functionality and so I can use them simoultaneously.
    But i don't know if AC can permit it and, eventually, how can be implemented.

  • It's certainly something I'd like to be possible - albeit through scripting.

    As 3. is the more tricky one, let's get 1. and 2. working first.

    Try this update:

    using UnityEngine;
    using AC;
    
    public class DirectNavInventory : MonoBehaviour
    {
    
        void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
        }
    
        void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
        }
    
        void Update ()
        {
            if (InvInstance.IsValid (KickStarter.runtimeInventory.HoverInstance))
            {
                if (Input.GetButtonDown ("SelectItemForHotspots"))
                {
                    KickStarter.runtimeInventory.HoverInstance.Select ();
                    PlayerMenus.GetMenuWithName ("Inventory").TurnOff ();
                }
                else if (Input.GetButtonDown ("ExamineItem"))
                {
                    KickStarter.runtimeInventory.HoverInstance.Examine ();
                }
            }
        }
    
        void OnMenuTurnOn (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                KickStarter.runtimeInventory.SetNull ();
                EnableDirectControl ();
                SetHotspotPositionType (UIPositionType.OnHotspot);
            }
        }
    
        void OnMenuTurnOff (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                DisableDirectControl ();
                SetHotspotPositionType (UIPositionType.FollowCursor);
            }
        }
    
        void EnableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
        }
    
        void DisableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = false;
            if (KickStarter.playerMenus.EventSystem) KickStarter.playerMenus.EventSystem.SetSelectedGameObject (null);
        }
    
        void SetHotspotPositionType (UIPositionType positionType)
        {
            PlayerMenus.GetMenuWithName ("Hotspot").uiPositionType = positionType;
        }
    
    }
    

    You'll need to use the latest release, v1.72.0, and then - in your InventoryBox properties, check both Prevent interactions? and Prevent selection?.

    You'll need to define two new inputs: SelectItemForHotspots and ExamineItem, which should be mapped to LB and RB respectively. When you invoke SelectItemForHotspots, the menu should close and you'll be able to use it in the scene.

    Testing this myself, however, does reveal that there is still an issue with player movement while the menu is open. I shall look into this on my end.

  • Thank you Chris, in the next days I'll update to 1.72.0 and try the new script.

  • When you do, use this one instead:

    using UnityEngine;
    using AC;
    
    public class DirectNavInventory : MonoBehaviour
    {
    
        private InvInstance examineInstance;
    
        void OnEnable ()
        {
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            EventManager.OnMenuTurnOff += OnMenuTurnOff;
            EventManager.OnInventoryInteract_Alt += OnInventoryInteract;
            EventManager.OnEndActionList += OnEndActionList;
        }
    
        void OnDisable ()
        {
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
            EventManager.OnMenuTurnOff -= OnMenuTurnOff;
            EventManager.OnInventoryInteract_Alt -= OnInventoryInteract;
            EventManager.OnEndActionList -= OnEndActionList;
        }
    
        void Update ()
        {
            if (InvInstance.IsValid (KickStarter.runtimeInventory.HoverInstance))
            {
                if (Input.GetButtonDown ("SelectItemForHotspots"))
                {
                    KickStarter.runtimeInventory.HoverInstance.Select ();
                    PlayerMenus.GetMenuWithName ("Inventory").TurnOff ();
                }
                else if (Input.GetButtonDown ("ExamineItem"))
                {
                    KickStarter.runtimeInventory.HoverInstance.Examine ();
                }
            }
        }
    
        void OnInventoryInteract (InvInstance invInstance, int cursorID)
        {
            if (cursorID == KickStarter.cursorManager.lookCursor_ID)
            {
                examineInstance = invInstance;
            }
        }
    
        void OnEndActionList (ActionList actionList, ActionListAsset actionListAsset, bool isSkipping)
        {
            if (actionListAsset && InvInstance.IsValid (examineInstance) && examineInstance.InvItem.lookActionList == actionListAsset)
            {
                if (PlayerMenus.GetMenuWithName ("Inventory").IsOn ())
                {
                    MenuInventoryBox inventoryBox = PlayerMenus.GetElementWithName ("Inventory", "InventoryBox") as MenuInventoryBox;
                    PlayerMenus.GetMenuWithName ("Inventory").Select ("InventoryBox", inventoryBox.GetItemSlot (examineInstance));
                }
                examineInstance = null;
            }
        }
    
        void OnMenuTurnOn (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                KickStarter.runtimeInventory.SetNull ();
                EnableDirectControl ();
                SetHotspotPositionType (UIPositionType.OnHotspot);
            }
        }
    
        void OnMenuTurnOff (Menu _menu, bool isInstant)
        {
            if (_menu.title == "Inventory")
            {
                DisableDirectControl ();
                SetHotspotPositionType (UIPositionType.FollowCursor);
            }
        }
    
        void EnableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
        }
    
        void DisableDirectControl ()
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = false;
            if (KickStarter.playerMenus.EventSystem) KickStarter.playerMenus.EventSystem.SetSelectedGameObject (null);
        }
    
        void SetHotspotPositionType (UIPositionType positionType)
        {
            PlayerMenus.GetMenuWithName ("Hotspot").ForceOff ();
            PlayerMenus.GetMenuWithName ("Hotspot").uiPositionType = positionType;
        }
    
    }
    

    This'll fix a couple of issues, but for the player to still move while the menu is enabled, you'll need to switch over to Unity UI for the menu's rendering.

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.