Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 /
avatar image
7
Question by gord0 · Oct 20, 2011 at 07:52 PM · physicsraycastcolliderlayermaskpassthrough

Is it possible to allow a raycast to pass through a collider to hit things behind it?

I have a scenario in which sometimes there's an invisible collider in front of objects that need to be clicked on. It is necessary that this invisible object has a collider. However even using a layermask the invisible object still blocks rays. The layer mask simply stops it from returning true for a collision.

It is not an option to turn on and off the collider of the invisible object at appropriate times as 1 or more objects respond to an OnTriggerExit with the invisible object.

What I need to know is, can I make a ray pass through a collider ignoring it completely until it either hits an intended collider or hits max distance?

Any help is much appreciated : ]

Comment
Add comment · Show 4
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 Veehmot · Oct 20, 2011 at 09:23 PM 0
Share

I have the same question!

avatar image canahari · Feb 05, 2012 at 04:15 PM 0
Share

Hi! I'm fighting with the same problem. Anyone found a solution yet?

avatar image aldonaletto canahari · Feb 06, 2012 at 04:44 AM 1
Share

@Owen Reynolds's answer works fine - but pay attention to the way the mask skip is formed: it's the complement (~) of the layers to be skipped. $$anonymous$$y answer works fine too, but takes a little more time - anyway, it's a solution when you don't want (or can) use different layers.

avatar image Drew_Summy canahari · Jul 10, 2017 at 03:13 AM 0
Share

Look into what a layermask is. It is the fourth argument to an instance of Physics.raycast. Using it is a bit nuanced, but if you read the documentation you will understand it: https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

6 Replies

· Add your reply
  • Sort: 
avatar image
12

Answer by Owen-Reynolds · Oct 21, 2011 at 03:57 PM

