I’m learning the basics of mesh generation, and am having some trouble with mapping the correct UV to the new generated mesh.
This is the code I’m using to clone the mesh:
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
public class MeshDupe : MonoBehaviour
{
public GameObject target;
public List<Vector3> targetVertices = new List<Vector3>();
public int[] targetTriangles;
public List<Vector3> targetNormals = new List<Vector3>();
public List<Vector4> targetTangents = new List<Vector4>();
public Vector2[] targetUVs;
public List<Vector3> newVertices = new List<Vector3>();
public List<int> newTriangles = new List<int>();
public List<Vector3> newNormals = new List<Vector3>();
public List<Vector4> newTangents = new List<Vector4>();
public List<Vector2> newUVs = new List<Vector2>();
private Material targetMaterial;
private Shader targetShader;
[Button]
void DupeMesh()
{
Mesh mesh = target.GetComponent<MeshFilter>().mesh;
mesh.GetVertices(targetVertices);
targetTriangles = mesh.triangles;
mesh.GetNormals(targetNormals);
mesh.GetTangents(targetTangents);
targetUVs = mesh.uv;
targetMaterial = target.GetComponent<Renderer>().material;
targetShader = targetMaterial.shader;
for (int i = 0; i < targetTriangles.Length; i += 3)
{
Vector3 v0 = targetVertices[targetTriangles[i + 0]];
Vector3 v1 = targetVertices[targetTriangles[i + 1]];
Vector3 v2 = targetVertices[targetTriangles[i + 2]];
Vector2 uv0 = targetUVs[targetTriangles[i + 0]];
Vector2 uv1 = targetUVs[targetTriangles[i + 1]];
Vector2 uv2 = targetUVs[targetTriangles[i + 2]];
AddData(v0, uv0, i);
AddData(v1, uv1, i + 1);
AddData(v2, uv2, i + 2);
}
CreateNew();
}
void AddData(Vector3 v, Vector2 uv, int i)
{
if (!newVertices.Contains(v))
{
newVertices.Add(v);
newNormals.Add(targetNormals[targetTriangles[i]]);
newTangents.Add(targetTangents[targetTriangles[i]]);
newUVs.Add(uv);
}
newTriangles.Add(newVertices.IndexOf(v));
}
void CreateNew()
{
GameObject dupe = new GameObject("dupe");
MeshRenderer meshRenderer = dupe.AddComponent<MeshRenderer>();
meshRenderer.sharedMaterial = new Material(Shader.Find("Standard"));
MeshFilter meshFilter = dupe.AddComponent<MeshFilter>();
Mesh newMesh = new Mesh();
MeshCollider posCollider = dupe.AddComponent<MeshCollider>();
posCollider.sharedMesh = newMesh;
newMesh.SetVertices(newVertices);
newMesh.SetTriangles(newTriangles, 0);
newMesh.SetNormals(newNormals);
newMesh.SetTangents(newTangents);
newMesh.SetUVs(0, newUVs);
meshFilter.mesh = newMesh;
meshRenderer.material = targetMaterial;
meshRenderer.material.shader = targetShader;
target.SetActive(false);
}
}
note: I’m creating this as an analog to another project, that is the reason I’m not referencing the mesh directly. In my project, I need to get the references from previously assigned lists.