Input Detector
Writing a custom Input Detector
If you use an Input System that is not supported, you can write a custom Input Detector. The only requirement is that the Input System has an Input Module (otherwise you also need to write that).
After writing a custom Input Detector, you may also want to write a custom Input Module Addition, which is pretty easy.
You can use the following pseudo-C#-code as a starting point:
using TheraBytes.BetterUi;
using UnityEngine;
using InputActionType = TheraBytes.BetterUi.InputActionType;
public class MyInputDetector : BaseInputDetector<MyActionMap, MyInputModule>, IInputDetector
{
static bool lastInputWasGamepad;
public override float InitialRepeatDelay { get { return inputModule.moveRepeatDelay; } } // <- probably not working
public override float ConsecutiveRepeatDelay { get { return inputModule.moveRepeatRate; } } // <- probably not working
protected override MyActionMap Submit => InputModule.submit; // <- maybe not working
protected override MyActionMap Cancel => InputModule.cancel; // <- maybe not working
public override bool LastInputWasGamepad => lastInputWasGamepad;
Vector2 previousPointerPosition;
public MyInputDetector(MyInputModule inputModule)
: base(inputModule)
{
}
public override void UpdateCurrentNavigationData()
{
base.UpdateCurrentNavigationData();
// here you may be able to set the value for "lastInputWasGamepad"
// if not, you would need to set it in the "Handle...()" methods.
// But you only need to set it, if you are also using it in your game.
// Better UI does not use "lastInputWasGamepad" at all.
}
protected override MyActionMap HandleKeyboardAndGamepad(out Vector2 direction)
{
direction = new Vector2();
if (IsActionPressed(inputModule.submit))
return InputActionType.Submit;
if (IsActionPressed(inputModule.cancel))
return InputActionType.Cancel;
direction = inputModule.GetNavigationMoveDirection(); // <- probably not working
if (direction.x != 0 || direction.y != 0)
{
return InputActionType.NavigateInAnyDirection;
}
return InputActionType.None;
}
protected override InputActionType HandleMouseAndTouch()
{
if (IsActionPressed(inputModule.leftClick))
{
return InputActionType.Submit;
}
var prev = previousPointerPosition;
var pos = inputModule.GetPointerPosition(); // <- probably not working
previousPointerPosition = pos;
if (pos != prev && prev != Vector2.zero)
{
return InputActionType.PointerPositionChanged;
}
return InputActionType.None;
}
bool IsActionPressed(MyActionMap action)
{
// determine somehow if the input for the action is held down this frame (check for being down, not "became pressed this frame")
return action.IsPressed; // <- probably not working
}
}
What you would need to do:
- rename the class if you want (should have the same name as its file)
- replace "MyActionMap" with the type that your input system is using for input mapping
- replace "MyInputModule" with the input module of your input system
- Implement "IsActionPressed()" and adjust all other code parts which are commented with "probably not working" (or "maybe not working")
- If you need "LasInputWasGamepad" in your game, implement it somehow (if you don't need it, you don't need to implement it)
Register the Detector
To let Better Navigation use this input detector, you need to register it. It must be registered before Better Navigation Awakes, so you may need to adjust the Script Execution Order of the class that does the registration (e.g. by adding an attribute above the class [DefaultExecutionOrder(-1000)]).
Here is the registration code.
BetterNavigation.InputDetectorsForInputModulesFactories.Add(typeof(MyInputDetector),
(inputModule) => new MyInputDetector(inputModule as MyInputModule));
What you would need to do:
- Replace "MyInputDetector" with the type of your class
- Replace "MyInputModule" with the type of the input system's input module