Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by kkrac · May 02, 2017 at 04:32 PM · raycastcanvasui imagephysics.raycastblocking

Block physics raycast on gameobjects if UI element was clicked

  1. There is a "Player" gameobject that has a script attached, that in the Update() evaluates if mouse was clicked with Input.GetMouseButtonDown. If true, it does a physics raycast to move or attack the player gameobject to whichever position was clicked on the screen.

  2. There is also a screen canvas that has a panel at the bottom for the skills bar. The panel has 4 images (ie: 4 slots), one for each skill, and each image has a script that implements IPointerClickHandler to detect a click, like in the following video by @BoredMormon https://www.youtube.com/watch?v=EVZiv7DLU6E

The click on the image is detected Ok. Problem is, that the physics raycast evaluates to true in the player script as well. So when a skill image is clicked, the player also moves/attacks to that position clicked. Is there a way to "block" the physics raycast done in the player script if an image in the skill bar was clicked? The idea is that if an image in the skill bar was clicked, the physics raycast on the terrain (or enemies, or props in the terrain) is ignored.

The way I can think of (haven't tried it yet though) is to move out of graphics raycast to physics raycast for the the UI elements as well, adding colliders to the images, and handling all clicks on the screen (either UI or gameobjects) with Input.GetMouseButtonDown on a script attached to the camera.

Thoughts?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by NatalieBaldwin · May 03, 2017 at 02:19 AM

I can contribute to this because i'm handling my game a little differently from yours. I'm having a very similar issue. My PlayerController script has methods for left click and right click on the ground/enemy/ally that function using physics.raycast. My UI consists of panels and buttons and images with event triggers. My google searches for the past 2 hours have led me to the conclusion that physics.raycast currently implements no easy solution to hit the UI and thus not hit the objects behind the UI. My desired outcome is the same as yours -- I would like the physics.raycast fired when clicking to not hit the objects behind the UI when i'm interacting with the UI. I'm finding a lot of answers how to solve this with every click method except physics.raycast. Seems like something that unity devs will have to add soon.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image OfficialCoatsee · May 03, 2017 at 02:22 AM 0
Share

You are in luck, I'm writing my answer now :D

avatar image
0

Answer by OfficialCoatsee · May 03, 2017 at 02:52 AM

YOU ARE BOTH IN LUCK!

I just solved this last week!

You are correct, @NatalieBaldwin - this isn't something that is FULLY supported just yet.

There is a pretty good work around though, and it is a little tedious.

When you first call your click, and send out your raycast - you can do a check, just like anything, for anything you like.

I do certain checks to...

  1. See if the mouse is inside or outside of certain ALWAYS unclickable in-game areas. So this checks for permanent UI interfaces that are always on the screen.

  2. Check to see if any specific UI is open.

Depending on what is returned from those statements, I decide what to do.

My UI handler consists of a whole heap, so I will narrow it down.

         //<-- start of showing tree options.
         if (showing_tree_options == true) {
             GUI.Label (new Rect(Screen.width / 51.3f, Screen.height / 1.17f, Screen.width / 3.0f, Screen.height / 10.0f), "" + selected_tree_object_name, selectedStyleNormal);
             //collected information from the tree (name), and have now displayed it for the player to see.
             //<-- start of chop option button.
             if (GUI.Button (new Rect (Screen.width / 51.3f, Screen.height / 1.099f, Screen.width / 7.0f, Screen.height / 12.72f), "Chop", selectedTreeChopOption)) {
                 //the chop button was on display, and has now been clicked.
                 player.GetComponent<Player>().setTargetObject(selected_tree_object);
                 player.GetComponent<Player>().setTargetLocation(Vector3.zero);
                 showing_tree_options = false;
             }
             //<-- end of chop option button.
             //<-- start of cancel option button.
             if (GUI.Button (new Rect (Screen.width / 1.89f, Screen.height / 1.099f, Screen.width / 7.0f, Screen.height / 12.72f), "Cancel", standardButton)) {
                 //the cancel button was on display, and has now been clicked.
                 showing_tree_options = false;
             }
             //<-- end of cancel option button.
         }
         //<-- end of showing tree options.


In my example of what I would call after I click, before the RayCast, I would for instance check to see if the UI is enabled.

You can get creative, and have one boolean that is set to true if ANY ui is enabled.

Hope this helps.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image kkrac · May 03, 2017 at 01:54 PM 0
Share

this wouldn't work for me, because in my case the UI is always enabled. It's an action/skill bar always visible at the bottom of the screen. I thought of verifying if the UI was clicked before the Input.Get$$anonymous$$ouseButtonDown, but the Input.Get$$anonymous$$ouseButtonDown (in the Update() methodof the player script) gets executed before the UI click, so that wouldn't help either. I couldn't find any helpful advice in the forums yet so far, but I'm sure there has to be some solution for this, there are probably many games out there with this same use case.

avatar image NatalieBaldwin kkrac · May 03, 2017 at 03:01 PM 0
Share

I think that's exactly what they were saying. If you have UI that is constantly in the same position you can use a few if statements to limit the area of the screen where mouse click fires a raycast. For example, i'm using a side-panning camera scroll. (the camera moves when your mouse is close to the edge of the screen).

if ((Input.mousePosition.x >= Screen.width - mDelta) && (Input.mousePosition.x < Screen.width)) {

With enough of these statements you could carve out an area where it is acceptable to send a raycast. Personally i'm going to save this til later and hope Unity devs fix it up neatly.

avatar image
0

Answer by BBIT-SOLUTIONS · Feb 14, 2018 at 03:22 PM

For touch inputs you can use the following snippet inside Update() as a workaround for this problem, but I think it would also be usable for mouse inputs. Just ensure, that all your UI elements are children of one UI-parent-GameObject.

 if(Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began){                              
             
             //check if touch position is over any active and visible UI object
             foreach(MaskableGraphic uiElement in uiParent.GetComponentsInChildren<MaskableGraphic>()){                 if(uiElement.gameObject.activeInHierarchy && uiElement.enabled){ 
                     Vector2 tmpLocalPoint;
                     RectTransformUtility.ScreenPointToLocalPointInRectangle(uiElement.rectTransform, Input.GetTouch(0).position, null, out tmpLocalPoint); 
                     if(uiElement.rectTransform.rect.Contains(tmpLocalPoint)){                        
                         Debug.Log("Raycast blocked by: " + uiElement.name);
                         return;
                     }    
                     
                 }    
             }

 }

 //Start Raycasting
 RaycastHit hit;
 Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
 if(Physics.Raycast(ray, out hit)){
    //Do your stuff here ...
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

130 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

A canvas to let through a given layer 0 Answers

raycast not hittig anything but charecter 0 Answers

How to offset a RectTransform? 0 Answers

Block some raycasts from world space canvas and ignore others? 0 Answers

PointerEnter / PointerExit gets triggered to the left of the worldspace canvas when swtiching to scene from the different scene 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges