Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
3
Question by Escapade · Jun 28, 2015 at 01:13 PM · raycastraycasthit

RaycastHit.triangleIndex always returning -1

So I've been looking into how to get the material of a certain triangle on a certain mesh by raycasting and then attempting to get the triangle index and search through the object's submeshes to find the triangle that was hit and thus, it's index which should be used to get the material BUT for some reason I am always getting a "-1" for the triangle index return when raycasting onto my mesh. I looked around and didn't see anyone else with "unity raycast.triangleIndex returning -1" issues so I came here.

Sorry if I missed something someone posted before but thought I'd ask to see if anyone knew what my issue might be. Below is the code I currently have.

 Vector3 HitCoords(){
         //Returns Vector3 of the mouse's click location
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit;
 
         //Raycast to mouse point
         Physics.Raycast (ray, out hit, 100);

             //set burstMaterial to hit triangle's material
     FindTriangleMaterial (hit);
 
         return hit.point;
     }
 
     void FindTriangleMaterial(RaycastHit hit){
         triIndex = hit.triangleIndex;      //<-- this is always -1
         mesh = GetComponent<MeshFilter>().sharedMesh;
         subMeshCount = mesh.subMeshCount;
         matIndex = -1;
 
         for (int i = 0; i < subMeshCount; i++) {
             int[] curTris = mesh.GetTriangles(i);
             for(int j = 0; j < curTris.Length; j++){
                 if(curTris[j] == triIndex){
                     matIndex = i;
                     break;
                 }
             }
         }
         if (matIndex == -1) {
             burstMat = null;
         } else {
             burstMat = GetComponent<Renderer>().materials[matIndex];
         }
     }

Thanks for anyone who can help.

EDIT: So in looking around, I have found that convex mesh colliders wont allow triangleIndex to ever work? I saw nothing on this anywhere else but if this is the case, that's a real bummer. Verification would be much appreciated.

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

5 Replies

· Add your reply
  • Sort: 
avatar image
6
Best Answer

Answer by Bunny83 · Jun 29, 2015 at 01:32 AM

Of course it doesn't work with a convex mesh collider since a convex mesh represents the convex hull of your actual mesh. So it's triangles have no relation to the actual mesh at all. A convex mesh collider also works way different from a normal mesh collider. A convex mesh collider represents a volume while a normal mesh collider just represents a surface.

Keep in mind that you can use two meshcolliders if you want, one convex and one non-convex. Just setup the layers accordingly to define which one can collider with what.

However if your mesh contains submeshes the triangleIndex won't help much i think. The MeshCollider of course doesn't use submeshes. So the triangle index won't tell you to which submesh the triangle belongs.

Your code also makes no sense since you compare the triangle index to a vertex index. The triangle index is simply the position of a triangle within the triangles array divided by 3 (since a triangle is made by 3 vertices)

What you can do is doing something like this (This might even work):

  • use the world space position of your raycast hit point and transform it into local space of your mesh (Transform.InverseTransformPoint).

  • Iterate through all submeshes and through all triangles (take 3 indices at a time)

  • use the vertices array with the 3 indices to get the actual positions of the corners.

  • use the 3 points to calculate the face normal (cross product)

  • use the face normal and one corner of the triangle to project our hit point onto the triangle.

  • Check if the distance between the projected point and the actual hitpoint is very small (so the point actually lays in the plane of the triangle).

  • Calculate the barycentric coordinate of the projected hit point for each triangle. See this post over here

  • With the barycentric coordinate you can easily check if the hitpoint is within the triangle

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 Escapade · Jun 29, 2015 at 03:39 AM 0
Share

Well thanks for clarifying. It seemed like that was the case about convex colliders as being more of just "volumes" but I didn't know for sure so thank you for clarifying. (Rather new to 3D development :D )

Any who, I have decided to not go through with this method because my game involves using non-kinematic rigidbodies and as far as I know, you can't have a non-kinematic, non-convex object in Unity so I'll just make some $$anonymous$$aterial variable that is passed in ins$$anonymous$$d of trying to find the material on a specific triangle of the object. Thanks for the clarification!

PS- To comment on your instructions that seem to be in mush detail and well thought out, thank you as well but that seems to be much too detailed for the simple effect I had in $$anonymous$$d. It seems like it would work but for what I was going to use the triangle-material-lookup for, it's just not worth it from a mobile development standpoint.

avatar image SheZii · Jul 19, 2020 at 02:47 PM 0
Share

Just took my 5-10 $$anonymous$$utes to log in (Coz I don't have access to my registered phone number blah blah) Just to Thank you... You saved me

avatar image
2

Answer by SirLogray · Jul 19, 2017 at 09:38 PM

Just replace your primitive Collider with a MeshCollider. RaycastHit.triangleIndex only works with those.

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 Bunny83 · Jul 19, 2017 at 09:58 PM 0
Share

He didn't use a primitive collider. He used a $$anonymous$$eshCollider. However the $$anonymous$$eshCollider must not be marked as "convex". It should be obvious that you need to use a $$anonymous$$eshCollider in the first place..

avatar image
0

Answer by DiegoSLTS · Jun 28, 2015 at 02:15 PM

Physics.Raycast returns true when the raycast actually hits something. You're not checking this, are you sure there was a hit? Maybe you're using the "hit" variable without any hit happening. Check that return value and maybe add a Debug.Log line to make sure it's hitting what you think it's hitting:

 Debug.Log(hit.rigidbody.name);
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 Escapade · Jun 28, 2015 at 08:04 PM 0
Share

O$$anonymous$$ I will give this a try thanks!

avatar image Escapade · Jun 28, 2015 at 08:16 PM 0
Share

So it returns the rigidbody's name as it should. Something I should probably say is that this script is on the actual object being raycast on. I use an On$$anonymous$$ouseDOwn event that calls the HitCoords() function to find where on this object I just clicked. This might be the issue but I was attempting to keep raycasting confined to each game object as it is clicked.

avatar image
0

Answer by Saravanan_unity · Mar 26, 2019 at 11:13 AM

@Escapade Just Update MeshCollider for each hit. Assign the updated mesh to MeshCollider component. This issue may be solved. but if any others finding for solution my suggestion may be helpful.

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 Es_ · Sep 13, 2020 at 08:44 PM

If there is a rigidbody attached to the transform of the hit meshCollider (non-convex), the meshCollider will not return triangle indexes. Set the rigidbody to isKinematic before raycasting and then back to whatever it was.

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

7 People are following this question.

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

Related Questions

Using raycast and collider to increase int 1 Answer

NullReference when checking tag via Raycast. How to solve this? 1 Answer

Raycast exit point of collider 0 Answers

Detect RaycastHit on Character Controller 2 Answers

Problem with raycast vertical 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