0

Image from unity scene

Hello, by the help of stack overflow (Unity | mesh.colors won't color my custom mesh object I was able to solve the problem where I can see the colorized triangle's face after being selected using ray-cast in unity as shown in the image attached. I was wondering how I can improve my method by making the neighbors of selected triangle also change its color as well. For example, as shown in the image the selected triangle's neighbors change its color to white and be there only for a few seconds.

I have shared my implemented code below. Any guidance will be really appreciated! Thank you.

using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;


public class MyRayDraw : MonoBehaviour
{
    public GameObject spherePrefab;

    // Better to reference those already in the Inspector
    [SerializeField] private MeshFilter meshFilter;
    [SerializeField] private MeshRenderer meshRenderer;
    [SerializeField] private MeshCollider meshCollider;

    private Mesh mesh;

    private void Awake()
    {
        if (!meshFilter) meshFilter = GetComponent<MeshFilter>();
        if (!meshRenderer) meshRenderer = GetComponent<MeshRenderer>();
        if (!meshCollider) meshCollider = GetComponent<MeshCollider>();

        mesh = meshFilter.mesh;

        // create new colors array where the colors will be created
        var colors = new Color[mesh.vertices.Length];
        for(var i = 0; i < colors.Length; i++)
        {
            colors[i] = new Color(1f, 0f, 0.07f);
        }

        // assign the array of colors to the Mesh.
        mesh.colors = colors;

    }

    private void Update()
    {
        if (!Input.GetMouseButtonDown(0)) return;

        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;


        if (Physics.Raycast(ray, out hit))
        {
            Debug.Log(hit.triangleIndex);
            //cube.transform.position = hit.point;

            // Get current vertices, triangles, uvs and colors
            var vertices = mesh.vertices;
            var triangles = mesh.triangles;
            //var uv = _mesh.uv;
            var colors = mesh.colors;

            // Get the vert indices for this triangle
            var vertIndex_1 = triangles[hit.triangleIndex * 3 + 0];
            var vertIndex_2 = triangles[hit.triangleIndex * 3 + 1];
            var vertIndex_3 = triangles[hit.triangleIndex * 3 + 2];

            // Get the positions for the vertices
            var vertPos_1 = vertices[vertIndex_1];
            var vertPos_2 = vertices[vertIndex_2];
            var vertPos_3 = vertices[vertIndex_3];
            
            // Now for all three vertices we first check if any other triangle if using it
            // by simply count how often the indices are used in the triangles list
            var verticesOccur_1 = 0;
            var verticesOccur_2 = 0;
            var verticesOccur_3 = 0;

            for (var i = 0; i < triangles.Length; i++)
            {
                if (triangles[i] == vertIndex_1) verticesOccur_1++;
                if (triangles[i] == vertIndex_2) verticesOccur_2++;
                if (triangles[i] == vertIndex_3) verticesOccur_3++;
            }
            

            // Create copied Lists so we can dynamically add entries
            var newVertices = vertices.ToList();
            var newTriangles = triangles.ToList();
            //var newUV = uv.ToList();
            var newColors = colors.ToList();

            // Now if a vertex is shared we need to add a new individual vertex
            // and also an according entry for the color array
            // and update the vertex index
            // otherwise we will simply use the vertex we already have
            if (verticesOccur_1 >= 1)
            {

                newVertices.Add(vertPos_1);
               // newUV.Add(vert1UV);
                newColors.Add(Color.green);
                vertIndex_1 = newVertices.Count - 1;
            }

            if (verticesOccur_2 >= 1)
            {
                newVertices.Add(vertPos_2);
                //newUV.Add(vert2UV);
                newColors.Add(Color.green);
                vertIndex_2 = newVertices.Count - 1;
            }

            if (verticesOccur_3 >= 1)
            {
                newVertices.Add(vertPos_3);
                //newUV.Add(vert3UV);
                newColors.Add(Color.green);
                vertIndex_3 = newVertices.Count - 1;
            }


        // Update the indices of the hit triangle to use the (eventually) new
            // vertices instead
            triangles[hit.triangleIndex * 3 + 0] = vertIndex_1;
            triangles[hit.triangleIndex * 3 + 1] = vertIndex_2;
            triangles[hit.triangleIndex * 3 + 2] = vertIndex_3;
            
            // Now we can simply add the new triangle
            newTriangles.Add(vertIndex_1);
            newTriangles.Add(vertIndex_2);
            newTriangles.Add(vertIndex_3);
            
            // And update the mesh
            mesh.vertices = newVertices.ToArray();
            mesh.triangles = newTriangles.ToArray();
            //_mesh.uv = newUV.ToArray();
            mesh.colors = newColors.ToArray();
            


            // color these vertices
            newColors[vertIndex_1] = Color.red;
            newColors[vertIndex_2] = Color.red;
            newColors[vertIndex_3] = Color.red;

            // Recalculate the normals
            mesh.RecalculateNormals();
        }
        else
        {
            Debug.Log("no hit");
        }
    }
}
  • An adjacent triangle would share two vertices in common with the original triangle. So first get the triangle index of your current triangle. Then get the 3d mesh and access the triangle array. Convert that array into groups of 3 to reconstruct the points. Then run that point collection to find any item that would share exactly 2 indexes. You should get 3 triangles as result. Once you get the triangles, you can color the vertices. – Everts Nov 30 '22 at 08:26
  • Thank you for your response—just have a quick question. The solution which you stated, is it included inside of my implemented code or it is a different part that I should write? I mean Do I change some details in my code or do I not need to change and add your solution to the rest of my code? – newCoderMe Nov 30 '22 at 12:42
  • It seems you start right by getting the data about the hit triangle, then I would maybe refactor, I would take the triangle array and create a subcollection to store indexes in group of 3, to get a triangle. From there, run that new collection for all adjacent triangles with two common indexes, you should get a result of 3 items. Then you can convert those 3 items of 3 indexes into vertices to which you can apply color – Everts Nov 30 '22 at 12:58
  • I understood now better. Thank you for your time. I appreciate it! – newCoderMe Nov 30 '22 at 13:48

0 Answers0