Forum rules - please read before posting.

OnInventorySelect Event Not Triggering in Adventure Creator

Hello!

I hope this message finds you well. I wanted to bring to your attention a potential bug that I have encountered regarding the OnInventorySelect event in Adventure Creator (AC).

I have been trying to utilize the OnInventorySelect event in my code, but it seems that the event is not triggering properly. I have attempted various configurations, including a clean installation of the Adventure Creator asset in Unity. Unfortunately, I have not been able to see any debug.log output from the OnInventorySelect method.

Here is a snippet of the code I am using:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using AC;

    public class EventsTester : MonoBehaviour
    {
        private void OnEnable ()
        {
            EventManager.OnInventorySelect += OnInventorySelect;
        }

        private void OnDisable ()
        {
            EventManager.OnInventorySelect -= OnInventorySelect;
        }

        private void OnInventorySelect (InvItem invItem)
        {
            print("OnInventorySelect " + invItem);

            KickStarter.playerMenus.EnableInteractionMenus(invItem);
        }
    }

I would greatly appreciate it if anyone could shed some light on this issue or provide guidance on how to properly trigger the OnInventorySelect event.

AC version: 1.77.3
Unity ver:2021.3.24f1

Thank you in advance for your assistance. I look forward to hearing from you.

Thanks,
Barnim

«1

