- Home /
Implementing Jump w/ New Input System
I'm attempting to implement jumping in my 2D platformer. The way I'm doing it works but it has numerous issues. I'm using the new Unity input system with unity events as my method of checking input; however, I'm not sure how to get the equivalent of GetKeyDown. With the following code the player jump input is read MANY times due to jumpInput equaling 1f numerous times per key press. (Since humans can't exactly hit the key for only one frame.)
public void JumpInput(InputAction.CallbackContext context) {
jumpInput = context.ReadValue<float>();
}
private void ProcessJumping() {
Vector2 jumpVelocity = new Vector2(0f, jumpHeight);
if (jumpInput == 1) {
rb.velocity += jumpVelocity;
}
Vector2 vel = rb.velocity;
vel.y += Physics2D.gravity.y;
}
Answer by RyanRogers · Jul 13, 2020 at 12:59 AM
you can check for a bool with inputAction.PlayerControls.Jump.triggered, assuming your input action is set up to work like a button. This will cause it to fire once on the frame, and not again.
You still need to do the OnDisable and OnEnable functions mentioned earlier, but this gets you as close to the old Input.GetKeyDown as you can get.
EDIT: The code would look like this:
using UnityEngine.InputSystem;
private void Awake() {
PlayerInputActions inputAction = new PlayerInputActions()
}
private void Update(){
if (inputAction.PlayerControls.Jump.triggered) {
Jump();
}
private void Jump() {
*Do your jump here*
}
private void OnEnable() {
inputAction.Enable();
}
private void OnDisable() {
inputAction.Disable();
}
What data type are you setting up your inputAction variable as? That's where I'm getting confused.
The data type is the just whatever you called your Input Actions that you made in the assets,
$$anonymous$$g here you can see I called my one PlayerInputActions, so that's what the data type will be called, yours will be whatever you called yours.
Thanks for the reply. Okay so the issue was that i didn't generate the C# class when i made the input actions; therefore, my script didn't know what to reference.
Answer by finnjwohner · Jul 12, 2020 at 10:22 PM
I'm not too familiar with the new input system so this may not be the best possible way to do it but this is how I did it,
using UnityEngine.InputSystem;
private void Awake() {
inputAction = new PlayerInputActions()
inputAction.PlayerControls.Jump.performed += Jump();
}
private void Jump() {
// Function that makes the player jump
}
private void OnEnable() {
inputAction.Enable();
}
private void OnDisable() {
inputAction.Disable();
}
Where PlayerInputActions is my input actions, PlayerControls is my action map and Jump is my jump action.
Edit: added in OnEnable() and OnDisable() functions that are also required.
Hmm, I think I follow but I'm not able to reference my Action $$anonymous$$ap like you are.
I did something along these lines:
using UnityEngine.InputSystem;
PlayerInput inputActions;
private void Awake() {
inputActions = new PlayerInput();
//This line won't work.
}
I tried serializing inputActions too. I'm still quite a beginner with Unity so I may be misunderstanding something simple.
Ahh my bad, forgot the OnEnable() and OnDisable() functions that are also required. Altogether should look like this.
using UnityEngine.InputSystem;
private void Awake() {
inputAction = new PlayerInputActions()
inputAction.PlayerControls.Jump.performed += Jump();
}
private void Jump() {
// Function that makes the player jump
}
private void OnEnable() {
inputAction.Enable();
}
private void OnDisable() {
inputAction.Disable();
}
Still not working properly. Testing out some other stuff but no luck.
What cached reference are you using for inputAction?
Answer by bsgbryan · Jul 14, 2020 at 12:34 AM
Using the new Input system with DOTS
I have a Jump action defined in my PlayerInputActions asset. This Jump action has an action type of Button. It has two bindings: Space (for the Keyboard & Mouse control scheme) and Button South (for the Gamepad control scheme).
I then have the following System:
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine.InputSystem;
// PlayerInputActions is the name of my Input asset
// Generated Input asset classes include an interface; making it easy to
// handle all the actions you created in code
public class GatherInput : SystemBase, PlayerInputActions.IPlayerActions {
private PlayerInputActions input;
private float jumping = 0;
// This is the handler for my Jump action
public void OnJump(InputAction.CallbackContext context) {
jumping = context.ReadValue<float>();
}
protected override void OnCreate() {
input = new PlayerInputActions();
// This registers this class as a handler for input events
// For every action you define you need an appropriate OnAction
// method in this class
input.Player.SetCallbacks(this);
}
protected override void OnStartRunning() => input.Enable();
protected override void OnStopRunning() => input.Disable();
// NOTE: Multiple input events can happen between executions of OnUpdate.
// This means that you need to be sure you sum up the data from all events
// between OnUpdate invocations for things like Delta bindings
protected override void OnUpdate() {
float j = jumping;
Entities.ForEach((ref PlayerInputData input) => {
input.Jumping = j;
}).Schedule();
// Resetting this value allows the player to press jump again
// NOTE: This means the player can spam the jump button
// Some sort of timeout would be nice if you wanted to do
// support double/triple jumps
jumping = 0;
}
}
PlayerInputData is a component:
using System;
using Unity.Entities;
using UnityEngine;
[Serializable]
[GenerateAuthoringComponent]
public struct PlayerInputData : IComponentData {
[HideInInspector]
public float Jumping;
public float JumpHeight;
}
This component is added to the player GameObject. I use sub-scenes, so my player GameObject gets converted to an entity automatically. If you're not using sub-scenes, just make sure to add a ConvertToEntity component (you'll likely want to specify Convert and Destroy as the Conversion Mode) to your player GameObject.
I then have a PlayerJump system:
using Unity.Entities;
using Unity.Physics;
public class PlayerJump : SystemBase {
protected override void OnUpdate() {
Entities.ForEach((
ref PhysicsVelocity velocity,
in PlayerInputData input
) => {
velocity.Linear.y += input.Jumping * input.JumpHeight;
}).Schedule();
}
}
This system causes the player to jump. If you don't want to use physics, you could animate the player's Translation.Value.y until it reaches input.JumpHeight.
Answer by kingdom216 · Oct 20, 2021 at 04:58 AM
The problem that I am having is that jump is not defined by my input system, but I have set it up just the same as I did with move and run which work perfectly. Does anybody know how to fix this?
Your answer
![](https://koobas.hobune.stream/wayback/20220613003051im_/https://answers.unity.com/themes/thub/images/avi.jpg)