Forum rules - please read before posting.

Intercept mouse click

Is it possible to intercept from script mouse click? 
When the player presses the right or left mouse button I should do some actions. Later, however, I should not block the default mouse click activity.
For example, the player right-click to deselect item, I would need to do a script action and then let the item deselect.
I'm working in a custom event, GetItemClick, but I have to intercept the click also out of the inventory.

Comments

  • edited October 2017
    To block mouse clicks, or control how and when AC detects them, use custom input overrides - also see the "Remapping inputs" chapter of the Manual.

    The "InputGetMouseButtonDown" override, when defined, causes AC to refer to this when checking for mouse clicks instead of Unity's Input.GetMouseButtonDown.  You can then return Unity's function in normal circumstances, but then just return false if you want clicks to be ignored.
  • edited October 2017
    Sorry Chris but I just can not understand how to use the custom input overrides.
    I have searched everywhere but clear examples I have not found.

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

    public class CE_MoveItemOverrideClick : MonoBehaviour {

    public int checkBtnPressed = 1;

    void Start () {
    KickStarter.playerInput.InputGetMouseButtonDownDelegate = CustomInputGetMouseButtonDownDelegate;
    }

    private bool CustomInputGetMouseButtonDownDelegate (int btnPressed) {

    Debug.Log (btnPressed);

    if (btnPressed == checkBtnPressed) {
    Debug.Log ("Button 1 pressed");
    }
    return true; //Input.GetMouseButtonDown (MouseBtnPressed);
    }

    }

    If I put this script on a gameobject what i get is:
    an infinite series of 0 (zero) returned by Debug.Log (btnPressed)
    the character follows the mouse (without click) as if the Movement method was set to Direct while instead it is Point And Click.
    Keep in mind that I removed all my code to make sure it did not interfere.
    Perhaps I have to define inputs or other preliminary operations?

    Video





  • AC is checking for the various button clicks continously, as any input should be.

    The input check, and hence your delegate override, is being asked if a given button index (int btnPressed) is being pressed.

    Your override returns "true" in all cases, meaning you are telling AC that any mouse button click it is checking for (left and right) is being held down.

    Replacing the "return true;" with:

    return Input.GetMouseButtonDown (btnPressed);

    Will have normal mouse-based behaviour return, but with the ability to detect if the RMB (button 1) is being clicked.

    If you then wanted to override it, you could insert eg:

    if (btnPressed == checkBtnPressed && someCondition)
    {
      // Don't accept RMB clicks at this time
      return false;
    }
    return Input.GetMouseButtonDown (btnPressed);
  • edited October 2017
    Thanks Chris, now I think I understand.
    So to be clear, if I want to intercept the mouse click of both buttons while an item is selected i will use in CustomInputGetMouseButtonDownDelegate 

    if (KickStarter.runtimeInventory.SelectedItem != null) {
    return false;
    }

    and in Update()

    if (Input.GetMouseButtonDown (1) && KickStarter.runtimeInventory.SelectedItem != null) {
    StartCoroutine (execCursorBack ());
    }
    else if (Input.GetMouseButtonDown (0) && KickStarter.runtimeInventory.SelectedItem != null  && KickStarter.runtimeInventory.MatchInteractions().Count > 0) {
    StartCoroutine (execCursorBack ());
    KickStarter.playerInteraction.UseInventoryOnHotspot (KickStarter.playerInteraction.GetActiveHotspot (), itemSel, false); 
    }

    In Coroutine I did some actions and I close it with

    KickStarter.runtimeInventory.SetNull ()

    Is this the right way to use the override?
    A question, would not be possible, to avoid manually closing the click event with SetNull () or UseInventoryOnHotspot () to simulate (after my line of code) a simple "Return Input.GetMouseButtonDown (BtnPressed)" leaving it your code to perform the correct operations?
  • That's the correct way to block using the override.

    Generally, you can have AC perform its default behaviour by returning the Unity Input function - as I showed above.  As you're using coroutines and so on, though, I can't say for sure how appropriate that would be - but I don't imagine you need to use an Update function.

    AC will check for the RMB every frame anyway, so you should be able to just put it all in the override function, e.g.:

    if (KickStarter.runtimeInventory.SelectedItem != null)
    {
      if (btnPressed == 1)
      {
        // Do something
      }
      else if (btnPressed == 0)
      {
        // Do something else
      }
      return false; // Remove this to have AC always perform the default functionality
    }
    return Input.GetMouseButtonDown (btnPressed);

  • edited October 2017
    Thanks Chris, but this is where I get into confusion and I do not understand if and where I'm wrong. What you suggest is the first thing I tried.

    private bool CustomInputGetMouseButtonDownDelegate (int BtnPressed) {

    if (KickStarter.runtimeInventory.SelectedItem! = null) {
    if (BtnPressed == 1) {
    Debug.Log (BtnPressed);
    }
    else if (BtnPressed == 0) {
    Debug.Log (BtnPressed);
    }
    return false;
    }
    return Input.GetMouseButtonDown (BtnPressed);
    }

    What I get, even with "return false" commented, are 0 and 1 alternating in the console (just I pick a item).
    This means my code would run repeatedly, so I thought about using Update ().
    As you said, AC is checking for the various button clicks continously and this explains why the function comes with a series of 0 and 1 alternates.
    But then what is the purpose of
    if (BtnPressed == 0 or 1)?
    as it would seem that btnPressed is always 0 or 1 every alternate frame without any mouse clicks.
    So I can not understand how and where to place my code directly into the override function, I am going crazy!
    Where am I wrong?
  • edited October 2017
    BtnPressed = 0 / 1 is checked for every frame as you say - but it's only if the return value is True that it makes any difference.  That the function is being called repeatedly is not important, only the result it returns.

    I don't feel like I have a clear picture of what it is you're actually trying to do as a result of all this - I think that's making it difficult to assist.

    If your custom behaviour lasts several frames / update cycles, using a coroutine is fine - but then just add a bool check to the override that you can set in that coroutine, e.g.:

    bool doNothing;

    private bool CustomInputGetMouseButtonDownDelegate (int BtnPressed)
    {
      if (doNothing) return false;
      // rest of function will not run if doNothing = True
    }

    private IENumerator execCursorBack ()
    {
      doNothing = true;
      // other stuff over time
      doNothing = false
    }

  • What I want to do is difficult to explain (using Update () +  Coroutine it works fine but I'm trying to figure out if I can directly use the override function as you suggested).
    To make it simple I would like to do this:
    1) I select an inventory item
    2) When I click the right button I would like to suspend it momentarily to perform some actions before the item is deselected.
    3) Once I did my actions, I'd like right click to proceed to deselect the item.
    Using your code as a reference I thought it would work.

    private bool CustomInputGetMouseButtonDownDelegate (int btnPressed) {
    if (KickStarter.runtimeInventory.SelectedItem != null)
    {
      if (btnPressed == 1)
      {
        mousePos = KickStarter.playerInput.GetMousePosition ();
        var newY = mousePos.y - menuTarget_Y;
        useVector = new Vector2 (mousePos.x, newY);
        CursorControl.SetLocalCursorPos (useVector);
      }
      else if (btnPressed == 0)
      {
        // Do something else
      }
      // return false; // Remove this to have AC always perform the default functionality
    }
    return Input.GetMouseButtonDown (btnPressed);
    }

    One of my actions is to restore the cursor position I had changed at the select item (I use a simple asset Cursor Control).
    From this code I would have expected that after executing my code, as I commented "return false", AC performed the default functionality through "Return Input.GetMouseButtonDown (btnPressed)" by calling SetNull ().
    Instead, the code is executed repeatedly and the cursor is pushed continuously down the screen.




  • edited October 2017
    Right.  Sorry!  I was having a brain-fart.

    So, the function is used to detect if a certain button is pressed - and the btnPressed parameter is merely used to determine which button is being checked.  But since the function itself is used to determine if the input is pressed, it must also incorporate the Input function:

    Change:
    if (KickStarter.runtimeInventory.SelectedItem != null)

    to:
    if (KickStarter.runtimeInventory.SelectedItem != null && Input.GetMouseButtonDown (btnPressed))

    That then makes the code only run if an item is selected, and that the requested button is indeed being held down.  Otherwise, it doesn't care if it's clicked or not.

    Apologies for not seeing that sooner.
  • edited November 2017
    Thanks Chris, in order to avoid having to handle all the clicks, I restricted override to the right button for the deselect item and the left button for hotspot operations. Everything else will be handled by your code.

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.