First of all I am sooo happy Iāve stumbled on your post. I have been trying to understand the provided examples for days now and your not quite working code was exactly what I needed. I managed to do everything I needed in minutes!
To show my gratitude I would like to offer you some shaky explanation written by a guy with one year of c# experience.
Anyway you have probably figured it out yourself by now, but perhaps others are interested. Anyway here it goes:
First problem with your code (and probably the origin for your debug needs) you donāt deactivate your action while rebinding it. An action cannot be rebound while it is in use, since it would cause uncertainty.
It probably threw you a similar error to this:
InvalidOperationException: Cannot rebind action 'Player/Jump[/Keyboard/space]' while it is enabled
UnityEngine.InputSystem.InputActionRebindingExtensions+RebindingOperation.WithAction (UnityEngine.InputSystem.InputAction action) (at wherever your class is)
Solution is easy, just disable it before the rebinding with:
m_Action.action.Disable();
and re enable it with:
m_Action.action.Enable();
Edit:
You can detect when the rebinding is complete with:
if(rebindOperation.completed)
Now the second question. Why dose your Debug.Log() trigger before completion. I donāt have a nice answer, but in my limited understanding it boils down to the following:
The command isnāt really a step like int i=1+1;
but more like a MonoBehaviour similar to Invoke(someFunction, someTimeLater);
that triggers every once in a while and checks for inputs that satisfy the parameters.
Basically you mistake the rebind being complete when in fact it is still running (or already legitimately completed).
Since I have a similar base code to you I would like to use this chance to post a working script, that might use some optimization regarding the reactivation of the action. (btw. dose that ām_ā before Action mean something? cause I just use Action as a public variable)
using UnityEngine;
using UnityEngine.InputSystem;
public class RebindScript : MonoBehaviour
{
public InputActionReference Action;
private InputActionRebindingExtensions.RebindingOperation rebindOperation; // this should be "optimised", since doing updates every frame is inefficient
void Update()
{
if (rebindOperation != null)
if (rebindOperation.completed)
{
Action.action.Enable();// after this you can use the new key
Debug.Log("finished");
}
}
public void StartInteractiveRebind()
{
Action.action.Disable(); // critical before rebind!!!
rebindOperation = Action.action.PerformInteractiveRebinding()
.WithControlsExcluding("Mouse")
.WithCancelingThrough("<Keyboard>/escape")
.OnMatchWaitForAnother(0.2f)
.Start();
}
}
Before I forget this script apparently eats alternative action bindings, so beware! If you have jump on āspaceā and āwā for example after this procedure you will only keep your new binding and will have to reload to have both back!
I would like to apologize if the formatting is weird I am new to forums in general.
Cordially the all consuming void.