Forum rules - please read before posting.

ScrollWheel deselects dragged item (and causes movement)

edited May 2021 in Technical Q&A

Hi there,
I'm using the scrollwheel to shift my inventory items (which works fine) but when using the scrollwheel while dragging an inventory item, it deselects the dragged item and causes the player to move. The reason I do this is to make it easy to combine an item from one visible "row" of items to an item on another row.

Here's a repro of the problem:
https://1drv.ms/u/s!Amz_vh8OYDX3vN5y6Kd_Qp-LtIy1pA?e=2sxeU6

To reproduce:

  1. Play Scene1 and notice how scrolling the scrollwheel does the same thing as clicking up/down in the inventory (the buttons has their own ShiftInventoryButton component which causes the shifting, and the scrollwheel is listened to by ScrollWheelListener component attached to the GameEngine).

  2. Now drag and drop an inventory item from the inventory menu (holding down the left mouse button) and (before releasing that mouse button) move the scrollwheel. Notice that the selected item is lost (the cursor is reset) and the player now tries to move to the position where the mouse button was released.

Any ideas on how to counteract this behaviour?

Thanks a bunch!

AC 1.73.6
Unity 2021.1.5

Comments

  • I'll take a look and see.

  • edited May 2021

    This is caused by using the scrollwheel to simulate the shift button's "alternative input button", which is causing AC to assume a click has taken place. Instead, update ScrollWheelListener to scroll through inventory directly:

    using UnityEngine;
    using AC;
    
    public class ScrollWheelListener : MonoBehaviour
    {
        const string Input_MouseScrollWheel = "Mouse ScrollWheel";
    
        void Update()
        {
            if (KickStarter.stateHandler.IsInGameplay())
            {
               var scrollWheel = Input.GetAxis (Input_MouseScrollWheel);
                if (scrollWheel < 0)
                {
                    PlayerMenus.GetElementWithName ("Inventory (Unity)", "InventoryBox").Shift (AC_ShiftInventory.ShiftNext, 4);
                }
                else if (scrollWheel > 0)
                {
                    PlayerMenus.GetElementWithName ("Inventory (Unity)", "InventoryBox").Shift (AC_ShiftInventory.ShiftPrevious, 4);
                }
            }
        }
    }
    
  • edited May 2021

    I actually tried that before posting - same result.

    Edit: Oh, it does work (after the fix) - but only if I move to a mouse with an actual scroll wheel... I'm usually using a mouse with a clickable physical button configured to scroll up/down, clicking those buttons to scroll still has the same problem as before. It deselects the item when the button is pressed down, and the player moves when the button is released.

  • Is this even with the "Alternative input button" fields cleared?

    It may be that such clicks are cancelling the drag-and-drop instance.

    You can get a stacktrace to the item's deselection by placing a Debug.Log statement at the end of RuntimeInventory's SetNull function, but try also placing logs in PlayerInteraction's IsDroppingInventory function - which of the condition blocks is causing it to return true?

  • Yes, this is even when the alt input button fields cleared.

    When I press down the scroll button while dragging an item, two things happens:

    1. PlayerInteraction's IsDroppingInventory returns true at 1667, as a result of the following if statement:
      if (KickStarter.settingsManager.InventoryDragDrop && KickStarter.playerInput.GetMouseState () == MouseState.Normal && KickStarter.playerInput.GetDragState () == DragState.Inventory)

    2. PlayerInteraction's IsDroppingInventory gets called with the following stack trace (line nr should map to your source code):
      https://1drv.ms/u/s!Amz_vh8OYDX3vN5-2W7lYrNuncJqsg?e=h8bY3w

  • It's likely coming from PlayerInput's ResetMouseClick function being called - place this in there and let's see the message:

    Debug.Log ("Reset mouse state from " + mouseState);
    
  • As the button is pressed down:
    "Reset mouse state from HeldDown"

    Stack trace:
    https://1drv.ms/u/s!Amz_vh8OYDX3vN8A51FA0TDI0Zh8LA?e=CObw90

  • edited May 2021

    I'm not sure how Unity processes a scrollwheel "click", but it sounds like it's overriding the left-click state.

    Two things to try:

    • Uncheck the Settings Manager's Mouse clicks have default functionality? option, and map an input named InteractionA to "mouse 0", to manually read it.
    • Re-check the above, then map a new input named "Drag" to "mouse 0". Then, in your GameEngine's Player Input component, set the "Drag Input Override" to "Drag".
  • edited May 2021

    Same exact results I'm afraid.

    Here are the new inputs:
    https://1drv.ms/u/s!Amz_vh8OYDX3vN8DSwDXLC77HlX-uw?e=16yHWD

  • To be clear: this is a mouse with extra buttons that simulate the scrollwheel? Or are you mapping them to Unity's input via script? Is there any way this behaviour can be recreated without such a device?

    Let's try determining how Unity reacts to the LMB being held, while this extra button is pressed. In a fresh, non-AC, scene, try this:

    void Update ()
    {
        Debug.Log ("LMB pressed: " + Input.GetMouseButtonDown (0));
    }
    

    Does that cause things to "reset", in that LMB is considered pressed down again?

    If your Input method is set to Mouse And Keyboard, the code block where AC checks the current mouse state is in PlayerInput.cs, lines 294-343 (current release). It may be worth placing Logs in each of the if/else checks to get the best idea of what's going on.

  • edited May 2021

    Yes, this is a mouse with configurable buttons - I'm not mapping them to Unity in any way.

    I tried your experiment and yes - pressing the scroll button actually interrupts the LMB from being pressed. I checked the config and the buttons are mapped to "Cruise" up & down.

    This being a total edge case, I totally get it if you wanna move on from this :)

  • edited May 2021

    If it's possible to determine when the scroll button is being pressed (e.g. "Input.GetMouseButton (3)" or similar), then it should be possible to account for that in an input override, i.e.:

    using UnityEngine;
    using AC;
    
    public class ScrollButtonFix : MonoBehaviour
    {
    
        void Start ()
        {
            KickStarter.playerInput.InputGetMouseButtonDelegate = MyGetMouseButtonDown;
        }
    
        private bool MyGetMouseButtonDown (int button)
        {
            if (button == 0)
            {
                // Check if scroll button is held, return false inside here if so
            }
            return Input.GetMouseButtonDown (button);
        }
    
    }
    
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.