Skip to content

Instantly share code, notes, and snippets.

@newpolaris
Last active April 24, 2025 09:46
Show Gist options
  • Save newpolaris/bcc26e03e7278f83551a51854ce106b9 to your computer and use it in GitHub Desktop.
Save newpolaris/bcc26e03e7278f83551a51854ce106b9 to your computer and use it in GitHub Desktop.

Revisions

  1. newpolaris revised this gist May 23, 2021. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
  2. newpolaris created this gist May 23, 2021.
    204 changes: 204 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,204 @@
    // Editor script that displays the number and UV coordinates of each individual vertex making up a triangle within a mesh
    // To install, place in the Assets folder of a Unity project
    // Open via Window > Show Vertex Info
    // Author: Luke Gane
    // Last updated: 2015-02-07

    using UnityEditor;
    using UnityEngine;

    public class ShowVertexNumber : EditorWindow {

    Mesh curMesh;
    MeshFilter curMeshFilter;
    SkinnedMeshRenderer curSMR;
    bool meshAvailable = false;
    bool displayAll = true;
    int curFace = 0, numFaces = 0, newFace = 0;

    GUIStyle centredStyle = null;

    Vector3 p1, p2, p3;

    [MenuItem("Window/Show Vertex Info")]
    public static void ShowWindow(){
    EditorWindow.GetWindow(typeof(ShowVertexNumber)); // Show existing window instance; if one doesn't exist, it is created
    }

    void OnEnable(){

    // See http://answers.unity3d.com/questions/58018/drawing-to-the-scene-from-an-editorwindow.html
    if (SceneView.onSceneGUIDelegate != this.RenderStuff){ // This appears to be a sufficient check
    SceneView.onSceneGUIDelegate += this.RenderStuff;
    }

    OnSelectionChange();
    }

    void OnDestroy(){
    SceneView.onSceneGUIDelegate -= this.RenderStuff;
    }

    void OnSelectionChange(){

    bool noMesh = true;

    if (Selection.activeGameObject){
    curMeshFilter = Selection.activeGameObject.GetComponentInChildren<MeshFilter>();
    if (curMeshFilter){
    curMesh = curMeshFilter.sharedMesh;
    meshAvailable = true;
    numFaces = curMesh.triangles.Length/3;
    noMesh = false;
    }
    else{
    curSMR = Selection.activeGameObject.GetComponentInChildren<SkinnedMeshRenderer>();
    if (curSMR){
    curMesh = curSMR.sharedMesh;
    meshAvailable = true;
    numFaces = curMesh.triangles.Length/3;
    noMesh = false;
    }
    }
    }

    if (noMesh){
    meshAvailable = false;
    numFaces = 0;
    }

    curFace = 0;
    newFace = curFace;

    Repaint();
    }

    void OnInspectorUpdate(){
    Repaint();
    }

    void OnGUI(){

    if (meshAvailable){

    EditorGUILayout.LabelField("Number of faces: ", numFaces.ToString());
    EditorGUILayout.LabelField("Current face index: ", curFace.ToString());

    newFace = EditorGUILayout.IntField("Jump to face index: ", curFace);
    if (newFace != curFace){
    if (newFace >= 0 && newFace < numFaces){
    curFace = newFace;
    }
    }

    EditorGUILayout.BeginHorizontal();

    if (GUILayout.Button ("Prev Face")){
    curFace = (curFace-1) % numFaces;
    if (curFace < 0){
    curFace = curFace + numFaces;
    }
    }

    if (GUILayout.Button ("Next Face")){
    curFace = (curFace+1) % numFaces;
    }

    EditorGUILayout.EndHorizontal();

    EditorGUILayout.Space();

    EditorGUILayout.LabelField("Index of red vertex: ", curMesh.triangles[curFace*3].ToString());
    EditorGUILayout.LabelField("Index of green vertex: ", curMesh.triangles[curFace*3 + 1].ToString());
    EditorGUILayout.LabelField("Index of blue vertex: ", curMesh.triangles[curFace*3 + 2].ToString());

    EditorGUILayout.Space();

    EditorGUILayout.LabelField("UV coords red vertex: ", "(" + curMesh.uv[curMesh.triangles[curFace*3]].x.ToString() + ", " + curMesh.uv[curMesh.triangles[curFace*3]].y.ToString() + ")");
    EditorGUILayout.LabelField("UV coords green vertex: ", "(" + curMesh.uv[curMesh.triangles[curFace*3 + 1]].x.ToString() + ", " + curMesh.uv[curMesh.triangles[curFace*3 + 1]].y.ToString() + ")");
    EditorGUILayout.LabelField("UV coords blue vertex: ", "(" + curMesh.uv[curMesh.triangles[curFace*3 + 2]].x.ToString() + ", " + curMesh.uv[curMesh.triangles[curFace*3 + 2]].y.ToString() + ")");

    }
    else{
    EditorGUILayout.LabelField("Current selection contains no mesh.");
    }
    }

    // Analogous to OnSceneGUI message handler of the Editor class
    void RenderStuff(SceneView sceneView){
    if (displayAll && meshAvailable) {
    for (int i = 0; i < numFaces*3; i++) {
    int index1 = curMesh.triangles[i];
    if (curMeshFilter){
    p1 = curMeshFilter.transform.TransformPoint(curMesh.vertices[index1]);
    }
    else if (curSMR){
    p1 = curSMR.transform.TransformPoint(curMesh.vertices[index1]);
    }
    Handles.color = Color.clear;
    Handles.DotCap(0, p1, Quaternion.identity, 0.10f*HandleUtility.GetHandleSize(p1));

    if (centredStyle == null){
    centredStyle = new GUIStyle(GUI.skin.label);
    centredStyle.normal.textColor = Color.white;
    centredStyle.fixedWidth = 10; // If you regularly inspect meshes with more than 999 vertices you may wish to increase this value
    centredStyle.fixedHeight = 10;
    centredStyle.alignment = TextAnchor.MiddleCenter;
    // centredStyle.normal.background = Texture2D.whiteTexture; // For reference, whiteTexture is 4x4 (not particularly relevant here)
    centredStyle.fontSize = 12;
    centredStyle.clipping = TextClipping.Overflow;
    }

    Handles.Label(p1, index1.ToString(), centredStyle);
    }
    sceneView.Repaint();
    }
    else if (meshAvailable) {

    int index1 = curMesh.triangles[curFace*3];
    int index2 = curMesh.triangles[curFace*3 + 1];
    int index3 = curMesh.triangles[curFace*3 + 2];

    if (curMeshFilter){
    p1 = curMeshFilter.transform.TransformPoint(curMesh.vertices[index1]);
    p2 = curMeshFilter.transform.TransformPoint(curMesh.vertices[index2]);
    p3 = curMeshFilter.transform.TransformPoint(curMesh.vertices[index3]);
    }
    else if (curSMR){
    p1 = curSMR.transform.TransformPoint(curMesh.vertices[index1]);
    p2 = curSMR.transform.TransformPoint(curMesh.vertices[index2]);
    p3 = curSMR.transform.TransformPoint(curMesh.vertices[index3]);
    }

    Handles.color = Color.red;
    Handles.DotCap(0, p1, Quaternion.identity, 0.25f*HandleUtility.GetHandleSize(p1));
    Handles.color = Color.green;
    Handles.DotCap(0, p2, Quaternion.identity, 0.25f*HandleUtility.GetHandleSize(p2));
    Handles.color = Color.blue;
    Handles.DotCap(0, p3, Quaternion.identity, 0.25f*HandleUtility.GetHandleSize(p3));

    Handles.color = Color.white;
    Handles.DrawDottedLine(p1, p2, 5f);
    Handles.DrawDottedLine(p2, p3, 5f);
    Handles.DrawDottedLine(p3, p1, 5f);

    if (centredStyle == null){
    centredStyle = new GUIStyle(GUI.skin.label);
    centredStyle.normal.textColor = Color.black;
    centredStyle.fixedWidth = 40; // If you regularly inspect meshes with more than 999 vertices you may wish to increase this value
    centredStyle.fixedHeight = 20;
    centredStyle.alignment = TextAnchor.MiddleCenter;
    // centredStyle.normal.background = Texture2D.whiteTexture; // For reference, whiteTexture is 4x4 (not particularly relevant here)
    centredStyle.fontSize = 12;
    centredStyle.clipping = TextClipping.Overflow;
    }

    Handles.Label(p1, index1.ToString(), centredStyle);
    Handles.Label(p2, index2.ToString(), centredStyle);
    Handles.Label(p3, index3.ToString(), centredStyle);

    sceneView.Repaint();
    }
    }

    }
    1 change: 1 addition & 0 deletions gistfile2.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    http://cfile27.uf.tistory.com/image/990C973360AA569332ACC0