I faced the same issue and found some other solution that could solve it, so probably it will be helpful for someone.
Used unity version: 2022.2.
First of all I need to say that I’m using input actions (new input system) not an input manager.
My input actions looks like this:
You also should have an EventSystem on your Project Hierarchy. Probably you already have one if you add a Canvas or some UI element.
I need to mention that I didn’t change an EventSystem or its properties, except of just applying ‘Input System UI Input Module’, so it looks like this:
My Canvas has a ‘DPad’ GameObject with 4 buttons (up, left, right and down).


DPad object has a ‘DPadController’ script as a component.
public class DPadController : MonoBehaviour
{
[SerializeField] private EventSystem eventSystem;
private GameObject _lastPressedButton;
private Dictionary<string, GameObject> _customPointerUpEventCalls;
public void Awake()
{
_customPointerUpEventCalls = new Dictionary<string, GameObject>();
}
public void PointerDown(GameObject pressedButton)
{
_lastPressedButton = pressedButton;
}
public void PointerEnter(GameObject pressedButton)
{
if (!_lastPressedButton)
{
return;
}
_customPointerUpEventCalls.TryAdd(_lastPressedButton.name, _lastPressedButton);
ExecuteEvents.Execute(_lastPressedButton,
new PointerEventData(eventSystem), ExecuteEvents.pointerUpHandler);
ExecuteEvents.Execute(pressedButton,
new PointerEventData(eventSystem), ExecuteEvents.pointerDownHandler);
_lastPressedButton = pressedButton;
}
public void PointerUp(GameObject pressedButton)
{
if (_customPointerUpEventCalls.ContainsKey(pressedButton.name))
{
// remove and do nothing because we already called 'up event' earlier in PointerEnter
_customPointerUpEventCalls.Remove(pressedButton.name);
return;
}
if (!_lastPressedButton)
{
return;
}
_customPointerUpEventCalls.TryAdd(_lastPressedButton.name, _lastPressedButton);
ExecuteEvents.Execute(_lastPressedButton,
new PointerEventData(eventSystem), ExecuteEvents.pointerUpHandler);
_lastPressedButton = null;
}
}
As you see you would need to attach EventSystem to an appropriate variable in UnityEditor.
In this script, methods are just ordinary methods (not events) and are called from ‘DPadButtonController’ script.
In DPadController we are saving last pressed button in ‘PointerDown’ method and if we enter some new button area (during already pressed event) then we explicitly call ‘PointerUp’ event on last pressed button, mark it as our own custom event invocation and call ‘PointerDown’ on newly entered button. We need to mark custom event invocation because otherwise the ‘PointerUp’ method will be called indefinitely.
Each of the movement buttons has a ‘DPadButtonController’ script as a component.
public class DPadButtonController : MonoBehaviour,
IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler
{
[SerializeField] private GameObject dpadControllerObject;
private DPadController _dpadController;
public void Awake()
{
_dpadController = dpadControllerObject.GetComponent<DPadController>();
}
public void Start()
{
// to make buttons clickable only where image is
GetComponent<Image>().alphaHitTestMinimumThreshold = 0.1f;
}
public void OnPointerDown(PointerEventData eventData)
{
_dpadController.PointerDown(gameObject);
}
public void OnPointerUp(PointerEventData eventData)
{
_dpadController.PointerUp(gameObject);
}
public void OnPointerEnter(PointerEventData eventData)
{
_dpadController.PointerEnter(gameObject);
}
}
In order ‘DPadButtonController’ script to work you would need to attach DPad GameObject to an appropriate variable in UnityEditor. And here we have only DPadController’s method invocations.
Hope it was helpful.