Hello Input System guys!
I’m porting the old control system in my prototype to the new Unity Input.
I’m having trouble with holding a key to move a player.
I thought the Hold Input Interaction might fill this roll, but this only triggers after x amount of time held. I’m surprised to see there isn’t a “While Held” interaction.
There seems to be events for the input began, performed, and cancelled, but not while the interaction is happening?
Am I blind or is this the case?
If you poll someInputAction.started it will return true every frame while the key or button is held down. That’s how I’m doing it.
They don’t pay much service to polling in the docs, and ReadValue is a bit obtuse, without good documentation for what each input type yields as a value type. Like, what’s a Button get you?
I get what you mean.
I have managed to make this work using the following theory:
-
When a player presses one of the InputAction Movement keys, we update the vector moveDirection.
-
Then, every frame we check to see if the InputAction Movement is in the phase Started. That is to say, if Movement.phase == InputActionPhase.Started.
-
If so, do the move by moveDirection.
-
If not, set moveDirection = vector2.zero
Code below, it’s not as polished as I’d like but it gets there so far. Any crit is welcome:
using UnityEngine.InputSystem;
public class ControlsManager : Manager
{
public delegate void MovementControlEvent(Vector2 v);
public static event MovementControlEvent OnMoveVectorIterated;
private InLevelControls inLevelControls;
private Vector2 moveVector;
public void Awake()
{
inLevelControls = new InLevelControls();
inLevelControls.Player.Movement.performed += context => SetMoveVector(context.ReadValue<Vector2>());
inLevelControls.Enable();
}
private void Update()
{
if (inLevelControls.Player.Movement.phase == InputActionPhase.Started) {
OnMoveVectorIterated?.Invoke(moveVector);
}
else
moveVector = Vector2.zero;
}
private void OnDestroy()
{
inLevelControls.Player.Movement.performed -= context =>
SetMoveVector(context.ReadValue<Vector2>());
}
private void SetMoveVector(Vector2 v)
{
moveVector = v;
}
}
}
In an ideal world, I’d like to write my own ContinuouslyHeldInteraction
, implimenting IInputInteraction
and have that appear in the Input editor window, a la the example on the Quickstart guide here. But that is beyond my understanding at the moment.
Edit: for clearer code for prosperity, hopefully someone stumbles on this in the future and it helps.
Seems fine to me. Personally, I find a bit of smoothing in there at the controls level is helpful, but depends on your code further downstream. Talking about just slapping a SmoothDamp on there before passing it along. People have been complaining that the old Input system let you put keys on an Axis and it would smooth the values, but the new system doesn’t offer that.
Also a static event might lock you out from having multiple controllers?
1 Like
I will be passing the moveVector out to a NavMeshAgent at some point, so that’ll likely take care of the smoothing on a per-character level.
You’re right, the static event does lock me out of multiple controllers. For the moment, that is not a problem since this a single game experience. So there shouldn’t ever be more than one controlmanager active. But in the future that could expand. Do you have any suggestions in that event?
I’d just make this a per-player thing and let whatever subscribe to it at an instance level. You could even singleton what you have and globally access it for now and the signature probably wouldn’t be too different.
But yeah too many things have been done because “someday” and if you know you’re never having more than one player then don’t listen to me!
No problem.
You’ve been a great help!
If I hadn’t of know about the ActionInputPhase.started I would of been plugging away at that problem for centuries.
Thanks, man. Is there a way I can endorse the answer, or upvote it, or something to make it more visible and useful to people?
No problem! I just spent a few days in hell with the InputSystem so I’m glad my pain could be useful beyond my own project.
1 Like