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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Procedural Mesh Problem [C#]

Discussion in 'Scripting' started by thewhiterose1, Jan 11, 2016.

  1. thewhiterose1

    thewhiterose1

    Joined:
    Sep 8, 2013
    Posts:
    18
    Hey,

    Basically I am trying to generate flat procedural terrain using a single mesh, and choosing between several material types for that particular quad of vertices. (Emulating to some extent Minecraft, basically).

    Long story short I had a working script before this that used game objects as separate meshes which lagged to hell (Apparently due to mesh colliders?), and I realised apparently this is how you are supposed to do meshes.

    So I went on to create a single mesh, using the following code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider))]
    5.  
    6. public class mapgen2 : MonoBehaviour
    7. {
    8.     public int xSize, zSize;
    9.     private Vector3[] verticies;
    10.     private Mesh mesh;
    11.  
    12.     private void Awake() {
    13.         Generate();
    14.     }
    15.  
    16.     private void Generate() {
    17.  
    18.         GetComponent<MeshFilter>().mesh = mesh = new Mesh();
    19.  
    20.         verticies = new Vector3[(xSize + 1) * (zSize + 1)];
    21.  
    22.         for (int i = 0, z = 0; z <= zSize; z++)
    23.         {
    24.             for (int x = 0; x <= xSize; x++, i++)
    25.             {
    26.                 verticies[i] = new Vector3(x, 0, z);
    27.             }
    28.         }
    29.         mesh.vertices = verticies;
    30.  
    31.         int[] tri = new int[(xSize + 1) * 6 * (zSize + 1)];
    32.  
    33.         for (int x = 0, i = 0, rZ = 0; x < ((xSize * zSize) + (xSize - 1)); x++, i += 6)
    34.         {
    35.             tri[i] = x;
    36.             tri[i + 1] = x + xSize + 1;
    37.             tri[i + 2] = x + 1;
    38.             tri[i + 3] = x + 1;
    39.             tri[i + 4] = x + xSize + 1;
    40.             tri[i + 5] = x + xSize + 2;
    41.             if ((x > 0) && (x % xSize == 0) && (rZ > zSize))
    42.             {
    43.                 rZ++;
    44.             }
    45.         }
    46.         mesh.triangles = tri;
    47.         mesh.Optimize();
    48.     }
    49.    
    50.     private void OnDrawGizmos() {
    51.         if (verticies == null) {
    52.             return;
    53.         }
    54.  
    55.         Gizmos.color = Color.black;
    56.         for (int i = 0; i < verticies.Length; i ++) {
    57.             Gizmos.DrawSphere(verticies[i], 0.1f);
    58.         }
    59.     }
    60. }
    61.  

    Which, I think more importantly for answering my question produces this:


    Question

    How can I emulate the old script I had? Where each individual quad has an independent material/is a particular type of block that is determined by the material/type of the blocks next to it?

    Thanks,

    (I know there are several threads, blog posts and videos regarding this topic, I've been searching around for ages trying to find what I want to no avail - I've come across concepts like textures atlases etc but I'm very confused!).
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Well, confusion or not, a texture atlas is exactly what you need!

    The idea here is that each quad will have a set of 4 vertices that are separate from the rest of the vertices (which means that, at most of those corner points in space, there will actually be 4 vertices at the same position). And then you can assign different UV coordinates to each quad.

    UV coordinates are simply indexes into the texture. "Texture atlas" means nothing more or less than a big texture that you use as a bunch of different pieces on an as-needed basis, by assigning the UV coordinates to the section you want. So a quad that should look like dirt, uses UV values that map to the "dirt" section of your texture, and so on.
     
  3. Mabenan

    Mabenan

    Joined:
    Feb 7, 2014
    Posts:
    132
    If you also want different shader types you can use subMeshes http://docs.unity3d.com/ScriptReference/Mesh.SetTriangles.html . Here you can assign different triangles to a material in your MeshRenderer. So you have for each Shader Type a Material an each Material has a Texture atlas descript by JoeStrout.
     
    JoeStrout likes this.