Procedural voxel terrain generation in Unity #1 - Creating a cube!

Поделиться
HTML-код
  • Опубликовано: 28 янв 2025

Комментарии • 26

  • @BoomBoomMushroom
    @BoomBoomMushroom 2 года назад +5

    Code form video (Make sure to rename Voxel to script name or vise versa):
    using System.Collections;
    using UnityEngine;
    using System.Collections.Generic;
    [RequireComponent(typeof(MeshFilter))]
    [RequireComponent(typeof(MeshRenderer))]
    public class Voxel : MonoBehaviour
    {
    public Vector3 pos;
    public Mesh mesh;
    public List vertices = new List();
    public List triangles = new List();
    public List uvs = new List();
    private int lastVertex;
    private void Start(){
    // Init Mesh
    mesh = new Mesh();
    // Create mesh data
    drawCube();
    // Set Mesh data
    mesh.vertices = vertices.ToArray();
    mesh.triangles = triangles.ToArray();
    mesh.SetUVs(0,uvs.ToArray());
    // Recalculate Lighting
    mesh.RecalculateNormals();
    // Set the mesh
    GetComponent().mesh = mesh;
    }
    void drawCube(){
    generateFrontFace();
    generateBackFace();
    generateLeftFace();
    generateRightFace();
    generateTopFace();
    generateBottomFace();
    }
    void generateFrontFace(){
    lastVertex = vertices.Count;
    // Declare vertices
    vertices.Add(pos + Vector3.forward); // 0
    vertices.Add(pos + Vector3.forward + Vector3.up); // 1
    vertices.Add(pos + Vector3.forward + Vector3.up + Vector3.right); // 2
    vertices.Add(pos + Vector3.forward + Vector3.right); // 3
    // First triangle
    triangles.Add(lastVertex + 2);
    triangles.Add(lastVertex + 1);
    triangles.Add(lastVertex);
    // Second triangle
    triangles.Add(lastVertex);
    triangles.Add(lastVertex + 3);
    triangles.Add(lastVertex + 2);
    }
    void generateBackFace(){
    lastVertex = vertices.Count;
    // Declare vertices
    vertices.Add(pos + Vector3.right); // 0
    vertices.Add(pos + Vector3.up + Vector3.right); // 1
    vertices.Add(pos + Vector3.up); // 2
    vertices.Add(pos); // 3
    // First triangle
    triangles.Add(lastVertex + 2);
    triangles.Add(lastVertex + 1);
    triangles.Add(lastVertex);
    // Second triangle
    triangles.Add(lastVertex);
    triangles.Add(lastVertex + 3);
    triangles.Add(lastVertex + 2);
    }
    void generateLeftFace(){
    lastVertex = vertices.Count;
    // Declare vertices
    vertices.Add(pos); // 0
    vertices.Add(pos + Vector3.up); // 1
    vertices.Add(pos + Vector3.forward + Vector3.up); // 2
    vertices.Add(pos + Vector3.forward); // 3
    // First triangle
    triangles.Add(lastVertex + 2);
    triangles.Add(lastVertex + 1);
    triangles.Add(lastVertex);
    // Second triangle
    triangles.Add(lastVertex);
    triangles.Add(lastVertex + 3);
    triangles.Add(lastVertex + 2);
    }
    void generateRightFace(){
    lastVertex = vertices.Count;
    // Declare vertices
    vertices.Add(pos + Vector3.right + Vector3.forward); // 0
    vertices.Add(pos + Vector3.one); // 1
    vertices.Add(pos + Vector3.right + Vector3.up); // 2
    vertices.Add(pos + Vector3.right); // 3
    // First triangle
    triangles.Add(lastVertex + 2);
    triangles.Add(lastVertex + 1);
    triangles.Add(lastVertex);
    // Second triangle
    triangles.Add(lastVertex);
    triangles.Add(lastVertex + 3);
    triangles.Add(lastVertex + 2);
    }
    void generateTopFace(){
    lastVertex = vertices.Count;
    // Declare vertices
    vertices.Add(pos + Vector3.up + Vector3.right); // 0
    vertices.Add(pos + Vector3.one); // 1
    vertices.Add(pos + Vector3.forward + Vector3.up); // 2
    vertices.Add(pos + Vector3.up); // 3
    // First triangle
    triangles.Add(lastVertex + 2);
    triangles.Add(lastVertex + 1);
    triangles.Add(lastVertex);
    // Second triangle
    triangles.Add(lastVertex);
    triangles.Add(lastVertex + 3);
    triangles.Add(lastVertex + 2);
    }
    void generateBottomFace(){
    lastVertex = vertices.Count;
    // Declare vertices
    vertices.Add(pos); // 0
    vertices.Add(pos + Vector3.forward); // 1
    vertices.Add(pos + Vector3.forward + Vector3.right); // 2
    vertices.Add(pos + Vector3.right); // 3
    // First triangle
    triangles.Add(lastVertex + 2);
    triangles.Add(lastVertex + 1);
    triangles.Add(lastVertex);
    // Second triangle
    triangles.Add(lastVertex);
    triangles.Add(lastVertex + 3);
    triangles.Add(lastVertex + 2);
    }
    }

    • @manudles
      @manudles 2 года назад

      tysm you saved me so much time!

    • @dnox428
      @dnox428 2 года назад

      to lazy to actually follow the tutorial XD

    • @kosuken
      @kosuken 2 года назад

      I had so much errors and it won’t render tysm

  • @_buffer
    @_buffer 3 года назад

    Great content!

  • @Glenos92
    @Glenos92 Год назад +2

    Thanks for a great tutorial and you explained it very well. This is my first time procedurally generating anything and creating a mesh through code and.... it works! Just out of curiosity is there not an easier way to do this and also, surely this would not be good for optimization?

    • @ErenCode
      @ErenCode  Год назад +4

      Sadly manually creating each vertice and triangle is the only way, luckily once you create one cube you can create many of them just by looping! Ideally to increase performance you'd use chunks so you don't have to redraw the entire terrain, and instead you only need to redraw a 16x16 block :D

  • @maxkratt
    @maxkratt 3 года назад +1

    Good tutorial! What are your goals for this series?

    • @ErenCode
      @ErenCode  3 года назад +2

      Just to create "simple" Minecraft style world generation, at this stage I won't be going over biomes, or ores depends on the response to the first few episodes, however we will be going over terrain, trees and grass as well as caves:)

    • @yogeshpundir5614
      @yogeshpundir5614 3 года назад

      @@ErenCode Amazing cant wait for second episode
      !

  • @Tjoldar
    @Tjoldar 2 года назад +2

    This is great. I only have one question: How do I set the triangles to visible? I do not see them in my scene... 🙈

    • @Tjoldar
      @Tjoldar 2 года назад +1

      I figured it out myself 😁

    • @ErenCode
      @ErenCode  2 года назад +1

      haha nice work! :D

  • @srn8386
    @srn8386 2 года назад +1

    where do lo learn to do that ? unity have a lot of things like vector3, recalculate texture bla bla idk how learn that

    • @ErenCode
      @ErenCode  2 года назад

      lots of practice haha, the more you make, the easier it gets :D

  • @lever1616
    @lever1616 2 года назад

    why did you make six different functions instead of making a single function that needs an enum face type passed through and use a switch

    • @ErenCode
      @ErenCode  2 года назад +1

      In this situation, either or would work, no right or wrong answer, I personally prefer to divvy stuff up into functions for my own readability. If the scope of this project was larger then I'd default to switches, but in this case, doesn't matter :D

  • @onfox1864
    @onfox1864 3 года назад

    Nice

  • @holo1444
    @holo1444 2 года назад +1

    Isen't it better to not make new vertices after you make your front and back face since at that point you have all the vertices you need in your vertices list?

    • @ErenCode
      @ErenCode  2 года назад +2

      Not necessarily... Technically it sounds correct "optimise your mesh by sharing vertices" however, the issue with sharing vertices is that your also sharing normals. Normals are what help our mesh determine how to light each face (basically it does the lighting on a model). If we share vertices, if means that all our faces would share the same lighting data, producing a very gross looking cube XD To get a nice sharp edged cube, we need to create a new vertex for each face. This is a for all models if you want sharp edges, if we were creating a smooth looking terrain then we'd share vertices and normals. Hope this makes sense, its a difficult concept to wrap your head around, procedural mesh generation isn't easy so don't worry if you get stuck! Feel free to join the Discord if you wanna talk about it further :D

  • @jesniels
    @jesniels Год назад

    Nice walkthrough.. Down to earth..
    Sadly you removed the code...

  • @MrCrompz
    @MrCrompz 3 года назад +1

    72th