Having trouble migrating from legacy UI to UI Toolkit with the Input Sysyem

Hello everyone,

I’ve searched the forum quite a bit, but i still can’t find a definitive answer or a good resource that can point me in the right direction.

As you can see from the image, i have an old canvas with a “Jump” button, upon which i added an On-Screen Button component. This, combined with the new Input System, has been used as a propotype on-screen mobile control system and so far it works.

The Input System also is the simplest one i could make:

I have this snippet of code in my player controller that recieves the message from the Input System and acts accordingly:

public class PlayerController : MonoBehaviour, PlayerControls.IPlayerActions, PlayerControls.IMenuActions
{
    private PlayerControls controls;
[...]
    public void OnJump(InputAction.CallbackContext context)
    {
        if (context.started && !isKnockedOut)
        {
            jumpRequested = true;
            jumpButtonBeingPressed = true;
        }
        else if (context.canceled)
        {
            jumpButtonBeingPressed = false;
        }
[...]
    private void Start()
    {
        controls = new PlayerControls();
        controls.Player.SetCallbacks(this);
        controls.Menu.SetCallbacks(this);

    }
}

Now, i’m migrating this simple UI to the UI Toolkit. What i’ve understood so far is, I have to create a component, attach it to the UIDocument object, and from there i get a reference to the button in the document (it’s what I’ve done for the main menu so far).
I need to make it so that the On-Screen Button behaviour is reproduced, so that when I press and release the button the input system event is triggered and OnJump is called on the playerController

I’m honestly completely stumbled here, I can’t find any way to do this properly and any help would be massively appreciated. I have the feeling I’m doing this all wrong, but I genuinely have no idea how to move on with this…

Thanks everyone!

Hi,

yes, this is unnecessarily hard to do. AFAIK there still is no simple API for triggering input events except using the test framework. Why someone inside Unity thought that triggering actions is something that’s only needed during testing is beyond me.

I have attached a working example for you.
Key steps are:

  1. Inherit from OnScreenControl (Source 1 and 2) and add this inherited component to your UIDocument.
  2. Configure one of these components for each control you want to trigger (yeah, this sucks).
  3. Register an event to your UI Toolkit button.
  4. Use Trigger() on the component.

If you are interested you could take a look into what the OnScreenButton does (source) and trigger the same behaviour manually. Though beware, some of the stuff in there is internal and you would need reflections. Unity has done a “great” job closing up all their new APIs so it’s incredibly hard to extend any of them. It’s very frustrating.

Key part is this (OnScreenControlTrigger inherits from OnScreenControl):

#if ENABLE_INPUT_SYSTEM
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.OnScreen;

public class OnScreenControlTrigger : OnScreenControl
{
    public string ControlPath;
    public float Value = 1f;

    protected override string controlPathInternal
    {
        get => ControlPath;
        set => ControlPath = value;
    }

    public void Trigger()
    {
        if (!string.IsNullOrEmpty(ControlPath))
            StartCoroutine(triggerEvent());
    }

    private IEnumerator triggerEvent()
    {
        yield return null;
        SentDefaultValueToControl();

        yield return null;
        SendValueToControl<float>(Value);

        yield return null;
        SentDefaultValueToControl();
    }
}
#endif

9254379–1294302–_UIToolkitNewInputSystem.unitypackage (6.28 KB)

1 Like

This is exactly what I was looking for, that’s amazing! Thank you so much!

And I do agree, while I’m loving both the freedom and ease of use of the UI Toolkit system and the new Input System, it is unnecessarily hard to get a proper integration between the two of them when it comes to mobile on screen controls. Hopefully this will improve in the near future!

Thanks again!