Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Material from Triangle

Discussion in 'Scripting' started by Crapcutter, Jul 16, 2008.

  1. Crapcutter

    Crapcutter

    Joined:
    Jun 4, 2008
    Posts:
    10
    Hi,

    I'm trying to write a script that will allow me to retrieve a material as indicated by a mouse click.

    The idea is to be able to allow an imported 3D model to use named Materials to indicate different functional areas.

    I can get the triangle from a RaycastHit, but I am struggling to go from this to the associated Material object that provides the texture for the hit triangle.

    Seems like it should be straightforward, but the path isn't immediately obvious right now.
     
  2. Crapcutter

    Crapcutter

    Joined:
    Jun 4, 2008
    Posts:
    10
    Okay, this seems to work. If anyone has any ideas to improve it, please let me know. I attach this script to models imported with mesh colliders.

    Code (csharp):
    1. function OnMouseDown () {
    2.     var go : GameObject = GameObject.Find("First Person Controller/Main Camera");
    3.     var cam : Camera = go.camera;
    4.    
    5.     var hit : RaycastHit;
    6.     if (!Physics.Raycast (cam.ScreenPointToRay(Input.mousePosition), hit))
    7.         return;
    8.    
    9.     var mat : Material = findRaycastMaterial(hit);
    10.    
    11.     if (mat != null) {
    12.         print("HIT on " + mat.name);
    13.     }
    14. }
    15.  
    16. function findRaycastMaterial(hit : RaycastHit) {
    17.     // Just in case, also make sure the collider also has a renderer
    18.     // material and texture
    19.     var meshCollider = hit.collider as MeshCollider;
    20.     if (meshCollider == null || meshCollider.sharedMesh == null)
    21.         return;
    22.  
    23.     var mesh : Mesh = meshCollider.sharedMesh;
    24.     var triangles = mesh.triangles;
    25.  
    26.     // Extract vertices indices that were hit
    27.     var v0 = triangles[hit.triangleIndex * 3 + 0];
    28.     var v1 = triangles[hit.triangleIndex * 3 + 1];    
    29.     var v2 = triangles[hit.triangleIndex * 3 + 2];  
    30.  
    31.     for (var m = 0; m <  renderer.materials.length; m++) {
    32.         var mts = mesh.GetTriangles(m);
    33.         for (var i = 0; i < mts.length; i += 3) {
    34.             if (mts[i] == v0  mts[i+1] == v1  mts[i+2] == v2) {
    35.                 return renderer.materials[m];
    36.             }
    37.         }
    38.     }
    39.    
    40.     return null;
    41. }
    42.  
    Does it make sense to expect the order of the vertices to be the same for the mesh and the material triangles?
     
    Raumgleiter likes this.
  3. Omar Rojo

    Omar Rojo

    Joined:
    Jan 4, 2007
    Posts:
    494
    Just a thought .. why don't you separate your object into diferent objects to represent those areas ?

    .org
     
  4. Crapcutter

    Crapcutter

    Joined:
    Jun 4, 2008
    Posts:
    10
    The idea is to try and make it as simple as possible to add an imported object, and to allow the modeler to create the model in the most convenient way.

    At present I am still investigating the best approach, but I wanted to see if it is feasible to use named materials as an alternative to requiring distinct objects.
     
  5. mocoda

    mocoda

    Joined:
    Aug 20, 2008
    Posts:
    29
    Hi

    I've just come across a similar problem where i need to detect the texture below a car driving on a terrain. Tried your neat function (thanks for posting it) upon a Raycast but it didn't work for a terrain object as it seems there is no renderer material for terrain objects (i'm very new to Unity so this is still all a bit mysterious).

    I was wondering how you'd got on developing around this problem and if you had any further insights - or if you knew how to detect textures within a terrain?

    My post is up at http://forum.unity3d.com/viewtopic.php?p=91048

    Thanks in advance
    Paul
     
  6. Crapcutter

    Crapcutter

    Joined:
    Jun 4, 2008
    Posts:
    10
    I suspect you can find the height of the terrain from a global x y, and then from that determine the texture. Probably a Raycast is not required.

    Just thought I'd float that suggestion so that someone more informed can clarify ;-)
     
  7. mocoda

    mocoda

    Joined:
    Aug 20, 2008
    Posts:
    29
    Thanks for the tip... however the terrain we've developed has ice/sand/grass at varying heights so couldn't base the surface purely on global y.

    If anyone else has any ideas - or even just to let us know i'm wasting my time as you just can't get at material information at a co-ordinate in terrains.

    Cheers
    Paul
     
  8. mia

    mia

    Joined:
    Dec 31, 2007
    Posts:
    83
    i would imagine you could query the terrains splat map to obtain the color/texture at a given location.