- Home /
Inputhandling is giving different results for left and right (arrows, ctrl's , shifts) but my code seems fine
Discussed in the question here:
I noticed the comment that you may want to use two buttons. I have repeatadly tried this but it's giving back unexpected behaviour ( Yes I checked the coding round and about 2592 times now) .
Here's the sample C# VS2010 .NET 2.0 (Yes I know [Flags] enumeration is better but it,s the .NET 2.0 I'm afraid which doesn't support that , my code has to be iPrimitive) :
The sample is for when a user HOLDS DOWN a key , it checks by comparing the states this frame and last frame.
if (!RightKeyPressed_Old) { if (RightKeyPressed_New) { //Input states character wants to Run right isRunning = true; } if (!RightKeyPressed_New) { //Input states character wants to stop Running right isRunning = false; } }
//With nesting: If Left Key is being held down! If it's NOT being held Down! if (!LeftKeyPressed_Old) { if (LeftKeyPressed_New) { //Input states character wants to Run isRunning = true; } if (!LeftKeyPressed_New) { //Input states character wants to stop Running left isRunning = false; } }
The code simply then checks in another method if the state is true to play the respective running animation. All I have to do then is change the character orintation in the 2D environment.
My Debug log clearly states the key was pressed and released however it is ONLY responding to ONE of the two. If I put one code block on top has no effect. The inputmanagersettings are not bugged and do match. The same is happening for left/right shift and left/right ctrl ( I tested it )
I'm not so worried anymore it's my code therefor, and more worried it's a way Unity3D thinks I should do inputhandling in a certain way with the manager which I'm just not getting.
Not confused yet? Well here's a quick summary:
I press left or right , and the response is NOT the same!! It's the same problem with left shift and left ctrl and the code seems to be working according to my debugging.
Please help me find a solution. I am willing to just toss it overboard and work with the negative values of a pressed buttong, but I don't want to be using GetAxis or GetAxisRaw.
Thanks in advance!
EDIT 11/2/2010:
I think I just found something. I may have just ended up performing a bypass giving me incorrect results. (Meaning: I changed the input manager values of the virtual buttons into something silly like T and Y buttons) and guess what. No response. So i may simply have assigned the wrong variable. Checking for that now. Will post results if so.
EDIT 11/2/2010: 2 minutes later
Nope, it just seems to accept left and right as input even though there is no button defined for it. When I tell it to use t and y on the object aswell as the input manager. The peculiar thing is. I really think I'm running out of options.
EDIT 11/2/2010: 10 minutes later
Think the code really was the same but that was actually the problem, I wanted to get a dumb version to run first and didn't care about left or right, but left was changing right. The problem moves if I invert the code block above and down, which I said it didn't , but I probably just forgot to save!
//Pressed this frame? if (Input.GetKeyDown(LeftKey)) { Debug.Log("LeftKey Was Pressed This Frame"); LeftKeyPressed_Old = true; LeftKeyPressed_New = true; }
if (Input.GetKeyUp(LeftKey)) { Debug.Log("LeftKey Was Released This Frame"); LeftKeyPressed_New = false; }
//Pressed this frame? if (Input.GetKeyDown(RightKey)) { Debug.Log("RightKey Was Pressed This Frame"); RightKeyPressed_Old = true; RightKeyPressed_New = true; }
if (Input.GetKeyUp(RightKey)) { Debug.Log("RightKey Was Released This Frame"); RightKeyPressed_New = false; }
FINAL EDIT: 11/3/2010
Changing the logic to this fixed it:
if (HasAbilityToRun) { if (!LeftKeyPressed_Old || !RightKeyPressed_Old) { //if a run left key was hit if (LeftKeyPressed_New) { //Input states character wants to Run isRunning = true;
//CHANGE CHARACTER ORIENTATION TO LEFT
//Run();
}
//if a run right key was hit
if (RightKeyPressed_New)
{
//Input states character wants to Run right
isRunning = true;
//CHANGE CHARACTER ORIENTATION TO RIGHT
//Run();
}
if (!LeftKeyPressed_New && !RightKeyPressed_New)
{
//Input states character wants to stop Running right
isRunning = false;
//STOP RUNNING
}
}
}
Yep, it really was the order in which I coded it. Stupid forgetting to save made me miss out a single valid testresult making me end up in a witch hunt.
Well lesson learned
DOUBLE CHEC$$anonymous$$ THE PROBLE$$anonymous$$S THAT $$anonymous$$A$$anonymous$$E SENSE, and THEN go look for the insane solutions. $$anonymous$$aking an error while debugging is very possible!
Answer by Proclyon · Nov 02, 2010 at 01:52 PM
<--- Edits and my comment answered it for me. Feel free to use it as information for your own problem solving adventures!
Still leaves the question of , why can't I acces negative values of virtual buttons? This seems like a bad joke since being able to undo an action can be usefull for more things then just running. Sheath/Unsheath ReadySpellCasting like in the elder scrolls games (Morrowind, Oblivion etc.) Which seems lame to recode checking state all the time.
I'm not really sure what you mean by virtual buttons. Could you tell me how you are setting all of you booleans? And why do you want to access the negative value, why just not make a new button?
Input manager in Unity3D allows you to define buttons. With their own names you can call them and use them as events. If pressed key down etc. Those are the virtual buttons. I will post the code to help out anyway, just check my edited main post
$$anonymous$$y boolean logic was without error. The problem was that my earlier posted 2 code blocks screwed each other over. The first would always keep setting to false. and it's the same bool in the testversion so the other would never get to true only the lowest block ever would be able to get a true value unless both were pressed at the same time.
I'm still a little confused, but I'll live with it. Is the problem solved? And do you ever set your xxx_Old values to false anywhere?
Answer by Atnas1010 · Nov 02, 2010 at 01:52 PM
I'm not sure what this problem is, but I would just use something like this:
isRunning = (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.RightArrow));
This is not affected by unitys input manager.
If you dont like this solution, I would need to see how you set all the booleans your script are based on, in order to help you further.
Indeed, that is not a proper solution for me right now to hardcode. It's a solution that will fix the problem though. So thank you for the idea
Answer by Atnas1010 · Nov 02, 2010 at 03:27 PM
This code gives me what I would expect you would want it to do.
if (!Input.GetKeyDown(KeyCode.RightArrow)) { //print(Time.time); if (Input.GetKey(KeyCode.RightArrow)) isRunningRight = true; else isRunningRight = false; }
//With nesting: If Left Key is being held down! If it's NOT being held Down! if (!Input.GetKeyDown(KeyCode.LeftArrow)) { if (Input.GetKey(KeyCode.LeftArrow)) isRunningLeft = true; else isRunningLeft = false; }
Is this what you were looking for?
Yes and no, I changed it to this ins$$anonymous$$d which is exactly what I needed. The problem for me was FINDING the true problem. And I made one error while bugfixing causing a huge delay in that.
Sample is in the main post in an EDIT