Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug OnScreenControl.SendValueToControl does not trigger Action [2019.4.3f1]

Discussion in 'Input System' started by fritzelr, Jul 29, 2020.

  1. fritzelr

    fritzelr

    Joined:
    Oct 6, 2015
    Posts:
    1
    I have created a simple clone of OnScreenStick to customize its behavior to suit my purposes. I am finding that calling SendValueToControl does not trigger the corresponding Action setup in my PlayerInput.

    I have set the control path of the joystick to Gamepad/LeftStick:



    I am testing this on my PC with a keyboard&mouse. I do not have a gamepad connected. Here is the Move action which I expect to fire:



    I am using the "Unity Events" configuration of PlayerInput on my Player object to handle the Move action. I can confirm that pressing WASD properly fires the action, but calling SendValueToControl from the OnScreenStick does not. Here is my OnScreenJoystick code, which is nearly identical to the OnScreenStick code:

    Code (CSharp):
    1. using UnityEngine.EventSystems;
    2. using UnityEngine.Serialization;
    3. using UnityEngine.InputSystem.Layouts;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem.OnScreen;
    6. using UnityEngine.InputSystem;
    7.  
    8. public class OnScreenJoystick : OnScreenControl, IPointerDownHandler, IPointerUpHandler, IDragHandler
    9. {
    10.     private float m_MovementRange;
    11.  
    12.     public float movementRange
    13.     {
    14.         get => m_MovementRange;
    15.     }
    16.  
    17.     [InputControl(layout = "Vector2")]
    18.     [SerializeField]
    19.     private string m_ControlPath;
    20.  
    21.     [SerializeField]
    22.     private GameObject joystickBoundsImageTemplate;
    23.     private GameObject joystickBoundsImage;
    24.  
    25.     [SerializeField]
    26.     private GameObject joystickCenterImageTemplate;
    27.     private GameObject joystickCenterImage;
    28.  
    29.     private Vector2 m_PointerDownPos;
    30.  
    31.     protected override string controlPathInternal
    32.     {
    33.         get => m_ControlPath;
    34.         set => m_ControlPath = value;
    35.     }
    36.  
    37.     private void OnEnable()
    38.     {
    39.         if (joystickBoundsImageTemplate == null)
    40.             throw new System.ArgumentNullException(nameof(joystickBoundsImageTemplate));
    41.  
    42.         if (joystickCenterImageTemplate == null)
    43.             throw new System.ArgumentNullException(nameof(joystickCenterImageTemplate));
    44.  
    45.         FillScreen();
    46.     }
    47.  
    48.     public void FillScreen()
    49.     {
    50.         Rect parentRect = (transform.parent as RectTransform).rect;
    51.         ((RectTransform)transform).SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, parentRect.width);
    52.         ((RectTransform)transform).SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, parentRect.height);
    53.     }
    54.  
    55.     public void OnPointerDown(PointerEventData eventData)
    56.     {
    57.         if (eventData == null)
    58.             throw new System.ArgumentNullException(nameof(eventData));
    59.  
    60.         RectTransformUtility.ScreenPointToLocalPointInRectangle(
    61.             transform.parent.GetComponentInParent<RectTransform>(),
    62.             eventData.position,
    63.             eventData.pressEventCamera,
    64.             out m_PointerDownPos
    65.         );
    66.  
    67.         Debug.Log($"Pointer down at {m_PointerDownPos}");
    68.  
    69.         if (joystickBoundsImage == null)
    70.             joystickBoundsImage = Instantiate(joystickBoundsImageTemplate, transform);
    71.         ((RectTransform)joystickBoundsImage.transform).anchoredPosition = m_PointerDownPos;
    72.         joystickBoundsImage.SetActive(true);
    73.  
    74.         if (joystickCenterImage == null)
    75.             joystickCenterImage = Instantiate(joystickCenterImageTemplate, transform);
    76.         ((RectTransform)joystickCenterImage.transform).anchoredPosition = m_PointerDownPos;
    77.         joystickCenterImage.SetActive(true);
    78.  
    79.         Rect bounds = ((RectTransform)joystickBoundsImage.transform).rect;
    80.         m_MovementRange = Mathf.Min(bounds.width, bounds.height) / 2;
    81.     }
    82.  
    83.     public void OnDrag(PointerEventData eventData)
    84.     {
    85.         if (eventData == null)
    86.             throw new System.ArgumentNullException(nameof(eventData));
    87.  
    88.         Debug.Log($"OnDrag");
    89.  
    90.         RectTransformUtility.ScreenPointToLocalPointInRectangle(
    91.             transform.parent.GetComponentInParent<RectTransform>(),
    92.             eventData.position,
    93.             eventData.pressEventCamera,
    94.             out var position
    95.         );
    96.  
    97.         Debug.Log($"Dragged to {position}");
    98.         var delta = position - m_PointerDownPos;
    99.  
    100.         delta = Vector2.ClampMagnitude(delta, movementRange);
    101.         ((RectTransform)joystickCenterImage.transform).anchoredPosition = m_PointerDownPos + delta;
    102.  
    103.         var newPos = new Vector2(delta.x / movementRange, delta.y / movementRange);
    104.         Debug.Log($"Sending position to control: {newPos}");
    105.         SendValueToControl(newPos);
    106.     }
    107.  
    108.     public void OnPointerUp(PointerEventData eventData)
    109.     {
    110.         if (joystickCenterImage != null)
    111.             joystickCenterImage.SetActive(false);
    112.        
    113.         if (joystickCenterImage != null)
    114.             joystickBoundsImage.SetActive(false);
    115.  
    116.         SendValueToControl(Vector2.zero);
    117.         Debug.Log($"Pointer up at {m_PointerDownPos}");
    118.     }
    119.  
    120. }
    In the Input Debugger, I do not see a gamepad device, which leads me to believe perhaps the OnScreenControl is not correctly creating a virtual gamepad device:



    Here's the PlayerInput configuration for reference:



    From what I can tell, OnScreenStick is broken. I have been wrestling with the new Input System for days. Is there something I'm doing wrong?
     
  2. CFodder1977

    CFodder1977

    Joined:
    Nov 18, 2018
    Posts:
    7
    Did you ever get an answer to this? I am having the same issue. When using the On-Screen Stick component, setting the "Control Path" to "Left Stick [Gamepad]" and having a "Left Stick [Gamepad]" defined as one of the bindings for my "Move" action would logically mean that this would trigger a CallbackContext, thus allowing me to utilize it to invoke any Unity events I have defined under my "Move" CallbackContext section of my Player Input component. However, no such luck. The Left Stick inputs are definitely being sent to the input system (because I am using them to read their Vector2 components via a non-CallbackContext method). However, they are definitely not being recognized through the CallbackContext system via SendValueToControl.

    I don't believe that the issue resides with the On-Screen Stick component. I hooked up a controller and it will not trigger the CallbackContext routine regardless of pairing it with the On-Screen Stick component. From what I can tell, the only thing I can get to work with CallbackContext are direct key presses on a keyboard without incorporating SendValueToControl.
     
    Last edited: Nov 19, 2020
  3. dreamCirno

    dreamCirno

    Joined:
    May 16, 2018
    Posts:
    20