• 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
0
Question by Baumkuchen · Oct 11, 2018 at 11:11 PM · gameobjectrigidbodycolliderchild

Physics.SphereCastAll to get rigidbody's like OnCollisionEnter

Hi, I want to use a Physics.SphereCastAll() to get all Gameobjects (Go's) with a Rigidbody attached to it. But I only get dozent children of the needed Go's .

What i currently do is:

 RaycastHit[] hits = Physics.SphereCastAll(transform.position, 5, transform.forward, 1f, myLayerMask);
     
 foreach (var hit in hits)
 {
        Debug.Log(hit.collider.gameObject.name);
 }


What should i do/use to get only the Go's with rigidbody's?

I cant iterate over the hits array. Because the rigidbody Go doen't have a Collider. So i dont get this Go(s) by SphereCastAll.

And I can't use

 foreach (var hit in hits)
 {
     hit.collider.transform.root.GetComponent<Rigidbody>()
 }

because the Rigidbody is not on the root Transform.

I simply want to have a functionality like OnCollisionEnter() ... this will only give the gameobject's with a rigidbody. But for a point in the world.

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 FlightOfOne · Oct 12, 2018 at 01:13 AM

I am not entirely understanding what your difficulty is but I will try. What is in that hits array is everything it detected, all the colliders. If you want to get the colliders (collider's transform) that has a Rigidbody attached to it you can do exactly what you tried to do but instead of doing 'root' you can do like this:

      foreach (var hit in hits)
      {
          Rigidbody rb=   hit.collider.transform.GetComponentInChildren<Rigidbody>(true);
            Debug.Log(rb.gameObject);
          //true gives you even the ones that are disabled.
      }

This will give you all the GameObjects that have rigidbodies attached to it.

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
0

Answer by Baumkuchen · Oct 12, 2018 at 09:23 AM

Yes that could do it. But is there no way to get the directly hitted Rigidbody's like OnCollisionEnter() does? Another function like Physics.SphereCastAll eventually?

Thanks for your answer!

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 FlightOfOne · Oct 12, 2018 at 01:26 PM 0
Share

OntriggerEnter and OnCollisionEnter do not detect Rigidbodies. It seems that way because ONE of the interacting (e.g the player and a box) objects is REQUIRED to have a rigidbody attached to it, but not both. OnCollision detects the collider, just like the spherecast, no difference. Rigidbodies do not receive hits, it just supports physics aspects of the hit check in Collision. Short answer is no, there's no built in way to find rigidbodies by casting a hit check. What exactly are you trying to accomplish here? $$anonymous$$aybe there is a more efficient way.

avatar image
0

Answer by Bunny83 · Oct 12, 2018 at 01:52 PM

The physics system works with rigidbody object. A rigidbody actually performs the collision detection. Child colliders of a rigidbody belong to the parent rigidbody (known as compound collider). However SphereCastAll only looking for individual colliders. This has nothing to do with rigidbody physics. So you have to manually determine the corresponding rigidbody objects for each collider you've found.


First to get the corresponding Rigidbody of a collider you can use the relatively new GetComponentInParent. It is similar to GetComponentInChildren but the other way round. Instead of searching down the hierarchy it only searches upwards. Though just like GetComponentInChildren it will also search on the object itself. So if the object with the collider has a rigidbody attached, this rigidbody will be returned. If not it will check the parent until it reaches the top (root). The method will return null if there is no rigidbody anywhere in the hierarchy chain upwards.


If you only looking for rigidbodies you can filter out any colliders where GetComponentInParent returns null. For those where you get a rigidbody you would store those rigidbodies somewhere.


The next problem is if a rigidbody has several colliders, you will get the same rigidbody more than once (once for each collider that was found). So you have to filter out duplicates. This all can be easily done with Linq:

 using System.Linq;
 
 // [..]
 
 RaycastHit[] hits = Physics.SphereCastAll(transform.position, 5, transform.forward, 1f, myLayerMask);
 Rigidbody[] rbs = hits.Select(h=>h.collider.GetComponentInParent<Rigidbody>()).Where(r=>r!=null).Distinct().ToArray();

To break this down

hits.Select(h=>h.collider.GetComponentInParent<Rigidbody>()) will return an enumerable which gets the Rigidbody component for each element in hits. Of course as we said earlier this enumeration can contain null values as well as duplicate rigidbodies


.Where(r=>r!=null) creates a filtered enumerable and filters out the null entries. So we only have actual rigidbodies in our collection.


.Distinct() will create a new enumerable with all the duplicates removed. So it only contains distinct values.


Finally .ToArray() will turn the enumerable into an actual array of Rigidbodies. If you just need to iterate over this collection you don't need to create an array. You can directly use the enumerable in a foreach loop. The return type of Distinct in out case is IEnumerable<Rigidbody>. However you may just use var like this

 var rbs = hits.Select(h=>h.collider.GetComponentInParent<Rigidbody>()).Where(r=>r!=null).Distinct();
 foreach(Rigidbody r in rbs)
 {
     // do something with the rigidbody "r"
 }


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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

170 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 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

OnCollisionEnter getting child instead 0 Answers

Mesh renderer does not move with parent rigid body 5 Answers

Ignore Collider 0 Answers

Problem colliding with walls 2 Answers

Should i be able to add gameobjects as children to a parent with a rigidbody? 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