I just ran a quick check -- rayCasting through a custom layer (one you create) works just fine. Made four cubes lined up on z, added custom layers 8 and 9 (skip and skip2, but the names don't matter,) lined them up on z and added a raycast script to the start cube:

 Cubes:    start->   wall1    wall2     target
 Layer:    default  skip(8)  skip2(9)   default

 if(Input.GetKey("space")) {
   RaycastHit H;

   // goes through wall1 (layer 8,) hits wall2:
   if(Physics.Raycast(transform.position, transform.forward, out H, 100, ~1<<8))
   Debug.Log(H.transform.name);

   // goes through both walls (layer 8 and 9) and hits target:
   int skip1n2 = ~((1<<8)|(1<<9));
   if(Physics.Raycast(transform.position, transform.forward, out H, 100, skip1n2))
   Debug.Log(H.transform.name);

   // The previous hits ignoreRaycast. This skips 8,9 and ignoreRC(layer 2):
   int skip = ~((1<<8)|(1<<9)|(1<<2));
   if(Physics.Raycast(transform.position, transform.forward, out H, 100, skip))
 }

http://unity3d.com/support/documentation/Components/Layers.html has the official example.

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 gord0 · Oct 21, 2011 at 12:16 AM 0
Share

I understand bit shifting, what I was trying to do simply didn't work until i used unity's build in ignore raycast layer.

avatar image
6

Answer by aldonaletto · Oct 21, 2011 at 03:10 AM

I can think of a few solutions for this problem:

1- Disable the "forbidden" object's collider, do the raycast and enable the collider. If you do this in the same function, nobody else will be affected. This may be a solution when you have only one forbidden object, but can be awkward if there are several of them.

2- Use RaycastAll: it returns an array with all hits, and you can ignore the forbidden objects until you find a valid one. This is more time expensive, specially if the raycast is infinite or too long:

 var hit: RaycastHit; // the hit info (if any) will be returned here
 var nonoTag: String; // define the forbidden tag here
 
 // specify the ray and the max distance 
 function XRaycast(ray: Ray, dist: float): boolean {
     var hits = Physics.RaycastAll(ray, dist); // get all hits
     for (hit in hits){ // check hits until a valid one is found
         if (hit.collider.tag != nonoTag) return true;
     }
     // if no valid hit found, return false
     return false;
 }


3- Do a Raycast and check the object hit: if it's a forbidden one, change the origin to the hit.point plus a little offset in the ray.direction, and repeat the process. This can be done recursively until a valid object is found or the ray hits nothing.
The function below can do this: it does successive Raycasts while finding forbidden objects. If some valid object is found, it returns true; if there are no valid objects, returns false.

 var hit: RaycastHit; // the hit info (if any) will be returned here
 var nonoTag: String; // define the forbidden tag here
 
 // specify the ray and the max distance 
 static function XRaycast(ray: Ray, dist: float): boolean {
     if (!Physics.Raycast(ray, hit, dist)) return false; // return false if nothing found
     if (hit.collider.tag != nonoTag) return true; // return true if valid obj found
     var end = ray.GetPoint(dist);             // if invalid object hit, set a new
     ray.origin = hit.point+0.1*ray.direction; // ray origin 0.1 ahead of the hit.point
     dist = Vector3.Distance(end, ray.origin); // update the max distance...
     return XRaycast(ray, dist);               // and call itself
 }




Comment
Add comment · Show 4 · 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 Drew_Summy · Jul 09, 2017 at 12:20 AM 0
Share

Wwith number 1, shouldn't we be careful about multi-threading?

avatar image Bunny83 Drew_Summy · Jul 10, 2017 at 03:16 AM 0
Share

You can't use multi threading at all in this case as the Unity API is not thread safe. A Raycast can only be executed from the main thread. Furthermore almost all gameobject / transform properties can't even be read from another thread. Unity implemented a check into most API methods / properties which will throw an exception if you try to use it from another thread.

avatar image Drew_Summy Bunny83 · Jul 10, 2017 at 03:40 AM 0
Share

Well that simplifies everything quite a bit. So, you are saying there is no multithreading in unity at all? How do programs run fast enough?

Show more comments
avatar image
1

Answer by Ziad · Oct 20, 2011 at 09:37 PM

Yeah sure just give it a layerMask

Something like this

         if (Physics.Raycast(ray, out hit, Mathf.Infinity, myLayerMask))
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 gord0 · Oct 20, 2011 at 10:06 PM 0
Share

Actually that's the way I spent an hour failing to make work. I came to find out that unity has it's own built in layer called "ignore raycast". I set said invisible object to that layer.

$$anonymous$$aking my own custom layers and separating the object that way does not work. The ray still hits the invisible object and does not continue past it. All that happens is the raycasthit returns false ins$$anonymous$$d of true.

avatar image Owen-Reynolds · Oct 20, 2011 at 11:16 PM 1
Share

Layermask is what you can HIT, not skip. To skip layer 12, say, use ~(1<<12) as the layer$$anonymous$$ask (the notes on Layer$$anonymous$$ask have an example and explain it.)

It sort of makes sense if you know that the traditional programmer's definition of a $$anonymous$$ask is often picking things you don't like (you mask them off.)

avatar image
1

Answer by Cornelis-de-Jager · Jul 10, 2017 at 03:04 AM

HI,

I struggled with this for a long time. And I finally found how to do it so it works every time. but first for your solution you can set the layer of the object to be ignored to "IgnoreRaycast", however, you do not always want this. So here is the correct way

 // Create Ray
 Ray ray = new Ray( transform.position, transform.forward);
 
 // Hit info
 RaycastHit hit;
 
 // Layer to hit / Layer to ignore
 string nameOfLayer = "InvisObjectLayer";
 
 /**
 * Note that we use ` ~ ` sign if we want the opposite. 
 * So we want all the layers accept that particular one. 
 * If we only want to cast to one layer just remove the ` ~ ` sign
 */
 LayerMask layer =  ~(1 << LayerMask.NameToLayer(nameOfLayer )); 
 
 // Do the raycast - Use if Statement to automatically check if there was a hit
 
 /** IMPORTANT
 *  We must use the Mathf.Infinty statement. Unity does not have a
 * function that accepts only a ray, hitInfo and layer!
 */
 if (Physics.Raycast (ray, out hit, Mathf.infinity, layer)) {
      if (hit.transform.tag == "Player")...
 }
 
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
avatar image
-1

Answer by mast3rillusion · Feb 27, 2015 at 07:38 AM

For C-Sharp:

Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));

RaycastHit hit;

int layerMask = 1 << 4;//setting the layer mask to layer 4 (water in my case)

layerMask = ~layerMask;//setting the layer mask to "ignore" layer (~)

if (Physics.Raycast(ray, out hit, maxInteractionRange, layerMask))//adding in the layer mask to the raycast and it WILL ignore the 4th layer!

{

//your code 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
  • 1
  • 2
  • ›

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

13 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

Related Questions

Colliders attached to objects on separate layers are colliding? 1 Answer

Melee-like function? 1 Answer

Prevent shooting when gun is inside wall 1 Answer

Raycast hits when missing a collider, misses when hitting a collider? 0 Answers

Surface with hole and Raycast - Which collider 1 Answer


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