- Home /
Need to press key twice to react
Hi!
This problem might be a tough thing to solve for you guys, and It's kinda hard to explain.
I have a script where I open a door with a password. The problem is when I added the password and then try to open the door it takes two presses on the "E" key to open. You can press the first "E" wherever you like, you don't have to be near the door (yes I have an "in range" in the script). After I pressed "E" one time then the seccond time I can open the door (if I'm near it).
As I said, this is really hard for you guys to understand, but I hope some of you guys know what I'm talking about.
Thanks in advance!
The script:
var InRange;
var buttonActivated;
var cabinet : GameObject;
var handle : GameObject;
var cabinetIsOpen = false;
var doorTimer : float = 0.0;
public var guiSkin : GUISkin;
//Sound
var OpenSound : AudioClip;
var CloseSound : AudioClip;
var buttonSound : AudioClip;
var unlockSound : AudioClip;
private var hasPlayed = false;
//Enabled/Disable
var EnableDisable : EnableDisableComponents;
//Password
var passwordWritten : String;
var newPassword : String;
private var setNewPassword : boolean = false;
private var tooShortPassword : boolean = false;
private var newPasswordSet : boolean = false;
private var wrongPassword : boolean = false;
var thePassword: String;
private var enterCabinet : boolean = false;
private var enterPassword : boolean = false;
private var correctPassword : boolean = false;
var zero = "0"[0];
var nine = "9"[0];
function OnTriggerEnter (c : Collider)
{
InRange = true;
}
function OnTriggerStay (c : Collider)
{
InRange = true;
}
function OnTriggerExit (c : Collider)
{
InRange = false;
}
function OnGUI()
{
if(InRange == true)
{
GUI.skin = guiSkin;
GUI.skin.settings.selectionColor = new Color(0.9, 0.7, 0.04);
if(!enterPassword && !correctPassword)
{
GUI.Label (Rect (Screen.width/2-50, Screen.height - 100, 120, 50),"[E] ENTER PASSWORD");
}
if(!cabinetIsOpen && correctPassword)
{
GUI.Label (Rect (Screen.width/2-50, Screen.height - 100, 120, 50),"[E] OPEN CABINET");
}
if(cabinetIsOpen && passwordWritten == thePassword)
{
GUI.Label (Rect (Screen.width/2-50, Screen.height - 100, 120, 50),"[E] CLOSE CABINET");
}
//Password lenght
if(enterPassword)
{
var e = Event.current;
if (e.isKey)
{
if (e.character < zero || e.character > nine)
{
e.character = 0;
}
}
//Set new password button
if(GUI.Button (Rect (Screen.width - 300, 90, 270, 50), "SET NEW PASSWORD"))
{
if(!setNewPassword)
{
setNewPassword = true;
newPassword = "";
}
else
{
setNewPassword = false;
}
}
//Set new password
if(setNewPassword)
{
wrongPassword = false;
GUI.Label (Rect (Screen.width/2 - 200, Screen.height/2 - 0, 500, 100), "SET NEW PASSWORD: ", "Password");
newPassword = GUI.TextField(new Rect(Screen.width/2 - 50, Screen.height/2 + 70, 200, 70), newPassword, 4);
if(GUI.Button (Rect (Screen.width/2 + 170, Screen.height/2 + 80, 100, 50), "SET"))
{
if(newPassword.Length == 4)
{
thePassword = newPassword;
setNewPassword = false;
audio.PlayOneShot(unlockSound);
newPasswordSetFunction();
}
else
{
tooShortPasswordFunction();
}
}
//Text popup
if(tooShortPassword)
{
GUI.Label (Rect (Screen.width/2 - 200, Screen.height/2 + 130, 500, 100), "TOO SHORT!", "Password");
}
}
//Text popup
if(newPasswordSet)
{
GUI.Label(new Rect (15, 100 -50, 250, 50), "NEW PASSWORD:" + newPassword, "textPopup");
}
//Enter password
GUI.Label (Rect (Screen.width/2 - 200, Screen.height/2 - 130, 500, 100), "ENTER PASSWORD:", "Password");
passwordWritten = GUI.TextField(new Rect(Screen.width/2 - 50, Screen.height/2 - 60, 200, 70), passwordWritten, 4);
if(GUI.Button (Rect (Screen.width/2 + 170, Screen.height/2 - 50, 100, 50), "ENTER"))
{
if(passwordWritten == thePassword)
{
enterCabinet = true;
correctPassword = true;
setNewPassword = false;
}
else
{
wrongPasswordSetFunction();
setNewPassword = false;
}
}
//Text popup
if(wrongPassword)
{
GUI.Label (Rect (Screen.width/2 - 200, Screen.height/2 - 0, 500, 100), "WRONG PASSWORD!", "Password");
}
}
if(passwordWritten == thePassword && enterCabinet)
{
passwordFunction();
}
}
}
function Update ()
{
if(doorTimer > 0)
doorTimer -= Time.deltaTime;
if(doorTimer < 0)
doorTimer = 0;
if(InRange == true)
{
if(Input.GetKeyDown ("e"))
{
if(!enterPassword)
{
enterPassword = true;
}
if(correctPassword)
{
ToggleDoor();
enterPassword = false;
}
}
}
if(enterPassword)
{
EnableDisable.interaction = true;
EnableDisable.disableComponents = true;
EnableDisable.enableComponents = false;
}
if(correctPassword && InRange)
{
EnableDisable.interaction = false;
EnableDisable.disableComponents = false;
EnableDisable.enableComponents = true;
}
}
//Password correct
function passwordFunction()
{
if(!hasPlayed)
{
audio.PlayOneShot(unlockSound);
hasPlayed = true;
yield WaitForSeconds(0.5);
enterPassword = false;
correctPassword = true;
}
}
//Open cabinet
function ToggleDoor()
{
if(doorTimer == 0 && correctPassword)
{
doorTimer = 1.0;
if (cabinetIsOpen == false)
{
audio.PlayOneShot(OpenSound);
cabinet.animation.Play("Cabinet open");
handle.animation.Play("Cabinet handle");
yield WaitForSeconds(0.9);
cabinetIsOpen = true;
}
else
{
audio.PlayOneShot(CloseSound);
cabinet.animation.Play("Cabinet close");
yield WaitForSeconds(0.7);
cabinetIsOpen = false;
correctPassword = false;
enterCabinet = false;
passwordWritten = "";
hasPlayed = false;
}
}
}
//Popups
function tooShortPasswordFunction ()
{
tooShortPassword = true;
yield WaitForSeconds(1);
tooShortPassword = false;
}
function newPasswordSetFunction ()
{
newPasswordSet = true;
yield WaitForSeconds(4);
newPasswordSet = false;
}
function wrongPasswordSetFunction ()
{
wrongPassword = true;
yield WaitForSeconds(1);
wrongPassword = false;
}
Try adding a debug.log () in the if (correctpassword) statement in your update function. Is there a response on the first keypress?
Answer by pako · Jan 12, 2015 at 01:22 PM
The problem has to do with the execution order.
You check for button press inside Update, and immediately after you check if correctPassword = true in order to ToggleDoor. However, correctPassword gets set to true inside OnGUI.
OnGUI runs after Update, see:
http://docs.unity3d.com/Manual/ExecutionOrder.html
Then, for correctPassword to get checked, you have to press the button again, because the check occurs only if the button has been pressed.
I think the solution is to add ToggleDoor() just after verifying the password.
I mean outside if(Input.Get$$anonymous$$eyDown ("e")) :
Update(){
//some code
if(Input.Get$$anonymous$$eyDown ("e"))
{
if(!enterPassword)
{
enterPassword = true;
}
}
if(correctPassword)
{
ToggleDoor();
enterPassword = false;
}
//some code
}
But then the door opens automatically when the password is correct. I want to press "E" so the door opens
enterPassword = true gets set to true only if the "E"is pressed.
The password is entered and checked for correctness inside OnGUI (lines 127, 130), only if enterPassword = true (line 70) which means that "E" has been pressed, or the password wouldn't be entered and checked for correctness.
What am I missing?
If I have...
if(correctPassword)
{
ToggleDoor();
enterPassword = false;
}
... outside the "E" button press, then the door opens automatically as I said. It's because when I press Enter on the button "correctPassword" sets to true. And the code above gets called because the "correctPassword = true"