2
\$\begingroup\$

I'm using NGUI to setup my UI in Unity.

Attached to the MainCamera I do have a script to rotate the camera view by clicking and dragging.

It does handle mouse events using Input.GetMouseButton().

The problem is that if I click and drag when the mouse is over a NGUI element (Button, Panel, Slider, whatever), NGUI handles all the mouse events correctly, but they also go through the MainCamera, and the camera rotate.

I want to prevent that.

If I use for example the Unity GUI.Button(), the mouse events are not transfered to the MainCamera and the camera does not rotate.

I have to replicate that, but using NGUI.

I have searched on their support forum, but i couldn't find a solution.

\$\endgroup\$
2
\$\begingroup\$

You can implement your own version of the below. Create a static bool in whatever GUI class you have available to all your scripts. Now, whenever you start a click operation with NGUI, you can set that bool to true. Then simply check to see if the bool is true before doing operations in other scripts. Ideally, if you have access to the NGUI source, this is a change you'd want to implement there, so it's all in one spot.

Remember to set it to false at the beginning of each frame.


Below works for Unity GUI:

Anywhere you want to respond to input that's shared with the GUI, you can use the test the hot control.

Hot control identifies the controlID of the GUI utility that's currently active. When it's set to zero, that means that no GUI control is active. So for example, in your camera control script you could do a test like this:

Update() {
    if (GUIUtility.hotControl == 0) {
        //Update camera
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ GUI.Utility(), sadly, works only for the Unity GUI System. NGUI uses it's own system based on 3D GameObjects rendered as 2D objects with a orthographic camera. \$\endgroup\$ – Fr0z3n Apr 23 '14 at 3:45
  • \$\begingroup\$ Bummer. Updated answer. \$\endgroup\$ – MichaelHouse Apr 23 '14 at 3:55
  • 1
    \$\begingroup\$ I did something like that, i created a new script that set a static variable to true if NGUI has not captured the Input, using UICamera.fallThrough. Then i check that variable, like GUIUtility.hotControl. I was about to post an answer with the solution right before your edit. \$\endgroup\$ – Fr0z3n Apr 23 '14 at 4:06
  • \$\begingroup\$ I don't agree with this answer. Changing the NGUI source-code is definitely a bad idea and will break as soon as there's an update. Using UICamera.fallThrough is how this should be done and should be a part of the accepted answer. \$\endgroup\$ – bummzack Apr 23 '14 at 14:38
1
\$\begingroup\$
  1. Make sure all NGUI components' layers are the same, like "UI".
  2. Attach your UI's NGUI panel with box collider.
  3. Add a script "InputManager.cs" and rewrite function GetMouseButton() like:

    public static bool GetMouseButton(int button)
    {
        if (UICamera.hoveredObject == null) {
            return Input.GetMouseButton(button);
        } else {
            // If click/drop on 2D UICamera, do not send the event to MainCamera.
            // 5 represents layer "UI"
            if (UICamera.hoveredObject.layer == 5) {
                return false;
            }
        }
    
        return false;
    }
    
  4. As the code above, use UICamera.hoveredObject.layer to check whether mouse is on NGUI UI layer, if on UI, GetMouseButton() will return false and MainCamera will not be affected.

  5. Make sure you add box collider to UI in step 2, otherwise UICamera.hoveredObject will be null.

  6. The layer number may be any number you like, not always 5.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.