Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

Bug No UV change after fixing UV map

Discussion in 'General Graphics' started by fomafomitch, Dec 23, 2022.

  1. fomafomitch

    fomafomitch

    Joined:
    Nov 22, 2020
    Posts:
    75
    Hello,

    I have a script that create mesh for an hexmap. Every cell (that contain 6 vertices) store data using UV1, UV2, UV3. There is a lot of data I will not explain all of them but what is important is that when cells change some UVs data it is visible in their shader :

    ezgif.com-gif-maker (8).gif


    But my vertices weren't "UVmap" so I cannot use some shader effect on it. Anyway after a lot of research I found this script that is doing perfectly what I need :
    https://github.com/kurtdekker/makegeo/blob/master/makegeo/Assets/setuvtoworld/SetUVToWorld.cs

    But the problem is : when I use SetUVToWorld.cs on a MeshRenderer, every datas on UV1, UV2, UV3 is "set in stone" and cannot change anymore. I like this script but I lost my ability to alterate the mesh.

    In the next video you can see a change of texture thanks to SetUVToWorld.cs + using another shader. But after that I can't alterate anything :
    ezgif.com-gif-maker (9).gif

    Code for my HexMesh that add UV1 UV2 UV3 vectors :

    Code (CSharp):
    1.  
    2. [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
    3. public class HexMesh : MonoBehaviour {
    4.    
    5.     public HexFeatureManager features;
    6.  
    7.     [NonSerialized] List<Vector3> vertices, terrainTypes;
    8.     [NonSerialized] List<Vector3> extraData_Fog_Terrain_Transition_LayerOver;
    9.     [NonSerialized] List<Vector3> extraData_ColorCoeff_Height_other;
    10.     [NonSerialized] List<Color> colors;
    11.     [NonSerialized] List<int> triangles;
    12.  
    13.     Mesh hexMesh;
    14.     MeshCollider meshCollider;
    15.  
    16.     void Awake () {
    17.         GetComponent<MeshFilter>().mesh = hexMesh = new Mesh();
    18.         meshCollider = gameObject.AddComponent<MeshCollider>();
    19.         hexMesh.name = "Hex_Mesh";
    20.     }
    21.  
    22.     public void Clear()
    23.     {
    24.         hexMesh.Clear();
    25.         vertices = ListPool<Vector3>.Get();
    26.         colors = ListPool<Color>.Get();
    27.         terrainTypes = ListPool<Vector3>.Get();
    28.         extraData_Fog_Terrain_Transition_LayerOver = ListPool<Vector3>.Get();
    29.         extraData_ColorCoeff_Height_other = ListPool<Vector3>.Get();
    30.         triangles = ListPool<int>.Get();
    31.     }
    32.  
    33.     public void Apply()
    34.     {
    35.         hexMesh.SetVertices(vertices);
    36.         ListPool<Vector3>.Add(vertices);
    37.  
    38.         hexMesh.SetColors(colors);
    39.         ListPool<Color>.Add(colors);
    40.  
    41.         hexMesh.SetUVs(1, terrainTypes);
    42.         ListPool<Vector3>.Add(terrainTypes);
    43.  
    44.         hexMesh.SetUVs(2, extraData_Fog_Terrain_Transition_LayerOver);
    45.         ListPool<Vector3>.Add(extraData_Fog_Terrain_Transition_LayerOver);
    46.  
    47.         hexMesh.SetUVs(3, extraData_ColorCoeff_Height_other);
    48.         ListPool<Vector3>.Add(extraData_ColorCoeff_Height_other);
    49.  
    50.         hexMesh.SetTriangles(triangles, 0);
    51.         ListPool<int>.Add(triangles);
    52.  
    53.         meshCollider.sharedMesh = hexMesh;
    54.     }
    55. }
    Function Apply() is called by the chunk to update mesh :

    Code (CSharp):
    1.  
    2.     //HexGridChunk.CS
    3.  
    4.     public void Triangulate()
    5.     {
    6.         terrain.Clear();
    7.         for (int i = 0; i < cells.Length; i++)
    8.         {
    9.             Triangulate(cells[i]);
    10.         }
    11.         terrain.Apply();
    12.     }
    13.    
    14.  
    Code (CSharp):
    1. // @kurtdekker
    2. public class SetUVToWorld : MonoBehaviour
    3. {
    4.     // set this if you are putting it on a parent object, otherwise
    5.     // this script operates only on the current GameObject.
    6.     public    bool        DriveToAllChildren;
    7.  
    8.     public    Material    MaterialToUse;
    9.  
    10.     public    bool        PreserveColor;
    11.  
    12.     public    bool        IncludeRotation;
    13.  
    14.     void Reset()
    15.     {
    16.         IncludeRotation = true;
    17.         MaterialToUse = null;
    18.     }
    19.  
    20.     public static void AddToAllMeshRenderersWithMeshFilters(
    21.         GameObject go,
    22.         bool _PreserveColor = false,
    23.         Material _MaterialToUse = null)
    24.     {
    25.         MeshRenderer[] rndrrs = go.GetComponentsInChildren<MeshRenderer> ();
    26.         foreach( var mr in rndrrs)
    27.         {
    28.             MeshFilter mf = mr.GetComponent<MeshFilter> ();
    29.             if (mf != null)
    30.             {
    31.                 var uvsetter = mr.gameObject.AddComponent<SetUVToWorld> ();
    32.                 uvsetter.PreserveColor = _PreserveColor;
    33.                 uvsetter.MaterialToUse = _MaterialToUse;
    34.             }
    35.         }
    36.     }
    37.  
    38.     void Start()
    39.     {
    40.         // be careful: we are intentionally adding instances of this
    41.         // script that don't have the DriveToAllChildren bit set, in
    42.         // order to benefit from setting things once.
    43.         if (DriveToAllChildren)
    44.         {
    45.             AddToAllMeshRenderersWithMeshFilters(
    46.                 gameObject, PreserveColor, MaterialToUse);
    47.             return;
    48.         }
    49.  
    50.         MeshFilter mf = GetComponent<MeshFilter> ();
    51.         if (mf)
    52.         {
    53.             Vector2[] uvs = mf.mesh.uv;
    54.             Vector3[] verts = mf.mesh.vertices;
    55.             int[] tris = mf.mesh.triangles;
    56.  
    57.             if (uvs.Length != verts.Length)
    58.             {
    59.                 uvs = new Vector2[ verts.Length];
    60.             }
    61.  
    62.             for (int i = 0; i < verts.Length; i++)
    63.             {
    64.                 verts [i] = transform.TransformPoint (verts [i]);
    65.                 if (!IncludeRotation)
    66.                 {
    67.                     verts [i] = Quaternion.Inverse (transform.rotation) * verts [i];
    68.                 }
    69.             }
    70.  
    71.             for ( int i = 0; i < tris.Length; i += 3)
    72.             {
    73.                 Vector3 norm = Vector3.Cross (
    74.                     verts [tris [i + 1]] - verts [tris [i + 0]],
    75.                     verts [tris [i + 1]] - verts [tris [i + 2]]).normalized;
    76.  
    77.                 float dotX = Mathf.Abs (Vector3.Dot (norm, Vector3.right));
    78.                 float dotY = Mathf.Abs (Vector3.Dot (norm, Vector3.up));
    79.                 float dotZ = Mathf.Abs (Vector3.Dot (norm, Vector3.forward));
    80.  
    81.                 if (dotX > dotY && dotX > dotZ)
    82.                 {
    83.                     for ( int j = 0; j < 3; j++)
    84.                     {
    85.                         uvs [tris[i + j]] = new Vector2 (verts [tris[i + j]].z, verts [tris[i + j]].y);
    86.                     }
    87.                 }
    88.                 else
    89.                 {
    90.                     if (dotY > dotX && dotY > dotZ)
    91.                     {
    92.                         for ( int j = 0; j < 3; j++)
    93.                         {
    94.                             uvs [tris[i + j]] = new Vector2 (verts [tris[i + j]].x, verts [tris[i + j]].z);
    95.                         }
    96.                     }
    97.                     else
    98.                     {
    99.                         for ( int j = 0; j < 3; j++)
    100.                         {
    101.                             uvs [tris[i + j]] = new Vector2 (verts [tris[i + j]].x, verts [tris[i + j]].y);
    102.                         }
    103.                     }
    104.                 }
    105.             }
    106.             mf.mesh.uv = uvs;
    107.  
    108.             if (MaterialToUse)
    109.             {
    110.                 Dictionary<Color, Material> ColorDictToSaveDrawcalls = new Dictionary<Color, Material>();
    111.  
    112.                 Renderer rndrr = GetComponent<Renderer>();
    113.                 if (rndrr)
    114.                 {
    115.                     Material[] allNewMaterials = new Material[ rndrr.materials.Length];
    116.  
    117.                     for (int i = 0; i < allNewMaterials.Length; i++)
    118.                     {
    119.                         Color preservedColor = Color.white;
    120.  
    121.                         Material originalMaterial = rndrr.materials[i];
    122.  
    123.                         var instancedMaterial = MaterialToUse;
    124.  
    125.                         if (originalMaterial)
    126.                         {
    127.                             if (PreserveColor)
    128.                             {
    129.                                 preservedColor = originalMaterial.color;
    130.  
    131.                                 if (ColorDictToSaveDrawcalls.ContainsKey( preservedColor))
    132.                                 {
    133.                                     instancedMaterial = ColorDictToSaveDrawcalls[preservedColor];
    134.                                 }
    135.                                 else
    136.                                 {
    137.                                     instancedMaterial = new Material( MaterialToUse);
    138.                                     instancedMaterial.color = preservedColor;
    139.                                     ColorDictToSaveDrawcalls[preservedColor] = instancedMaterial;
    140.                                 }
    141.                             }
    142.                         }
    143.  
    144.                         allNewMaterials[i] = instancedMaterial;
    145.                     }
    146.  
    147.                     rndrr.materials = allNewMaterials;
    148.                 }
    149.             }
    150.         }
    151.         else
    152.         {
    153.             Debug.LogError (
    154.                 GetType() + ": there is no MeshFilter on GameObject '" + name + "'!");
    155.         }
    156.     }
    157. }
    I love SetUvWorld script but I don't understant why it remove my script capacity to change their UV1 UV2 UV3 ?