Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

OnMouseEnter/Exit Double Call

Discussion in 'Scripting' started by CoherentInk, Mar 21, 2009.

  1. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    I'm having some trouble with the OnMouseEnter and OnMouseExit calls on an object that is used to determine waypoints. If I have my mouse over the box when it is instantiated, I get two calls to OnMouseEnter and one call to OnMouseExit in between. Effectively this means that a movement arrow is created, destroyed, and then a new one is created. Why would this be happening?

    The box collider on this object is set as a trigger (since I don't want it to interact with any rigidbodies) and the renderer is set to fade in when it is created. I've tried turning off the fade in, but that makes no difference.

    So is there something that I'm missing about colliders/triggers and the raycasts going on behind the scenes and the process when you instantiate an object? Any help would be greatly appreciated and I'm happy to provide more info if needed.

    The relevant code is below:

    Code (csharp):
    1. void OnMouseEnter () {
    2.     if (!destroying) {
    3.         for (int i = 0; i < selected.Count; i++) {
    4.             movementArrows.Add((GameObject)Instantiate(movementArrowPrefab, transform.position, transform.rotation));
    5.         }
    6.         ((GameObject)movementArrows[0]).renderer.material.color = new Color(0, 1, 0, 0.75f);
    7.         Screen.showCursor = false;
    8.     }
    9. }
    10.  
    11. void OnMouseExit () {
    12.     Screen.showCursor = true;
    13.     if (!destroying) {
    14.         foreach (GameObject movementArrow in movementArrows) {
    15.             StartCoroutine(((Fade)movementArrow.GetComponent("Fade")).FadeOut(true));
    16.         }
    17.         movementArrows.Clear();
    18.     }
    19. }
    20.  
     
  2. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    As a follow up, OnMouseEnter and OnMouseExit are also being called whenever the camera moves. What vital piece of information am I missing about these functions?

    I can program around them for the most part, but it's giving me a major headache! This isn't limited to this one object I'm working with, it seems to happen with any object in this project (and probably others).

    Has anyone else come across this or know why it is implemented this way?
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I don't remember seeing any behavior like that...I just did a quick test, and I see OnMouseEnter being called once if an object is instantiated under the mouse cursor but that's it.

    --Eric
     
  4. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    There's always the possibility that you've got a GUI component in the way. OnMouseOver would be interrupted by any GUI textures on the center of the screen, as that's where the mouse is when it's frozen.

    Other than that, I can't think of a time when that's happened for me before.
     
  5. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    OK, so there's obviously a bug in my code somewhere. I created a new project and tried to recreate the basic parts (as I suspect Eric has) and I'm not getting multiple OnMouseEnter calls. Looks like I need to start going through the entire scene and code to see where the offending bit is.

    FWIW, there aren't any GUI components on the screen at all when this is happening. Also, the mouse isn't frozen when this is happening, it's only hidden since I'm using the coordinates to generate a cursor in 3D space. There is a collider on the camera, but it is set to the IgnoreRaycast layer, as is the object that is instantiated which tracks the mouse movements.

    Thanks for your help, if I find a solution I'll post it here. And by solution I mean an explanation of where I screwed up!
     
  6. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    OK, so I've figured out what is causing the problem but still don't understand why.

    I've created a scene that has just a cube and a camera in it. The cube is set to log each time that OnMouseEnter is called on it. The camera is set up for basic movement in 3D space (up/down, left/right, forward/backward, roll left/right). So far so good. Regardless of camera movements etc, OnMouseEnter is only called once for each time that the mouse actually starts hovering over the box.

    Now add one small change to the code: add an empty (or non-empty for that matter) call for OnGUI. Suddenly every movement of the camera will generate additional OnMouseEnter events. I'd appreciate it if someone else could confirm that they get similar results. I'll post a project illustrating this if it can't be repeated by others.

    I'm still hoping that I've made some really basic mistake but it seems less likely now.
     
  7. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    Oh yeah, I get that all the time. It's something that only happens in the editor, but it's still ridiculously annoying when I'm attempting to do something that requires a combination of GUI and mouseOver events.

    Whenever I create a standalone with the same project it doesn't happen at all.
     
  8. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    So I guess I should file a bug report?
     
  9. DGuy

    DGuy

    Joined:
    Feb 7, 2007
    Posts:
    187
    I can confirm your results: A model + an OnGUI handler + place mouse over model + move camera = Multiple OnMouseEnter/Exit events.

    I searched the forums and re-read the docs but no indication this has been run into before or what might be the reason why it occurs.

    I'd say, yea, file a bug report.

    As a work around, try this code (written in Boo, but should be easily converted to JS/C#):
    Code (csharp):
    1.     private _isOver as bool
    2.     def OnMouseEnter():
    3.         info as RaycastHit
    4.  
    5.         // has the raycast out from mouse hit something?
    6.         if Physics.Raycast( Camera.main.ScreenPointToRay(Input.mousePosition), info ):
    7.  
    8.             // has the raycast out from mouse hit the gameobject this handler is attached to?
    9.             if info.collider.gameObject == self.gameObject:
    10.  
    11.                 // if mouse is not already over gameobject
    12.                 if not _isOver:
    13.  
    14.                     _isOver = true
    15.  
    16.                     // Do OnMouseEnter Stuff Here
    17.                     Debug.Log( "OnMouseEnter" )
    18.  
    19.  
    20.     def OnMouseExit():
    21.         info as RaycastHit
    22.  
    23.         if _isOver:
    24.  
    25.             // has the raycast out from mouse hit something
    26.             if Physics.Raycast( Camera.main.ScreenPointToRay(Input.mousePosition), info ):
    27.        
    28.                 // has the raycast out from mouse *NOT* hit the gameobject this handler is attached to?
    29.                 if info.collider.gameObject != self.gameObject:
    30.  
    31.                     _isOver = false
    32.  
    33.             else:
    34.  
    35.                 _isOver = false
    36.    
    37.             if not _isOver:
    38.                
    39.                 // Do OnMouseExit Stuff Here
    40.                 Debug.Log( "OnMouseExit" )
    41.  
    The above basically confirms the mouse cursor has actually entered/exited object before "invoking" the event.
     
  10. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Hey guys...

    Could you file a bug with a simple repo case, then I'll see what I can do about fixing this once and for all...

    Thanks
     
  11. CoherentInk

    CoherentInk

    Joined:
    Jul 16, 2006
    Posts:
    216
    Filed it yesterday-- case 170253.

    Thanks!
     
  12. bjdottcom

    bjdottcom

    Joined:
    Aug 13, 2009
    Posts:
    2
    What's the status on this bug? Near as I can tell, in the editor, I still get an object's OnMouseOut/Exit called when I hit a key on the keyboard while over that object.
    This happens using Unity 2.6.
     
  13. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Is that the latest 2.6.1?
     
  14. bjdottcom

    bjdottcom

    Joined:
    Aug 13, 2009
    Posts:
    2
    Nope, it is 2.6.0f7. Didn't realize there was a later version. Will get it up to 2.6.1 later today or tomorrow.
     
  15. invicticide

    invicticide

    Joined:
    Nov 15, 2009
    Posts:
    109
    I'm on 2.6.1f3 and am also seeing this issue. In my repro, if *any* object in the scene has a script component that implements OnGUI() (even if that object is not the collider I'm mousing over), the collider will get OnMouseEnter()/OnMouseExit() repeatedly, but only if I'm holding down the mouse button at the same time.
     
  16. Gilead7

    Gilead7

    Joined:
    Apr 2, 2009
    Posts:
    27
    Apparently it has not yet been addressed at 2017 3.1.f1 I'm getting a similar situation.