Finding the polygon/face your'e currently looking at?

So Im trying to find the face of the object instance im looking at but I cant work out how to go about doing it

ive got a script attached to my object so OnMouseEnter get the transform of it and make it the selected object then OnMouseExit reset the the selected object to null

say if i my mouse cursor was over the top face/polygon how would i find that out?

raycasting? (not educated on raycasting but i did a little search and im guessing its this)

would someone be able to explain the logic or maybe give me a quick example or a link to a tutorial

all help appreciated

thanks!

Hi there. :)

An explanation of raycasts: Raycasts are systems that when called are given a number of variables. One of these variables is actually a reference, and what handles the data returned by the hit. Physics.Raycast returns a bool statiing if it hit, but it is also fed a variable of type RaycastHit, which after the raycast, is fed with data.

Raycasts can come in two forms.

Form one is calling Physics.Raycast, and passing the directional values there. Form two is pre-creating the raycast, and then calling Physics.Raycast, replacing all of the inputs with parameters from the Ray object.

You want the latter. Why?

There exists a function called ScreenPointToRay, which creates an object of type Ray that can be used in Physics.Raycast. When this ray gets fired, it will hit exactly whatever the camera is looking at (Or what your mouse is over, if you feed it the mouse's position).

RaycastHit contains a variable, which is the index of the tri on the mesh you hit. I believe that is what you are looking for.

Putting this all together [Based on examples in the doc]:

c#

using UnityEngine;
using System.Collections;

public class DoMyRay : MonoBehaviour
{
    void Update()
    {
        //This generates our ray. We input the positions x, and y, as screen height and width divided by two to send a ray towards whatever the
        //screen center is viewing.
        //Camera.main is a static var, capable of being accessed from any code without references.
        Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2, 0));

        //This defines a RaycastHit object. Its information is filled out if Physics.Raycasthit actually hits.
        RaycastHit hit = new RaycastHit();

        //This uses the ray's parameters to call physics.raycast. Mathf.Infinity is the distance the raycast will go before giving up. [Don't worry, distances of this size cause no lag].
        //We specify 'out' as that is just how c# rolls. [It goes into variable references, ETC. All of this is automagic in JS]
        if (Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity))
        {
            //This is not necissarry. All it does is visualize in 3D what the camera is looking at. hit.Distance is how far the raycast got before
            //Hittign soemthing. It functions as how far away we will draw the ray.
            Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.red);

            //This is the index of the tri the camera is looking at:
            int ind = hit.triangleIndex;

            Debug.Log("Hit tri index is " + ind*3);

        }
    }
}

JS:

  function Update()
{
    //This generates our ray. We input the positions x, and y, as screen height and width divided by two to send a ray towards whatever the
    //screen center is viewing.
    //Camera.main is a static var, capable of being accessed from any code without references.
    var ray : Ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2, 0));

    //This defines a RaycastHit object. Its information is filled out if Physics.Raycasthit actually hits.
    var hit : RaycastHit = new RaycastHit();

    //This uses the ray's parameters to call physics.raycast. Mathf.Infinity is the distance the raycast will go before giving up. [Don't worry, distances of this size cause no lag].
    if (Physics.Raycast(ray.origin, ray.direction, hit, Mathf.Infinity))
    {
        //This is not necissarry. All it does is visualize in 3D what the camera is looking at. hit.Distance is how far the raycast got before
        //Hittign soemthing. It functions as how far away we will draw the ray.
        Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.red);

        //This is the index of the tri the camera is looking at:
        var ind : int = hit.triangleIndex;

        Debug.Log("Hit tri index is " + ind * 3);
    }
}

An explanation to meshes:

Meshes in Unity are defined by a number of data arrays. These arrays are:

UV1 -- Used for texture mapping. Very confusing, I won't bother explaining.

UV2 -- Works the same way, used for lightmappy

Vertices -- Used to define geometry "waypoints" which faces snap to

Triangles -- Defines tries and which vertices they snap to.

Vertices -- Vertices are 3D points in space which cannot be seen. They define the waypoints that faces -- AKA tris -- CAN cover. Most 3D modeling applications allow faces to be quads (four-side faces) but in Unity they all have to be three sided (tris).

mesh.triangles is a power of three array. That means that the number of elements in this array will always be devisable by three. Why is it this way?

Every three elements in the tris array belong to the same tri. To visualize it:

In a cube:

Vertices: Index :Value 0 :Vector3(0,0,0)

1 :Vector3(1,0,0)

2 :Vector3(0,1,0)

3 :Vector3(1,1,0)

4 :Vector3(0,0,1)

5 :Vector3(1,0,1)

6 :Vector3(0,1,1)

7 :Vector3(1,1,1)

These are points in 3D space relative to the object using the mesh.

Tris (This is a shortened version, does not visuallize WHOLE cube):

This specifies a face that spans the gap between the vertex positions at indexes 0, 1, and 2:

Index: Value

0: 0

1: 1

2: 2

IF a mesh were to have two tris making a quad, it would look like this:

0: 0

1: 1

2: 2

3: 3

4: 1

5: 2

Assuming the verts were layed out properly. Each of those values in the triangles array points to a vertice in the vertices array. It it's self points to a place in 3d space. Every three elements in the tris array represents the pointers to the three vertices in each tri.

I was wrong in thinking that hit.triangleIndex directly pointed to one of these indexes. Instead, it points to the tris as a whole. So, if the index were 0, it would point to triangle indexes 0, 1, 2. If it is 1, it woudl point to 3, 4, and 5. If it were 2, it would point to 6, 7, and 8.

Likewise, multiplying the hit index by 3 allows you to gather the precise index of the first element in the tri ti points to. For instance, because the returned value 2 points to 6, 7, and 8, multiplying 2x3 returns 6, which is the first index it points to.

Explanation to meshes in general:

3D geometry works similarly. When you model something, you create vertices [which in the modeler you can see.] You then select various vertices and tell the mesh a face exists between them. When you do that, you are basically making a triangle, and the three corners on that triangle touch the three vertices you chose.. Just in 3D.

Unity's arrays are just optimized ways of expressing those decisions in 3D modeling. A square face is just two triangles working together to define a square.

You can get the direction the face of an object is facing using Unity’s Raycast class,
example:

RaycastHit Hit;
Hit.normal; // it is a Vector3 quantity

//for X - axis :
Hit.normal.x;

//for Y - axis :
Hit.normal.y;

//for Z - axis :
Hit.normal.z;

This will only give you the direction the face in facing in world space.
for example if it is facing in the positive Z direction, it will return a Vector3,
(0, 0, 1)
where the z value is positive.