Anyway to ignore raycast collision on other gameObjects?

Anyway to ignore raycast collision on other gameObjects?

Postby jiweigame » Sat Aug 07, 2010 11:58 am

Say I have several buttons on the screen and have an orthographic camera as the specific gui Camera. Now the problem is when I hit the GUI Button, the raycast also hit other gameObjects in the scene, causing some unwanted command processing(We have Diable-like movement, hit the ground and move character to the desired position). Is there anyway to ignore other hits when you hit a GUI button?
jiweigame
 
Posts: 8
Joined: Fri Aug 06, 2010 10:50 am

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Brady » Sat Aug 07, 2010 9:00 pm

Yes, this is where you need to set your UIManager's "Mouse and Touch Mask" to just the layers you're using for your GUI elements. And then make sure all your GUI elements are in those layers.
Brady
 
Posts: 5361
Joined: Tue Jul 06, 2010 11:33 pm

Re: Anyway to ignore raycast collision on other gameObjects?

Postby jiweigame » Sun Aug 08, 2010 9:10 am

Thanks for your quick reply. The way you recommended seems no help to my problem. Because in my game I have two cameras, one is the Main Camera always locking on my character, and the other is the GUI Camera. When I click on a gui button, there will be two raycast triggered. One is in your EZ gui system, one is from my own game system, using Main Camera to do raycast and hit any target in the game scene. So is there any convenient way to disable other mouse events when I hit any EZ GUI elements?
jiweigame
 
Posts: 8
Joined: Fri Aug 06, 2010 10:50 am

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Brady » Sun Aug 08, 2010 8:57 pm

Ahh, I see what you mean. You're doing your own separate input processing, which duplicates it. I get it now.

Yes, fortunately EZ GUI anticipates this sort of situation. You can let EZ GUI do the input checking once for all your game needs, and then have it pass this information to you in the event that the pointer does not "hit" an EZ GUI control. Use the UIManager's SetNonUIHitDelegate() method like so:

Code: Select all
UIManager.instance.SetNonUIHitDelegate(MyDelegate);

...

void MyDelegate(POINTER_INFO ptr)
{
   // Check the pointer's ray (from the UI camera(s)):
   Physics.Raycast(ptr.ray);

   // Get the pointer's screen coordinates:
   ptr.devicePos;

   // Etc...
}


See the EZ GUI docs for all the various information stored in the POINTER_INFO struct. To summarize, EZ GUI polls the mouse/touchpad every frame, and if any of these pointers do not "hit" an EZ GUI element, these get passed to the aforementioned delegate. If they do hit an EZ GUI element, the delegate will not be notified.
Brady
 
Posts: 5361
Joined: Tue Jul 06, 2010 11:33 pm

Re: Anyway to ignore raycast collision on other gameObjects?

Postby jiweigame » Mon Aug 09, 2010 2:52 am

Thanks, man! That fixed my problem.
jiweigame
 
Posts: 8
Joined: Fri Aug 06, 2010 10:50 am

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Little Angel » Wed Sep 22, 2010 8:13 am

There has been some discussion on how to do this explicitly. - So, if someone were to spell this out loud and clear, like a tourist talking to someone without knowing the language... Slow and Loud, would it be:

- Remove (or protect) all of your previous code that reacts to input.
- Set this NotUIHitDelegate on the UI Manager.
- Replace all of your code here within the NonUIHitDelegate (or put pointers to the methods from that original code here)...

Correct?
Little Angel
 
Posts: 772
Joined: Thu Sep 02, 2010 10:23 pm

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Brady » Wed Sep 22, 2010 8:30 am

Yes, if you have code that is doing system-level input polling, then you're going to get ALL input events - whether they were part of an interaction with an EZ GUI control or not. To only get notified of the input that is not part of the user using the UI, you will need to remove that polling code. Instead, where you are polling for, say, touches, you want to instead move your input handling code into the delegate you define such as the one shown in the above example. So instead of polling the actual device (or using Unity's input methods), just take the POINTER_INFOs as they come in to the delegate one by one. All pointer events that don't "hit" a control will get passed through this delegate.

You can now do your swipe detection, ray casts, or whatever else, with the info about the input event contained in the POINTER_INFO struct inside the delegate method.
Brady
 
