Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Press interaction on a mouse position not working?

Discussion in 'Input System' started by CDF, Jun 9, 2020.

  1. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,324
    So I'm new to this Input System and trying to create an action that occurs when the user presses, holds and releases the mouse (or touch screen).

    I want to take the screen position of the input, convert it to normalized coordinates (-1, 1) and use that value in the "performed" callback. The goal of the action is to move the player left/right depending on where you press/touch on screen. It should also work with gamepads and keyboard as well.

    I thought this might be how to achieve it:
    positionAndPress.png

    Here I have a "Position [Mouse]" action that has a "Press and Release" interaction and a custom "Screen Input" processor to turn the position into the normalized coordinates.

    But I never receive any started, performed, cancelled events. If I remove the "Press" interaction then I receive events, but every time the mouse moves, which is not what I want.

    Can also see I have a game pad and keyboard sending "Move" commands as well. So I'd like to keep mouse position and touch position within the "Move" action.

    Is this not possible? Is there a better/different way I should be doing this?
     
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,324
    Ok, after looking at the internals a bit. This is the wrong approach. It's not actually checking a press, rather, it considers a press if the mouse position magnitude < 0.5. In other words, 0.5 pixels from bottom left corner.

    so not sure how to continue here.
     
  3. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,324
    Ok, think I got it. Had to create a custom composite binding:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.InputSystem;
    3. using UnityEngine.InputSystem.Layouts;
    4. using UnityEngine.InputSystem.Utilities;
    5.  
    6. public class ScreenInputComposite : InputBindingComposite<Vector2> {
    7.  
    8.     #region Fields
    9.  
    10.     [InputControl(layout = "Axis")]
    11.     public int position;
    12.  
    13.     [InputControl(layout = "Button")]
    14.     public int button;
    15.  
    16.     #endregion
    17.  
    18.     #region Public Methods
    19.  
    20.     public override Vector2 ReadValue(ref InputBindingCompositeContext context) {
    21.  
    22.         var positionValue = context.ReadValue<Vector2, Vector2MagnitudeComparer>(position);
    23.         var buttonValue = context.ReadValueAsButton(button);
    24.  
    25.         if (buttonValue) {
    26.  
    27.             float sw = Screen.width / 2;
    28.             float sh = Screen.height / 2;
    29.  
    30.             float x = positionValue.x - sw;
    31.             float y = positionValue.y - sh;
    32.  
    33.             float h = Mathf.Clamp(x / sw, -1, 1);
    34.             float v = Mathf.Clamp(y / sh, -1, 1);
    35.  
    36.             return new Vector2(h, v);
    37.         }
    38.  
    39.         return Vector2.zero;
    40.     }
    41.  
    42.     public override float EvaluateMagnitude(ref InputBindingCompositeContext context) {
    43.  
    44.         var buttonValue = context.ReadValueAsButton(button);
    45.  
    46.         return buttonValue ? 1 : 0;
    47.     }
    48.  
    49.     #endregion
    50.  
    51.     #region Private Methods
    52.  
    53. #if UNITY_EDITOR
    54.     [UnityEditor.InitializeOnLoadMethod]
    55.     static void RegisterEditor() {
    56.  
    57.         Register();
    58.     }
    59. #endif
    60.  
    61.     [RuntimeInitializeOnLoadMethod]
    62.     private static void Register() {
    63.  
    64.         InputSystem.RegisterBindingComposite<ScreenInputComposite>();
    65.     }
    66.  
    67.     #endregion
    68. }
    69.  
    composite_1.png composite_2.png
    So now I can use the "Press" interaction correctly and receive the position in normalized coordinates :)