- Home /
OnGUI() and key pressing problems.
I'm making a demo-game, with no purpose, other than for me to get better at unity. It's a first person perspective, and i wanted the player to be able to pick up a gem of some sort, it all worked fine, however, once i wanted to introduce a UI, a problem came up.
I use this script, to detect if the player mouses over the gem:
private var MO=0; // Attach this script to a mesh to make it detect when he mouse is over the object, if it is, MO will be //one, otherwise it will be zero
function OnMouseEnter ()
{ MO=1; renderer.material.color = Color.red; }
function OnMouseExit() { MO=0; renderer.material.color = Color.red; }
The idea of the script is, that i can read the variable MO, and if it is 1, then the mouse is over, it all worked fine, as i said, however, then i made this script, which is used to display messages on the screen: The renderer.material.color, is only so i can see if the object is moused over or not.
function OnGUI()
{
}
This is the script that checks the variable MO:
function Update() { if (Input.GetKeyDown(KeyCode.E)) { if (gem) { if (Vector3.Distance(transform.position,gem.transform.position(is smaller than)2.5) if (gem.GetComponent("MouseOver").MO==1) { gui.GetComponent("MessageSystem").NewMessage(1.0,235/255,4/255,"Gem picked up."); Offer1=1.0; Destroy(gem); } }
if (altar)
if (Vector3.Distance(transform.position,altar.transform.position)(Is smaller than)3.2)
if (altar.GetComponent("MouseOver").MO==1)
if (Offer1==1)
{
gui.GetComponent("MessageSystem").NewMessage(1.0,235/255,4/255,"The gem was sacrifized to the god of fuckbuckets, you have hereby gained an additional 10 life.");
gui.GetComponent("ShowLife").LifeUp(10);
Offer1=0;
}
}
}
The (Is smaller than) are '<'s in the actual code, but the < and > seems to mess up the code tag. What the last script is, is activating when the player presses the 'E' key. If the mouse is looking at the gem (If gem.GetComponent("MouseOver").MO is 1), then it will proceed by deleting the game object (As to simulate the player has picked up the gem), and then send show a message in the UI saying: "Gem picked up". As i said, the problem is, that if the second script is activated, and has the command: "function OnGUI" within it, then whenever a key, on the keyboard, is pressed, it somehow automaticly "calls" the OnMouseExit() event of the first script. This means that the third script no longer recognizes gem.GetComponent("MouseOver").MO as 1, but now as 0, and the "picking-the-gem-up" part of the script is therefor not executed. This happens with every key on the keyboard, but not the mouse, also, it only happens in te editor, not when i build and run the project.
Here i can see another person has the axcact same problem: http://forum.unity3d.com/viewtopic.php?t=40371 Could it be that OnGUI() somwhow provoces the OnMouseExit() function. I have tried to print the position of the mouse, and it is still the same, so the OnMouseExit() Event actually runs, even though the mouse is still where it was when the OnMouseEnter() event happened. You can try yourself to import both the first and the second script into a unity project (I tried with more than one project and setup), and you will see that as long as you hold down a key, the object will flash the original color and red, since it is constantly trated as the mouse enters and leaves it.
First, you can re-edit your post - if you select the code section, and click on the code button (it looks like "101010" above the answer box), then your code will be formatted better. Assu$$anonymous$$g you put it on single lines, anyway. :) Second, it would help to list the actual error message, too. I suspect it's something with the $$anonymous$$essages array, but until you edit it, the code's too unreadable to tell. :)
@$$anonymous$$edianHansen, nice, the code is much more clear now. I still have some questions, though. First, where is the code that actually uses $$anonymous$$O? I don't see anywhere that checks its value? Second, for debugging (and posting), it's helpful to remove as much code as possible. If the bug can happen even when OnGUI() function is empty, then post it as empty. :) It's shorter, easier to understand. It might be worth creating a duplicate project, then deleting as much as you can and still leave the bug.
UPDATE! I found that this problem is only present, when running in the editor, as soon as i build and run, the problem is not there!
Answer by Cyclops · Mar 18, 2010 at 04:23 PM
Actually, it's not quite working as you think :) The problem is also in a standalone executable, just not noticeable due to the higher framerate.
Here is some sample code that will show exactly what's happening:
// s_Mouse.js var mouseOver : boolean = false; var eDown : boolean = false; var mCount : int = 0;
function OnMouseEnter() { mouseOver = true; } function OnMouseExit() { mouseOver = false; }
function OnGUI() { if (mouseOver) { mCount += 1; GUI.Button (new Rect(20, 20, 100, 20), "Ping " + mCount); } else GUI.Button (new Rect(20, 20, 100, 20), "Pong"); if (eDown) GUI.Button (new Rect(20, 50, 50, 20), "EEEE"); if (mouseOver && eDown) GUI.Button (new Rect(20, 100, 100, 20), "Double Bonus"); // Flickers. } function Update () { if (Input.GetKeyDown(KeyCode.E)) eDown = true; if (Input.GetKeyUp(KeyCode.E)) eDown = false; }
Drag/drop this script onto any Object, then run the Editor. When you move the mouse over your Object, the GUI button changes from Ping to Pong. Move the mouse away, and press the E button - another button pops up. Now, if you move the mouse onto the object while the E key is pressed - the Gui buttons start flickering.
It seems as if the OnMouseEnter is being fired repeatedly. If you build an executable, you don't see any flickering - only in the Editor.
However - it's only because the executable is running faster. Notice that I put a Counter in the Ping box. It grows steadily in the Editor - and massively in the standalone.
So the OnMouseEnter() event is firing constantly, in both the Editor and standalone. It's only obvious in the Editor, due to the slower framerate.
I admit, it doesn't seem like it should: "OnMouseEnter is called when the mouse entered the GUIElement or Collider." Maybe it's a bug, or the documentation is wrong - or something else is going on. :)
But yes, it's behaving the same in your standalone, you're just not seeing the effects due to the higher framerate.
No, it's not behaving the same way, because: Normally when the E key is pressed, you will pick up the gem, this doesn't happen because the moues now "exits" the object. In the stand-alone it get's picked up, (I have also tried having a pring function in the On$$anonymous$$ouseExit() function) and it's only in the editor that i see that print function, not the in stand alone. I appreciate that you still try to resolve my problem, though :P
As Cyclops indicated, On$$anonymous$$ouseEnter/Exit/Over seem to be very unreliable/unintuitive. They get called when not expected, or not called when expected. I would recommend using a single Update function that casts a Ray through the mouse pointer and handle Enter/Exit/Over yourself.
Answer by Nic.du · Apr 30, 2010 at 05:56 PM
I'm getting a very similar problem. I display a GUI when the mouse is over an object using OnMouseEnter. However - when I press any key it refires the OnMouseEnter. Seems very very weird. Kind of annoying as I just spent the evening refactoring code to use OnMouseEnter instead of casting a ray...
This occurs in the editor btw.
Nic.
Your answer
Follow this Question
Related Questions
Unity 4.6.3f1 bug or normal behaviour? MouseButtonDown cancelled/ ignored by key press 0 Answers
How to avoid multiple mouse clicks registering in OnGUI? 1 Answer
How do i change controller from keyboard to mouse?? 1 Answer
Unity UI Mouse + Keyboard navigate, Un-Highlight button choice on mouse over 0 Answers
problem whit input key 2 Answers