how do you make a custom interaction that filters out most event send?

I tried this bit of code which should only let Started() pass through but instead no event is being fired. So what’s the secret sauce?

// Interaction which only sends one event on DOWN
using UnityEngine.InputSystem;
using UnityEngine;

public class UIInputDownInteraction : MonoBehaviour
{
    [ContextMenu("Register")]
    public void Register()
    {
        InputSystem.RegisterInteraction<OnDownInteraction>();
    }
}
public class OnDownInteraction : IInputInteraction
{
    public void Process(ref InputInteractionContext context)
    {
        switch (context.phase)
        {
            case InputActionPhase.Started:
                context.Started();
                break;
        }
    }

    public void Reset()
    {
    }
}

6787175--786194--upload_2021-1-31_23-2-51.png
in PlayerInput/Events/UI
6787175--786197--upload_2021-1-31_23-8-41.png
if I remove this custom interaction then all returns to “normal” where that event it fired 3 times so this part of the setup seems correct.

6787175--786191--upload_2021-1-31_22-55-25.png

If no interaction is added, the built-in “default interaction” kicks in. If an interaction is added, it takes over and gets control over the phases of the action.

This basically says “if the action has been started, start the action”. Which is why it does nothing. Comes down to the above thing of the interaction driving the phases.

Taking a look at TapInteraction.Process() may be helpful. In a way, the interaction “filters” out anything in-between the press and release.

Ok I still don’t understand everything about it, for example it’s unclear which method calls the Down event in InputAction, out of the 3 events.
I wrangled something anyway but as I was about to test it I noticed the OnDown disappeared from the action menu, it seems that registering no longer works. I based it on the input system github.

// Interaction which only send one event on DOWN
using UnityEngine.InputSystem;
using UnityEngine;
using UnityEngine.Scripting;

#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif

[Preserve]
public class OnDownInteraction : IInputInteraction
{
    public void Process(ref InputInteractionContext context)
    {
        if (context.isWaiting && context.ControlIsActuated(0.5f))
            context.Started();
    }

    public void Reset()
    {
    }

    static OnDownInteraction()
    {
        InputSystem.RegisterInteraction<OnDownInteraction>();
    }

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void Initialize()
    {
        InputSystem.RegisterInteraction<OnDownInteraction>();
    }
}
1 Like

Agreed, registering custom interactions doesn’t seem to work at the moment.

verify that you don’t have 2 register, for some reason it breaks the first register … silently
now that register works @Rene-Damm the interaction still emits 3 events and I don’t understand how your interactions filter things out so what’s the solution?

1 Like

Thanks, I’ll try and find the other register then.