I am trying to implement a method using ray casting in unity where I can set different color to selected face of triangle and set different color to the contacted triangle (neighboring triangles) but when I am running it's coloring all triangles same color. I was wondering if there is a problem with my implementation or do I need to update my unity settings (such as materials etc.)
I have shared my implemented code below. Any help will be really appreciated! Thank you.
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
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;
//colors
[SerializeField] private Material startMaterial;
[SerializeField] private Material newMaterial;
Renderer objrenderer;
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] = Color.black;
}
// 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 we check if the vertices are used by more than one triangle
// If so, we need to split the triangle into three new ones
// and add the new vertices to the vertices list
if (verticesOccur_1 > 1)
{
// Add the new vertices to the vertices list
newVertices.Add(vertPos_1);
newVertices.Add(vertPos_2);
newVertices.Add(vertPos_3);
// Add the new triangles to the triangles list
newTriangles.Add(vertIndex_1);
newTriangles.Add(newVertices.Count - 3);
newTriangles.Add(newVertices.Count - 1);
newTriangles.Add(newVertices.Count - 3);
newTriangles.Add(vertIndex_2);
newTriangles.Add(newVertices.Count - 2);
newTriangles.Add(newVertices.Count - 1);
newTriangles.Add(newVertices.Count - 2);
newTriangles.Add(vertIndex_3);
// Add the new colors to the colors list
newColors.Add(Color.black);
newColors.Add(Color.black);
newColors.Add(Color.black);
// Update the triangle index to the new triangle
triangles[hit.triangleIndex] = newTriangles.Count / 3 - 1;
}
if (verticesOccur_2 > 1)
{
// Add the new vertices to the vertices list
newVertices.Add(vertPos_1);
newVertices.Add(vertPos_2);
newVertices.Add(vertPos_3);
// Add the new triangles to the triangles list
newTriangles.Add(vertIndex_1);
newTriangles.Add(newVertices.Count - 3);
newTriangles.Add(newVertices.Count - 1);
newTriangles.Add(newVertices.Count - 3);
newTriangles.Add(vertIndex_2);
newTriangles.Add(newVertices.Count - 2);
newTriangles.Add(newVertices.Count - 1);
newTriangles.Add(newVertices.Count - 2);
newTriangles.Add(vertIndex_3);
// Add the new colors to the colors list
newColors.Add(Color.black);
newColors.Add(Color.black);
newColors.Add(Color.black);
// Update the triangle index to the new triangle
triangles[hit.triangleIndex] = newTriangles.Count / 3 - 1;
}
if (verticesOccur_3 > 1)
{
// Add the new vertices to the vertices list
newVertices.Add(vertPos_1);
newVertices.Add(vertPos_2);
newVertices.Add(vertPos_3);
// Add the new triangles to the triangles list
newTriangles.Add(vertIndex_1);
newTriangles.Add(newVertices.Count - 3);
newTriangles.Add(newVertices.Count - 1);
newTriangles.Add(newVertices.Count - 3);
newTriangles.Add(vertIndex_2);
newTriangles.Add(newVertices.Count - 2);
newTriangles.Add(newVertices.Count - 1);
newTriangles.Add(newVertices.Count - 2);
newTriangles.Add(vertIndex_3);
// Add the new colors to the colors list
newColors.Add(Color.white);
newColors.Add(Color.green);
newColors.Add(Color.yellow);
// Update the triangle index to the new triangle
triangles[hit.triangleIndex] = newTriangles.Count / 3 - 1;
}
// Update the mesh with the new data
mesh.vertices = newVertices.ToArray();
mesh.triangles = newTriangles.ToArray();
//mesh.uv = newUV.ToArray();
mesh.colors = newColors.ToArray();
// 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);
// color these vertices
newColors[vertIndex_1] = Color.red;
newColors[vertIndex_2] = Color.red;
newColors[vertIndex_3] = Color.red;
//color the mesh
mesh.colors = newColors.ToArray();
// Recalculate the normals
mesh.RecalculateNormals();
}
else
{
//reset the colors back to original
var colors = new Color[mesh.vertices.Length];
for(var i = 0; i < colors.Length; i++)
{
colors[i] = Color.black;
}
mesh.colors = colors;
Debug.Log("No hit");
}
}
}