Comments

  • The code's solid - it works on my end when attached to the 3D Demo scene, and the Sword item is selected in the Inventory.

    What are the circumstances around your selection of the item?

    Given the event you're using, it's important to be clear that selecting an item - in the AC sense - isn't necessarily the same as clicking its button in the Inventory menu.

    Item selection refers to an item becoming "active" - whether indicated by a change in cursor / Hotspot label - such that following clicks on another item or Hotspot result in an interaction being triggered.

    If an InventoryBox's type is set to Custom Script, or "Allow selection?" is unchecked, then item's won't necessarily be selected when clicked.

    If that's what you're trying to hook into, however, you can rely on the OnMenuElementClick event, and cast the intended element:

    void OnMenuElementClick (Menu menu, MenuElement element, int slot, int buttonPressed)
    {
        if (menu.title == "Inventory" && element.title == "InventoryBox")
        {
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvItem invItem = inventoryBox.GetItem (slot);
            print("OnInventorySelect " + invItem);
        }
    }
    
  • Turns out, the OnInventorySelect event works perfectly fine in a fresh, unchanged project's 3D Demo scene.

    However, I discovered that it stops working once you switch the Inventory interactions to "Multiple." Doesn't that seem like a problem? Shouldn't it work consistently, regardless of the chosen interactions mode?

    On the other hand, the OnMenuElementClick event seems to work flawlessly at all times. This could potentially help me with creating custom inventory item interactions. I only need two actions: "look at" (to describe an item) and "combine" (to start selection of another item to try to combine them). These actions should be selectable via keyboard, controller, or mouse from a contextual menu. I've made progress with input using the Input System and custom menus thanks to "AC_ScreenSpaceHotspotDetection".

    By the way, AC_ScreenSpaceHotspotDetection also relies on the OnInventorySelect event, and it doesn't work when interactions in the Inventory are set to "Multiple".

    Is there any insight or advice you can offer regarding these issues? I greatly appreciate your support and guidance in resolving them.

  • edited May 2023

    Shouldn't it work consistently, regardless of the chosen interactions mode?

    Clicking an item doesn't necessarily equate to selecting it.

    If an item becomes selected, however, the event will fire - regardless of the interaction method.

    What is your "Interaction method" set to?

    If "Choose Hotspot Then Interaction" - such that clicking an item brings up the Interaction menu - then an item will not be "selected" in the AC sense at that point. It only becomes selected if the user then clicks an Interaction icon that causes it to become so - whether that be automated, or because the Interaction calls the Inventory: Select Action.

    When it comes to AC's built-in item combining system, an item does need to be selected. What you could do is hook into OnMenuElementClick, and then select the item manually as part of that:

    MenuInventoryBox inventoryBox = element as MenuInventoryBox;
    InvInstance invInstance = inventoryBox.GetInstance (slot);
    invInstance.Select ();
    

    By the way, AC_ScreenSpaceHotspotDetection also relies on the OnInventorySelect event, and it doesn't work when interactions in the Inventory are set to "Multiple".

    The script and the settings go in tamdem. The template hooks into the event to alter the "Hotspot detection method" while an item is selected and ready to be used on a Hotspot. It won't fire at the point an Item's Interaction menu is opened as a result of enabling Multiple interactions, but nor should it - the item hasn't yet been selected, but is then open to being so by a further click on the intended Interaction icon.

  • Thanks for clarifying how the selection process works in AC. I have also read and tested the script provided in the AC Wiki page (https://adventure-creator.fandom.com/wiki/Override_inventory_clicks). It has been instrumental in helping me better understand and test the functionality.

    I have one more question. I want to add a button in the Interaction menu that allows the player to return to the Inventory while keeping the previously selected item highlighted. This would be helpful when the action originated from a specific inventory item and the player wants to go back to it later.

    Here's the user scenario:

    • The player goes to the Inventory and selects an item.
    • They click the item to open the Interaction menu with options like "Examine" and "Combine".
    • If "Examine" is selected, a subtitle menu shows the description, and the player stays in the Inventory with the same item highlighted.
    • If "Combine" is selected, the interaction menu closes, and the player remains in the Inventory with the selected item.

    I'm encountering issues, such as losing focus when the interaction menu closes. I need to close and reopen the Inventory to regain navigation functionality.

    Could you provide some guidance on implementing this feature?

    Thank you for your assistance and expertise. I appreciate your help.

  • How far along your four steps are you getting things to work? Certainly the first three should be possible without need for any scripts.

    For the "Combine" button - this could be an Interaction, with an icon assigned from the Cursor Manager, similar to Examine.

    Putting aside custom scripts for the moment, try defining a specific "Combine" interaction for a given item, that uses the Inventory: Select Action to select that item. This can later be automated, but that in itself should cause the item to become selected.

    Depending on your settings, this may also close the Interaction menu - but following this up with a Menu: Change state Action should do this manually if necessary.

    I'm encountering issues, such as losing focus when the interaction menu closes. I need to close and reopen the Inventory to regain navigation functionality.

    The order of menus listed in the Menu Manager affects the priority they're given when auto-selecting their elements, but you can use the Menu's Select function to manually correct this:

  • edited May 2023

    Hi Chris,

    I followed your suggestion and tried to implement the interaction without using any custom scripts. I added a "Combine" interaction in the Cursor Manager and the Interaction Menu. I also set up the "Combine" interaction as a standard interaction that executes "Inventory->Select" in an Action List. Additionally, in the "Combine" interaction for inventory items, I displayed an informative text.

    Each time the inventory interaction finishes, the inventory loses focus. Everything works fine if I change the UI source for the Inventory to AC's built-in UI.

    It's a lot of setups, so I recorded the entire process with comments and uploaded a video. Here's the link:
    https://clipchamp.com/watch/cEuEKZsqoF6

    Thank you for your continued support and guidance!

  • edited May 2023

    Recreated - thanks for the video.

    It's a bit hard to say where the fault lies, since Unity UI and its Event System is also at play here. However, you can remedy this with a custom script that:

    1. Records the last-selected item slot to be highlighted
    2. Re-selects that slow once gameplay resume

    ReselectInventory.cs:

    using UnityEngine;
    using AC;
    
    public class ReselectInventory : MonoBehaviour
    {
    
        int lastSelectedSlot;
    
        void OnEnable ()
        {
            EventManager.OnEnterGameState += OnEnterGameState;
            EventManager.OnMouseOverMenu += OnMouseOverMenu;
        }
    
        void OnDisable ()
        {
            EventManager.OnEnterGameState -= OnEnterGameState;
            EventManager.OnMouseOverMenu -= OnMouseOverMenu;
        }
    
        void OnEnterGameState (GameState gameState)
        {
            Menu inventoryMenu = PlayerMenus.GetMenuWithName ("Inventory");
            if (inventoryMenu.IsOn () && gameState == GameState.Normal)
            {
                inventoryMenu.Select ("InventoryBox", lastSelectedSlot);
            }
        }
    
        void OnMouseOverMenu (Menu menu, MenuElement element, int slot)
        {
            if (menu.title == "Inventory" && element.title == "InventoryBox")
            {
                lastSelectedSlot = slot;
            }
        }
    
    }
    

    A quick note on the Combine interactions - I mentioned automating this earlier. To avoid using the Inventory: Select Action for each, you can check Select item if Interaction is unhandled? in the Settings Manager's "Inventory settings" panel.

  • Thank you for taking the time to review the video and provide further assistance. I really appreciate your help, and I'm glad to report that I made some progress. Your script partially solves the issue, although I have encountered some additional problems.

    Firstly, I would like to express my gratitude for the script you provided. It records the last-selected item slot to be highlighted and re-selects that slot once gameplay resumes. This helps in maintaining the selection focus in the Inventory. The ReselectInventory script works to some extent, but I am facing further challenges.
    And I'm not sure how is it possible that it works if you consider the following:

    One particular issue I noticed is that the "OnMenuTurnOn" and "OnMenuTurnOff" events are triggered only after closing the interaction menu, and both events fire simultaneously. As a temporary solution, I implemented a hack by checking the menu's status in the Update method. This allows me to block interactions in the Inventory while the Interaction menu is open (to prevent scrolling of Inventory while navigating down the Interaction menu, for example). I have demonstrated this problem in a video: https://clipchamp.com/watch/NSfoi38U32t

    Thank you again for your valuable help!

  • Check that your OnEnable and OnDisable functions hook into the OnMenuTurnOn event - it looks like it might be hooking into OnMenuTurnOff.

  • You are absolutely right, and I can't believe I missed such a simple mistake.
    My OnEnable and OnDisable functions were indeed hooking into the OnMenuTurnOff event instead of the OnMenuTurnOn event. It's embarrassing how easily I overlooked this. I have been working on this UI for so long that I started missing these basic issues.

    I sincerely appreciate your keen observation and pointing out the error. Your guidance has been incredibly valuable, and I can't thank you enough for your help.

    Barnim

  • edited May 2023

    No worries - I've done it enough times to spot it!

  • Hi Chris,

    I have another problem that I can't seem to solve, and I need your help. The behavior of the OnMouseOverMenu event is inconsistent between the Inventory menu and the Conversation menu.

    In the Inventory menu, the OnMouseOverMenu event is triggered during keyboard navigation, but it doesn't respond to mouse movements (even though the buttons correctly highlight and select menu items). On the other hand, in the Conversation menu, the OnMouseOverMenu event doesn't respond to keyboard input but is triggered by mouse movements. This is the opposite of what I would expect based on the behavior in the Interaction menu.

    The Event System correctly detects the "Selected" object, but I'm not sure how to detect when the Event System changes the "selected" object to a new one.
    Additionally, this is an attempt to work around something that works in one menu but not in the other. I'm unsure how to resolve this issue, as I need it to detect mouse clicks outside of the menu and restore the previously selected element via keyboard input to avoid losing focus for the keyboard.

    I have attached a link to a video illustrating the problem:
    https://youtube.com/watch?v=MWr4B1oOByo

    Unfortunately, the video gets blurry in some places, and I can't make it crisp with Clipchamp.
    The code for OnMouseOverMenu looks like this:

    void OnMouseOverMenu (AC.Menu menu, MenuElement element, int slot) 
            {
    
                if (menu == null)
                {
                    print("Menu is null!");
                    return;
                }
    
                if (element == null)
                {
                    print("Menu element is null! Menu: " + menu.title);
                    return;
                }
    
                print("OnMouseOverMenu " + menu.title + " element: " + element.title + " slot: " + slot);
    
                if ((menu.title == inventoryMenuName && element.title == "InventoryBox")
                    || (menu.title == "Conversation" && element.title == "DialogueList"))
                {
                    // Save info what item was clicked before opening the Interaction menu
                    lastSelectedSlot = slot;
                }
    
                if (menu.title == "Pause")
                {
                    lastSelectedMenuElement = element;
                }
            }
    

    And the print function within it is the one that I observe (or miss it) in the console.
    If you need better video quality pls let me know, I'll find another recording tool.

    Could you please provide some guidance on how to address this issue?

    Thank you for your continued support and expertise.

  • I can't make out from the video - but are you using your own Event System and/or Input System? The issue might be a combination of factors/systems that are all wrangling for control over UI selection.

    Also, what is your intent behind UI selection? For menus to be simultaneously directly- and mouse-controlled?

    When it comes to the OnMouseOverMenu event: AC has its own checks for determining whether or not a Menu is currently directly-controlled. If this check fails, it will not be able to fire the event when using the keyboard or controller.

    This check comes in the form of the Directly-navigate Menus when.. options at the top of the Menu Manager. There are separate options for each "game state" - paused, during conversations etc.

    For navigation during gameplay: this isn't a Manager option, but available at runtime using the Engine: Manage systems Action - so that you can enable/disable such control when needed.

    If your scene has no Event System, AC will spawn its own - and this will include its Optional Mouse Input Module, which forces Menus into either mouse/direct control based on the above settings. You can attach this to your own Event System if you have one. It shouldn't be strictly necessary, but the closer you stick to how AC "wants" to work, the more consistent the behaviour should be.

  • My game is a First Person Adventure with optional VR. I achieved this by detecting VR headset connectivity. I've prepared two Menu Managers: a PC version (Unity Prefabs), and a VR version using "Unity UI in scene" with "World Space UI" Canvas render mode. This allows for easy UI customization per platform. Depending on the situation, I load the relevant one. The code could be optimized further, but it's not the case today :)

    To enable VR, I had to use the new Input System. Your package from Downloads helped configure it, making the keyboard, mouse, Gamepad, and Oculus Quest2 with controllers functional.

    I also implemented automatic input detection in the Update() method if VR is not detected:

            private void AutoSwitchInputMethod()
            {
                if (Keyboard.current.anyKey.isPressed)
                {
                    SetInputMethod(InputMethod.MouseAndKeyboard);
                    AC.KickStarter.menuManager.keyboardControlWhenPaused = true;
                    AC.KickStarter.menuManager.keyboardControlWhenDialogOptions = true;
                    AC.KickStarter.menuManager.keyboardControlWhenCutscene = true;
                    AC.KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
                }
    
                if (isMouseMoveDetected || Mouse.current.leftButton.isPressed || Mouse.current.rightButton.isPressed)
                {
                    SetInputMethod(InputMethod.MouseAndKeyboard);
                    AC.KickStarter.menuManager.keyboardControlWhenPaused = false;
                    AC.KickStarter.menuManager.keyboardControlWhenDialogOptions = false;
                    AC.KickStarter.menuManager.keyboardControlWhenCutscene = false;
                    AC.KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
                }
    
                if (Gamepad.current != null
                    && (Gamepad.current.buttonSouth.wasPressedThisFrame))
                {
                    SetInputMethod(InputMethod.KeyboardOrController);           
                    AC.KickStarter.menuManager.keyboardControlWhenPaused = true;                        
                    AC.KickStarter.menuManager.keyboardControlWhenDialogOptions = true;
                    AC.KickStarter.menuManager.keyboardControlWhenCutscene = true;
                    AC.KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
                }
                DetectMouseMovement();
            }
    
            void DetectMouseMovement()
            {
                isMouseMoveDetected = false;
                Vector2 mousePosition = Mouse.current.position.ReadValue();
                Vector2 mouseDelta = mousePosition - lastMousePosition;
    
                if (mouseDelta != Vector2.zero)
                {
                    isMouseMoveDetected = true;
                }
                lastMousePosition = mousePosition;                          
            }
    

    All menus are set with AC.PlayerMenus.GetMenuWithName("Pause").autoSelectFirstVisibleElement, and I use Engine-Manage system->Direct-nav in-game menus: Enabled for each of them "On Turn On".
    And in the code (just to be sure):
    void OnMenuTurnOn (AC.Menu menu, bool isInstant)
    {
    KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
    menu.autoSelectFirstVisibleElement = true;

    I've developed a proof-of-concept VR menu, leveraging "ScreenSpaceHotspotDetection" for Hotspots detection when near, akin to Beyond of a Steel Sky. All VR menus are joystick-controlled.

    My current focus is refining PC menus. I aim for full WSAD keyboard or left gamepad joystick navigation without the need for cursor aiming. The mouse is optional and only active upon detection of movement. The cursor is default hidden and should remain so when menus are closed. Mouse use should hide the keyboard cursor and vice versa, with the last used menu element highlighted for seamless navigation.

    I have implemented a method to detect mouse clicks outside the Conversation menu in Update(), maintaining keyboard focus:

                // Conversation Menu
                if (conversationMenu != null && conversationMenu.IsOn() && lastSelectedSlot != null
                    && (KickStarter.playerInput.GetMouseState () == MouseState.SingleClick
                    || KickStarter.playerInput.GetMouseState () == MouseState.DoubleClick
                    || KickStarter.playerInput.GetMouseState () == MouseState.RightClick)
                    && !KickStarter.playerMenus.IsMouseOverMenu())
                {
                    // hover on last selected slot even if mouse clicks outside of menu
                    conversationMenu.Select ("DialogueList", lastSelectedSlot);
                }
    

    In both the PC and VR versions, the player has access to items in Inventory from the Interaction Menu when operating on a Hotspot. I added scroll in the Interaction menu in InventoryBox. This is the only way Player interacts with items on Hotsposts.
    The Inventory serves only to gain information about items and to combine items.

    I have my base GameObject called "JAGS-SceneStart", which I add to each scene at the top, which customizes some of Adventure Creator's actions. It contains scripts:

    • My main "JagsOnSceneStart" script - VR detection and Menu Manager configuration, creating a VRPlayer in the scene, and input detection.
    • My script for customizing UI behaviors "JagsUIManagement" - manual management of UI in Inventory Menu, Inventory Interactions Menu (my own custom menu), Conversations Menu, Pause Menu. I had to do this to separate Interaction Menus on Hotspots from item interaction menus in Inventory.
    • Slightly modified ScreenSpaceHotspotDetection - added mouse movement detection and showing the mouse cursor only then - so if the player uses a GamePad, they don't see the mouse cursor.
    • Event System - Unity event system. Added manually to support new Input System. Automatycally created event system adds base input that doesn't work with IS.
    • XR UI Input Module - this is a script from UnityEngine.XR.Interaction.Toolkit.UI for mapping XR actions to UI interaction.
    • Controls Reader - this is your script for handling the Input System.
    • Player Input - a script managing the InputSystem configuration. Interestingly, I have to have it disabled in the editor, otherwise it conflicts with the XR UI Input Module, but it still works. Your Controls Reader script finds it and everything works.

    The child objects of "JAGS-SceneStart" generally include AC's MainCamera (and an additional camera for separately displaying UI for VR), which works with both AC's FirstPersonPlayer, which AC initiates from Players prefab, and with my VRPlayer depending on whether the headset is detected.

    I know that when I enter a conversation, the GameState changes from Normal to DialogOptions, and this may influence AC's behavior. I tried to analyze where and when the OnMouseOverMenu event is invoked by AC and only found this:
    In PlayerMenus.cs on line 2200:

    KickStarter.eventManager.Call_OnMouseOverMenuElement (mouseOverMenu, mouseOverElement, mouseOverElementSlot);

    Reading the entire UpdateAllMenus() code and broadly analyzing the behavior, I couldn't understand why OnMouseOverMenu works differently for me in InventoryUI and ConversationUI, and why sometimes OnMouseOverMenu is triggered only by the keyboard and other times only by the mouse. The ConversationUI handling code is based on my InventoryUI handling code and is essentially a few lines of code. However, I open Inventory manually, while Conversation is opened by AC with Appear type = During Conversation.

    OnMouseOverMenu is the only place I can set lastSelectedSlot and I don't know any other way to do it.

    I've done my best to keep everything as simple as possible and interfere with AC's operation as little as possible. However, I'm aware that there are many dependencies here and the problem may not be trivial to solve. Nevertheless, I hope that we will be able to unravel this mystery. I would be grateful for any hints and tips.

  • edited May 2023

    I've conducted a few more experiments. I have the old input system disabled. I removed the XR UI Input Module script from the scene to eliminate any potential conflicts. Thus, I only have the Event System, Controls Reader, and Player Input. When Player Input is enabled, nothing works except for mouse movement and clicking on a Hotspot (via ScreenSpaceHotspotDetection) - I can't select anything from the Interaction Menu by clicking.

    When I disable Player Input, the keyboard works for movement, but interaction with the UI does not.

    With Player Input disabled, I add InputSystemUIInputModule and configure it to work with my Input Actions. Everything begins to function as before the removal of the XR UI Input Module - everything seems to work, but OnMouseOverMenu events are triggered as before - differently in Inventory and Conversation.

    Enabling the Player Input checkbox causes the keyboard to stop working again, and I can once again trigger the interaction menu at a hotspot with the mouse, but I can't confirm any interactions.

    https://imgur.com/Omg9rEn

    The behavior is the same using both InputSystemUIInputModule and XRUIInputModule (from UnityEngine.XR.Interaction.Toolkit.UI).

    I don't understand what's happening here.

  • I've prepared two Menu Managers: a PC version (Unity Prefabs), and a VR version using "Unity UI in scene" with "World Space UI" Canvas render mode. This allows for easy UI customization per platform. Depending on the situation, I load the relevant one

    Swapping out Managers at runtime should be avoided if at all possible - Menu data be transferred into PlayerMenus at runtime. If you change the asset after this point, there'll be a mismatch between the two sets.

    The safest way to do this, if not already, would be to do so in a separate scene that runs before AC itself - and then load the first "AC" scene afterwards.

    I tried to analyze where and when the OnMouseOverMenu event is invoked by AC and only found this:

    There's actually two places it can be called.

    The first, which you've found, is called if the Menu does not use Unity UI - or, if it is, when the mouse is involved.

    The second occurs in the UISlotClick script, which attaches itself to UI Buttons at runtime. This script's OnSelect event handler triggers the event if it was selected using direct navigation.

    When I disable Player Input, the keyboard works for movement, but interaction with the UI does not.

    Movement as in Player movement?

    First-person Player movement reads Horizontal and Vertical inputs - these will need to be defined in your Input Actions asset and enabled. As it looks like you've put these into a separate Action Map, it may be that the Map needs manually enabling.

  • Hi Chris,

    Thanks for the insights regarding the reloading of the Menu Manager. Currently, I only have one scene and I simply detect if VR is active, load the corresponding configuration into the Menu Manager, and then execute "KickStarter.RestartGame (true, 0);". I'll delve into this more once I finish working on the PC version of the UI.

    Indeed, I found an additional OnMouseMenuOver call in UISlotClick, but it doesn't give me much, as the direct-navigation by keyboard works for my menu, but it doesn't work for mouse movement.

    When I mentioned "Movement", I was referring to the movement of the First Person Player, but that's no longer an issue.

    I've managed to fix the PlayerInput configuration - it's enabled and almost everything works perfectly. I missed "Use in control scheme" configuration in most cases.
    When I say that the Conversation Menu and Pause Menu "work perfectly", I mean that the OnMouseOverMenu event is triggered for both keyboard and mouse movement. In the case of mouse movement, when I detect that the "Directly-navigate Menus when paused/Conversations" options are disabled, I select the appropriate element or slot.I've set the Highlight color (mouse hover) for the Button to transparent, which allows the keyboard and mouse navigation to appear as a single 'cursor'.

    This is my OnMouseOverMenu example method (it does not support Interaction menu):

            public void OnMouseOverMenu (AC.Menu menu, MenuElement element, int slot) 
            {
                if (menu == null || element == null)
                {
                    print("Menu or element is null!");
                    return;
                }
    
                print("OnMouseOverMenu " + menu.title + " element: " + element.title + " slot: " + slot);
    
                if (menu.title == inventoryMenuName && element.title == "InventoryBox")
                {
                    // Save info what item was clicked before opening the Interaction menu
                    lastSelectedSlot = slot;
                    if (!AC.KickStarter.menuManager.keyboardControlWhenPaused)
                    {
                        inventoryMenu.Select ("InventoryBox", lastSelectedSlot);
                    }
                }
    
                if (menu.title == "Conversation" && element.title == "DialogueList" && !conversationEnded)
                {
                    lastSelectedSlot = slot;
    
                    if (!AC.KickStarter.menuManager.keyboardControlWhenDialogOptions)
                    {   // if mouse used
                        conversationMenu.Select ("DialogueList", lastSelectedSlot);
                    }
                }
    
                if (menu.title == "Pause")
                {
                    lastSelectedMenuElement = element;
    
                    if (!AC.KickStarter.menuManager.keyboardControlWhenPaused)
                    {   // if mouse over is made by mouse
                        pauseMenu.Select(lastSelectedMenuElement, 0);
                    }
                }
            }
    

    However, the Interaction and Inventory menus only work with keyboard movement. I found out that I have no menu that works for mouse to trigger OnMouseOverMenu in gameState.Normal. So, I enabled the "Pause game when enabled" option for these menus and they start to work correctly, but in the gameState.Paused. I don't think it's a good idea to have Hotspot Interactions Menu opened in a Game Paused state.
    Is there any workaround for this or better approach?

    Lastly, I want to express my sincere thanks for your thoroughness and patience in helping me work through these issues. Your support is greatly appreciated!

  • The Direct-nav in-game Menus? option isn't a per-Menu option - so you'll need to uncheck it if you want to switch over to mouse movement.

    Fundamentally, the Interaction and Inventory menus should both work during gameplay with the mouse - and fire the OnMouseOverMenu. The 3D Demo's interface should be working this way - it may help to temporarily switch over to it (even in another project) to compare with your setup.

    It may also be worth temporarily reverting your Menu Source values to Adventure Creator, so as not to involve Unity UI - as this adds another layer of complexity. I'd recommend checking that the events fire and input is as expected without Unity UI, before re-incorporating into the mix.

    On the topic of Interaction menu navigation: what's your Select Interactions by field set to? If Clicking Menu, then the input/event firing should be as with any other menu. The other options, however, involve a separate input system handled internally.

  • edited June 2023

    Thanks for your response. I've followed your advice and I can see some improvement, but I'm still experiencing some issues.

    Firstly, I have "Select Interactions by" set to "Clicking Menu".

    The suggestion regarding the "Direct-nav in-game Menus?" option was spot on. Now, in GameState.Normal, the Inventory menu is working, but the Interaction menu only partially. I copied the Interaction menu from the "AC_ScreenSpaceHotspotDetection" package. It has two elements: "Interactions" and "InventoryBox". When the keyboard or mouse cursor is over the InventoryBox, everything works well, and the OnMouseOverMenu event is triggered for both. However, for the Interactions element, this event hardly ever triggers: except for when the mouse first enters its area and the keyboard cursor is in the InventoryBox area, in which case it turns out that the Menu Element is null - it doesn't detect the "Interactions" menu element.

    It's even stranger with the Conversation menu, where the OnMouseOverMenu event, for keyboard navigation, is only triggered when the mouse moves outside the area of this menu.
    For mouse event is triggered properly (in the video below, I suggested that it is not working for mouse, but that was my mistake during video editing, sorry).

    Interestingly, when I change the Menu Source to Adventure Creator, everything works as it should in both the Interaction and Conversation menus.

    I have attached a video demonstrating these issues (I did my best to increase the quality a little bit):
    https://youtu.be/YklS7J3zUL4

    Here is the code I use to detect input and set canKeyboardControlMenusDuringGameplay based on it:

    private void AutoSwitchInputMethod()
    {
        if (anyGamepadKeyPressedDetected)
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
            SwitchInputMethod(InputMethod.KeyboardOrController, true);
        }
        else if (Keyboard.current.anyKey.IsPressed())
        {
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = true;
            SwitchInputMethod(InputMethod.MouseAndKeyboard, true);
        }
        else if (isMouseMoveDetected || Mouse.current.leftButton.isPressed || Mouse.current.rightButton.isPressed)
        {               
            KickStarter.playerInput.canKeyboardControlMenusDuringGameplay = false;
            SwitchInputMethod(InputMethod.MouseAndKeyboard, false);
        }
    }
    
    private void SwitchInputMethod(InputMethod newInputMethod, bool keyboardControl)
    {
        if (currentInputMethod != newInputMethod)
        {
            currentInputMethod = newInputMethod;
            JagsUtils.SetInputMethod(newInputMethod);
        }
    
        if (AC.KickStarter.menuManager.keyboardControlWhenPaused != keyboardControl ||
            AC.KickStarter.menuManager.keyboardControlWhenDialogOptions != keyboardControl ||
            AC.KickStarter.menuManager.keyboardControlWhenCutscene != keyboardControl)
        {
            AC.KickStarter.menuManager.keyboardControlWhenPaused = keyboardControl;
            AC.KickStarter.menuManager.keyboardControlWhenDialogOptions = keyboardControl;
            AC.KickStarter.menuManager.keyboardControlWhenCutscene = keyboardControl;
        }
    }
    

    Any further help with these issues would be greatly appreciated!

    Best,
    Barnim

  • Thanks for the details.

    I must apologise, as it looks like a bug with AC is involved here - at least with the Interaction menu. I've recreated the problem with your details, and OnMouseOverMenu indeed doesn't fire if an Interaction element's For fixed icon? option is unchecked.

    To fix this, open up AC's MenuInteraction script, and replace its IsSelectedByEventSystem and IsSelectableInteractable functions (starting around line 706) with the following:

    public override bool IsSelectedByEventSystem (int slotIndex)
    {
        if (fixedIcon)
        {
            if (uiButton)
            {
                return KickStarter.playerMenus.IsEventSystemSelectingObject (uiButton.gameObject);
            }
        }
        else
        {
            if (slotIndex >= 0 && slotIndex < uiSlots.Length && uiSlots[slotIndex].uiButton)
            {
                return KickStarter.playerMenus.IsEventSystemSelectingObject (uiSlots[slotIndex].uiButton.gameObject);
            }
        }
        return false;
    }
    
    public override bool IsSelectableInteractable (int slotIndex)
    {
        if (fixedIcon)
        {
            if (uiButton)
            {
                return uiButton.IsInteractable ();
            }
        }
        else
        {
            if (slotIndex >= 0 && slotIndex < uiSlots.Length && uiSlots[slotIndex].uiButton)
            {
                return uiSlots[slotIndex].uiButton.IsInteractable ();
            }
        }
        return false;
    }
    

    That said, your situation does also involve Input System and custom scripts - so see if those changes are enough to fix that Menu's issue.

    For the Conversation menu, are you getting this behaviour with the default interface's Conversation menu / ConversationUI prefab? What's the result of temporarily removing your script that alters the input method and direct-control options, and testing mouse and keyboard in separate instances of Play mode?

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.