Input SystemはuGui上の画像をタッチするとInput Action上で入力を検知する他入力装置と置き換える形で入力を受け付けるようになるOn-Screen StickコンポーネントとOn-Screen Touchがあります。
Input Systemのインストールや使い方は以下のページをご確認ください。
On-Screenコンポーネント
uGuiにOn-Screen Stickコンポーネントを追加するとタッチで画像が上下左右斜めにMovement Rangeの分だけ動くようになります。また、Control Pathで指定したデバイスを選択することで、Input Action上からは、あたかもそのデバイスからの入力を受け付けたかのように動くようになります。
また、uGuiにOn-Screen Touchコンポーネントを追加すると、Control Pathで指定したデバイスを選択することで、Input Action上からは、あたかもそのデバイスからの入力を受け付けたかのように動くようになります。


例えばこの場合、On-Screen Buttonにマウスの右クリックを設定しています。併せてInput Actionアセットでは、アクション「Fire」にマウスの右クリックを設定します。そのため、On-Screen Buttonコンポーネントを追加した画像をタップすると、アクション「Fire」が実行されます。
どちらも、Buttonである必要はありません。例えば次はどちらもuGuiのImage画を使用しています。(左がStickで右がButton)

Control PathはuGuiを動かすEventSystemのInput System UI Input ModuleコンポーネントのInspectorで設定したAction Asset内のアクションで設定したデバイス操作を選択しなければいけません。
上記On-Touch StickコンポーネントはGamePadの左スティックを選択しており、InputActionでGamePadの左スティックはアクション「Move」の入力受付となっているため、「Move」のVector2を受け取るとOn-Touch Stickの動きを取得することができます。
On-Screen Touchコンポーネントはマウスの右クリックを選択しており、InputActionでマウスの右クリックはアクション「Fire」の入力受付となっているため、「Fire」をisTriggerで取得すると、ボタンがタッチスクリーンされた時を感知します。
自作On-Screenコンポーネントの作成
下記はOn-Screen Buttonと同じ効果があるコンポーネントです。
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.OnScreen;
using UnityEngine.InputSystem.Layouts;
public class OnScreenMy : OnScreenControl, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
[InputControl(layout = "Button")]
[SerializeField]
private string _controlPath;
protected override string controlPathInternal
{
get => _controlPath;
set => _controlPath = value;
}
public void OnPointerUp(PointerEventData eventData)
{
SendValueToControl(0.0f);
}
public void OnPointerDown(PointerEventData eventData)
{
SendValueToControl(1.0f);
}
public void OnDrag(PointerEventData eventData)
{
}
}
On-Screenで必要なのは、controlPathInternalに与えている値がInspectorで選択したコントロールに置き換わる形で常に与えられている点です。
[InputControl(layout = "Button")]
[SerializeField]
private string _controlPath;
protected override string controlPathInternal
{
get => _controlPath;
set => _controlPath = value;
}
値はSendValueToControlで与えられます。
SendValueToControl(1.0f);
クラス名はOnScreenとなっていますが、上記コードの通り、実際はSendValueToControlに値を入れればよいだけのため、ヴァーチャルパッドだけでなく、他のことでも扱えそうです。