Monday, June 13, 2016

c# - Unity Array Index Is Out Of Range Raycast triangleIndex


I just tried the script from the official unity documentation here https://docs.unity3d.com/ScriptReference/RaycastHit-triangleIndex.html , the script is working at some point :


Working 1



But unity throw error "Array index is out of range" more often than successful click if i click at random place in 1 gameobject ( Cylinder ) :


[ i replay the game and do 5 click , see the error count at the debugger ]


Error 1


This is my script ( not important it is almost same with the documentation , but i just put it , and i removed some part to make it shorter) :


    RaycastHit thehit;
if (Input.GetMouseButtonDown (0) && methodoneenabled == true) {
Ray theray = Camera.main.ScreenPointToRay (Input.mousePosition);

if (Physics.Raycast (theray, out thehit)) {
Debug.Log ("raycast work");

if (thehit.collider != null) {
string thedebug = "Hit : " + thehit.collider.gameObject.name + " ";

MeshCollider themeshhittwo = thehit.collider.gameObject.GetComponent ();
if (themeshhittwo == null) {
Debug.Log (" | themeshhittwo == null ! | ");
} else {

Debug.Log (" | " + thehit.triangleIndex + " | ");


Mesh mesh = themeshhittwo.sharedMesh;
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
Vector3 p0 = vertices [triangles [thehit.triangleIndex * 3 + 0]];
Vector3 p1 = vertices [triangles [thehit.triangleIndex * 3 + 1]];
Vector3 p2 = vertices [triangles [thehit.triangleIndex * 3 + 2]];
Transform hitTransform = thehit.collider.transform;
p0 = hitTransform.TransformPoint (p0);
p1 = hitTransform.TransformPoint (p1);
p2 = hitTransform.TransformPoint (p2);

Debug.Log (" | " + p0 + " ; " + p1 + " ; " + p2 + " | ");
Debug.DrawLine (p0, p1);
Debug.DrawLine (p1, p2);
Debug.DrawLine (p2, p0);
}
}
}
}

My script can be run so tell me if i missed some part when copying and pasting .



Can anyone tell me what is the wrong part and the cause of the error at the script ? -,- though the script is official script ....


Edit : the script i shared is located at CameraScript.Update()
Edit : the error is located at


    Vector3 p0 = vertices [triangles [thehit.triangleIndex * 3 + 0]];      

but mostly will available at here too


    Vector3 p1 = vertices [triangles [thehit.triangleIndex * 3 + 1]];
Vector3 p2 = vertices [triangles [thehit.triangleIndex * 3 + 2]];

Edit : i found out that the error appear if i click the middle of the cylinder , and work well if i click near the corner of the cylinder ( not the corner ! ) , also it is work well at plane mesh without error , but what was causing it -,- .....




Answer



You've already printed all the info you need - it's right there in your console output.


Your hit.triangleIndex is -1.


Since C# arrays start at 0, this will always be out of range.


So, why would Unity give you a value of -1 here? Because you didn't hit a triangle!


You've set up your cylinder with two colliders on it: a CapsuleCollider and a MeshCollider. MeshColliders have triangles, but CapsuleColliders don't.


Your ray hits the CapsuleCollider most of the time (since it's round, it tends to stick out beyond the facets of the polygonal surface), but then instead of working with the collider you actually hit, you've changed the Unity example script to use GetComponent to grab the MeshCollider, even if it's not the one you hit. This is not a safe thing to do.


If you want to ensure you hit the MeshCollider, you can do a few different things (in order from simplest to most laborious...):





  • Remove the CapsuleCollider




  • Put the CapsuleCollider and MeshColider into separate child objects of the cylinder, and put each onto a different physics layer. Then you can use a layermask with your raycast to select just the mesh's layer.




  • Use RayCastAll to tunnel through your first colision and hit the next one to (and the next, and the next...) then you can search through the results array for the first one that hit a MeshCollider




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...