Open taylorstine opened 3 years ago
I'm binding my action with InputActionType.PassThrough
param and then just have this little piece:
public static partial class Extensions {
public static IObservable<InputAction.CallbackContext> ToObservable(this InputAction action) =>
Observable.FromEvent<InputAction.CallbackContext>(
h => action.performed += h,
h => action.performed -= h
);
}
You can add type param there (make it generic) and read value accordingly, or just use it separately, because single responsibility and you know. So, let's say you need bool out of some 1D axis:
myAction.ToObservalbe()
.Select(context => context.ReadValue<float>() != 0)
I had the same idea (although I would call it PerformedAsObservable
).
However, my problem is that the removeHandler is never called: inputAction.performed -= h
. I guess this makes sense because it is not bound to any IDisposable.
Can I tell UniRx somehow to call the removeHandler on scene change?
Well, I guess one solution is to call the removeHandler in OnDestroy of some GameObject. I already have an InputManager
in every scene. Thus, my solution is
public static class InputActionExtensions
{
public static IObservable<InputAction.CallbackContext> PerformedAsObservable(this InputAction inputAction)
{
Action<Action<InputAction.CallbackContext>> removeHandler = h => inputAction.performed -= h;
Action<Action<InputAction.CallbackContext>> addHandler = h =>
{
inputAction.performed += h;
InputManager.Instance.OnDestroyAsObservable().Subscribe(_ => removeHandler(h));
};
return Observable.FromEvent<InputAction.CallbackContext>(addHandler, removeHandler);
}
}
There is a helper method for removing the handler:
UniRx.DisposableExtensions.AddTo
.
You use it like this:
protected void Start()
{
SomeModel.OnEventObservable().Subscribe(value => ...).AddTo(this);
}
So when the Monobehaviour is destroyed, the handler will be removed.
Thank you folks for this post, it helped me achieve the same thing but slightly modified, in case someone wants to read it I just wrote an answer to a post in Reddit https://www.reddit.com/r/Unity3D/comments/qeugyw/somebody_tried_use_unirx_with_input_system/
would love to have an out-of-the-box way to do this via uniRX tho
I created a lib with my solution: https://github.com/achimmihca/PrimeInputActions
It is Unity's InputActions with UniRx and a priority queue.
I would like to use UniRx with Unity's new Input System. Maybe the API would look something like this:
Is there a suggested way to do this?