Impulse forces on keydown. Is there a better way?

I just picked up unity a few weeks ago and started working on a platformer for my first game. For jumping I am adding a impulse force on key down. Since it was on key down I did this in update so the event wouldn’t be missed and the physics had no issues.

I moved on to wall jumping today and where the player jumps off of walls like you could in Mario or many other platformers. Since it was on keydown I did this just like I did jumping but I started noticing inconsistent behavior with the physics. Sometimes the force was not applied, sometimes it stopped midway and other times it worked.

Moving the jump machinics to fixedupdate fixes the physics issue but then keydown events are not always caught in fixed update so I will have to listen to keydown in update and run the physics in fixed update.

Assuming I will need to do this for other actions what is the best way to track the state of the keys and pass it to fixed update without creating a ton of variables? or is there a better way to do this?

Your best bet would probably be to use a boolean to check how many jumps has been made.
For example:

public bool jumpedTwice= false;

void Update()
{
if(Input.GetKeyDown(KeyCode.Space) && !jumpedTwice)
{
  //jump
if(Input.GetKeyDown(KeyCode.Space)
{
jumpedTwice = true;
//jumping second time
}
}
}

Basically, void Update would probably be the best method to catch Input from user. But you should always try to use some variables in order to prevent it from bugging! Hope it was the right answer to your question!

That’s what I am currently doing.

I am targeting consoles which will have 12+ buttons. Add that to keydown, key and keyup stats and you have a lot of class properties.

I am hoping there is a better way to pass state from update to fixed update.

How about handling the input in update (so nothing is missed) and setting a flag that a jump is triggered, then in fixedupdate read this flag and if it is set, do the jump and clear the flag?

There is not really a better way. bools don’t take up that much memory or code space.

2 Likes

Yes, bool’s will probably be your best bet! :slight_smile: Dont be afraid of using them.

By better I am not talking about memory but about maintainability and readability.

I feel like 300+ lines of code of setting bool values and checks as overkill. If its the only option then I will move it into it’s own method.

You are correct. Input checking in Unity is not overly pleasant. Not being able to configure input to catch it directly in FixedUpdate is one of the issues that crops up. The other is that axes bindings can not be changed at run time.

You can achieve the same effect you do with 5 booleans, by using only 2 booleans - depends on how experienced you are.

Can you give me an example on how I can map keydown, key, and key up states for 8 buttons with less than 16 bools?

I can reduce 24 checks down to 16 by having two bools per key. wasDown and isDown.

Why are you not using the different key inputs? You dont need “isDown”. You can just say if(Input.GetKey(KeyCode.E)) and it will check if you are holding down E button. If you say if(Input.GetKeyDown(…)) then it will check if you just click the button. After using Input.GetKey you can use Input.GetKeyUp. Then by these input methods, you can assign variables inside of them. Basically, 8 buttons = 8 bools mostly - depending on how much you need them.

For example, you can say:

public bool isDown;

if(Input.GetKey(KeyCode.E))
{
isDown = true;
}

if(Input.GetKeyUp(KeyCode.E))
{
isDown = false;
}

For most situations that will do but in some cases it wont. For example in Mario the fire button only fires on key down but can be used to run if held and he wont fire again until you repress the button.

Sure I could listen to only the key event but then I have to track if it was the first instance of being true. To me it seems easier and more readable to listen to the two different events of keyDown and key.

it would be simpler to do isDown = Input.GetKey(KeyCode.E) for the use case you are suggesting. your code makes it impossiable to do something soon as the key is lifted.
I am asking about cases where you want to do a different actions for each of the states KeyDown, Key and KeyUp. I am currently doing this like so

public bool wasDown = false;
public bool isDown = false;

void Update() {
    wasDown = isDown;
    isDown = Input.GetKey(KeyCode.E);
}

void FixedUpdate(){
    if(isDown && !wasDown){
        // key down event
    } else if(isDown && wasDown)  {
        // key event
    } else if(wasDown && !isDown) {
        // key up event
    }
}

Then why are you using getkey instead of GetButton?

im am prototyping for computers while I learn unity and c#. Find and replace is not hard to do when I need to switch.

Was just thinking you could set the buttons in the input manager naming them jump walk fire.

You can use as much as you want in one single key press, and it’s pretty usefull to just have one variable that you assign to do some stuff, while the input itself can take care of some other stuff. Obviosuly it’s just another method, but I’d suggest you less variables. What you’re doing seems like duplicating stuff to me.

@Sykoo The whole point of the variables is to capture the input inside of Update, then use it inside of FixedUpdate. As these don’t run at the same rate you can’t simply set the bool to true of false in Update, this would be exactly the same as checking for input in FixedUpdate. At best you need to set a bool true in Update and false in FixedUpdate. This doesn’t allow for sophisticated input detection, and ends up with complicated if statements.

@yamiko Did you ever consider doing something event based, like the old OnGUI system? Its more complex to code, but could potentially make your code look better and tidy up all of those nasty if statements. Create a struct to store input, build a queue. Enqueue each input during Update and Dequeue it during FixedUpdate?

Not sure how this approach would run in terms of efficiency. But it would eliminate the need to write tonnes of variables to transfer each input across to FixedUpdate.

Its also worth checking which inputs actually need to go to FixedUpdate, and which can be handled in Update. In general things like physics based jumping and movement should be in FixedUpdate. But shooting, dialogue, menus, regular movement and any other non physics behaviour doesn’t actually need its input translated. I’d be surprised if all 12+ of your buttons needed to be read by FixedUpdate.