Posts: 5361
Joined: Tue Jul 06, 2010 11:33 pm

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Little Angel » Wed Sep 22, 2010 8:54 am

So, I'm curious now, rather than just clarifying a point... I've just cracked open a script that I'll eventually need to have its functionality (if not its code) play with EZG, and I want to see this for myself.

Scripts the previously relied on an "Update()"...

I assume that this NonUIHitDelegate will be called every frame that there is non-UI input, so ... when "translating" a script from a stand-alone form to the NonUIHitDelegate, you can abandon the Update() and go straight to the core of the code, no?

Take this code (modified from standard assets to require the mouse to be down and slightly optimized):
Code: Select all
[AddComponentMenu("Camera-Control/Mouse Down Look")]
public class MouseDownLook : MonoBehaviour {

   public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
   public RotationAxes axes = RotationAxes.MouseXAndY;
   public float sensitivityX = 15F;
   public float sensitivityY = 15F;

   public float minimumX = -360F;
   public float maximumX = 360F;

   public float minimumY = -60F;
   public float maximumY = 60F;

   float rotationX = 0F;
   float rotationY = 0F;
   
   Quaternion originalRotation;
   
   void Start () {
      // Make the rigid body not change rotation
      if (rigidbody)
         rigidbody.freezeRotation = true;
      originalRotation = transform.localRotation;
   }

   void Update () {
      if (Input.GetMouseButton(0)) {                                       //   Require that the main mouse button is down
         switch (axes) {
            case RotationAxes.MouseXAndY:
//            if (axes == RotationAxes.MouseXAndY) {
               // Read the mouse input axis
               rotationX += Input.GetAxis("Mouse X") * sensitivityX;
               rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
      
               rotationX = ClampAngle (rotationX, minimumX, maximumX);
               rotationY = ClampAngle (rotationY, minimumY, maximumY);
               
               Quaternion xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
               Quaternion yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
               
               transform.localRotation = originalRotation * xQuaternion * yQuaternion;
            break;
            
            case RotationAxes.MouseX:
//            } else if (axes == RotationAxes.MouseX) {
               rotationX += Input.GetAxis("Mouse X") * sensitivityX;
               rotationX = ClampAngle (rotationX, minimumX, maximumX);
      
               xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
//               Quaternion xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up);
               transform.localRotation = originalRotation * xQuaternion;
            break;
            
            case RotationAxes.MouseY:
//            } else {
               rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
               rotationY = ClampAngle (rotationY, minimumY, maximumY);
      
               yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
//               Quaternion yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left);
               transform.localRotation = originalRotation * yQuaternion;
//            }
            break;
         }   
      }
   }
   
   public static float ClampAngle (float angle, float min, float max) {
      if (angle < -360F)
         angle += 360F;
      if (angle > 360F)
         angle -= 360F;
      return Mathf.Clamp (angle, min, max);
   }
}


I am assuming that one can just put this code within the NonUIHitDelegate?

(I may have answered this by the time someone gets to it, but it's helping me think... and it's distracting me from other pain and anquish...)
Little Angel
 
Posts: 772
Joined: Thu Sep 02, 2010 10:23 pm

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Little Angel » Wed Sep 22, 2010 9:04 am

Hum... by putting everything under one roof, as it were, it does contain it, but it also does make things a bit complicated. I'll have to think this one through.

I the case of the code above, I have two instances of it. One controlling the y pivot axis on what is essentially the player, and one controlling the x pivot axis on a different child object so I can control the pivot location.

I wasn't planning on solving this today, like I said, but I'm distracted now...

Time to do some mental origami.
Little Angel
 
Posts: 772
Joined: Thu Sep 02, 2010 10:23 pm

Re: Anyway to ignore raycast collision on other gameObjects?

Postby Brady » Wed Sep 22, 2010 10:13 am

I think you basically want to replace those "GetAxis()" calls with something like:

rotationY += ptr.inputDelta.y * sensitivityY;

And to see if the mouse button is held down in this case, just check the ptr.active flag. If it's true (active), then the touch/mouse is being held down.
Brady
 
Posts: 5361
Joined: Tue Jul 06, 2010 11:33 pm

Next

Return to EZ GUI General

Who is online

Users browsing this forum: No registered users and 4 guests