Hey,
inspired by Student Game Dev has moved!: Unity Voxel Tutorial Part 1: Generating meshes from code I have created a slightly different version, so it can work with 2D physics.
For this I used an EdgeCollider2D which i gave the coordiantes of the squares vertices (I think) :
private void GenCollider(int x, int y)
{
col = GetComponent<EdgeCollider2D>();
if (Block(x, y + 1) == 0)
{
// TOP
newColVertices.Add(new Vector2(x, y));
newColVertices.Add(new Vector2(x + 1, y));
}
if (Block(x, y - 1) == 0)
{
// BOTTOM
newColVertices.Add(new Vector2(x, y - 1));
newColVertices.Add(new Vector2(x + 1, y - 1));
}
if (Block(x - 1, y) == 0)
{
// LEFT
newColVertices.Add(new Vector2(x, y));
newColVertices.Add(new Vector2(x, y - 1));
}
if (Block(x + 1, y) == 0)
{
// RIGHT
newColVertices.Add(new Vector2(x + 1, y));
newColVertices.Add(new Vector2(x + 1, y - 1));
}
I copied his way, how he achieved that there won’t be created an EdgeCollider2D for every single Block.
To test it i have created a 2D sprite which I gave a BoxCollider2D and also a Rigidbody.
When I hit the play button it works. But when I move the texture manually beneath the surface of the map it fells at first through the blocks but sometimes get stuck or gets even up again what it’s not supposed to do.
Here is my whole Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GenerateSquares : MonoBehaviour {
private List<int> newTriangles = new List<int>();
private List<Vector3> newVertices = new List<Vector3>();
private List<Vector2> newColVertices = new List<Vector2>();
private List<Vector2> newUV = new List<Vector2>();
private Mesh mesh;
private EdgeCollider2D col;
private float tUnit = 0.25f;
private int squareCount;
public byte[,] blocks;
private Vector2 tStone = new Vector2(0, 0);
private Vector2 tGrass = new Vector2(0, 1);
private void Start()
{
GenTerrain();
BuildMesh();
UpdateMesh();
}
private void GenSquare(int x, int y, Vector2 texture)
{
mesh = GetComponent<MeshFilter>().mesh;
newVertices.Add(new Vector3(x, y));
newVertices.Add(new Vector3(x + 1, y));
newVertices.Add(new Vector3(x + 1, y - 1));
newVertices.Add(new Vector3(x, y - 1));
newTriangles.Add(squareCount * 4);
newTriangles.Add((squareCount * 4) + 1);
newTriangles.Add((squareCount * 4) + 3);
newTriangles.Add((squareCount * 4) + 1);
newTriangles.Add((squareCount * 4) + 2);
newTriangles.Add((squareCount * 4) + 3);
newUV.Add(new Vector2(tUnit * texture.x, tUnit * texture.y + tUnit));
newUV.Add(new Vector2(tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
newUV.Add(new Vector2(tUnit * texture.x + tUnit, tUnit * texture.y));
newUV.Add(new Vector2(tUnit * texture.x, tUnit * texture.y));
squareCount++;
GenCollider(x, y);
}
private void GenTerrain()
{
blocks = new byte[30, 60];
for(int x = 0; x < blocks.GetLength(0); x++)
{
int stone = Noise(x, 0, 80, 15, 1);
stone += Noise(x, 0, 50, 30, 1);
stone += Noise(x, 0, 10, 10, 1);
stone += 25;
int dirt = Noise(x, 0, 100, 35, 1);
dirt += Noise(x, 0, 50, 30, 1);
dirt += 25;
for (int y = 0; y < blocks.GetLength(1); y++)
{
if (y < stone)
{
blocks[x, y] = 1;
if (Noise(x, y, 12, 16, 1) > 10)
{
blocks[x, y] = 2;
}
if (Noise(x, y * 2, 16, 20, 1) > 10)
{
blocks[x, y] = 0;
}
}
else if (y < dirt)
{
blocks[x, y] = 2;
}
}
}
}
int Noise(int x, int y, float scale, float mag, float exp)
{
return (int)(Mathf.Pow((Mathf.PerlinNoise(x / scale, y / scale) * mag), (exp)));
}
void BuildMesh()
{
for (int px = 0; px < blocks.GetLength(0); px++)
{
for (int py = 0; py < blocks.GetLength(1); py++)
{
if (blocks[px, py] == 1)
{
GenSquare(px, py, tStone);
}
else if (blocks[px, py] == 2)
{
GenSquare(px, py, tGrass);
}
}
}
}
byte Block(int x, int y)
{
if (x == -1 || x == blocks.GetLength(0) || y == -1 || y == blocks.GetLength(1))
{
return (byte)1;
}
return blocks[x, y];
}
private void UpdateMesh()
{
mesh.Clear();
mesh.vertices = newVertices.ToArray();
mesh.triangles = newTriangles.ToArray();
mesh.uv = newUV.ToArray();
mesh.RecalculateNormals();
col.points = newColVertices.ToArray();
squareCount = 0;
newVertices.Clear();
newTriangles.Clear();
newUV.Clear();
}
private void GenCollider(int x, int y)
{
col = GetComponent<EdgeCollider2D>();
if (Block(x, y + 1) == 0)
{
// TOP
newColVertices.Add(new Vector2(x, y));
newColVertices.Add(new Vector2(x + 1, y));
}
if (Block(x, y - 1) == 0)
{
// BOTTOM
newColVertices.Add(new Vector2(x, y - 1));
newColVertices.Add(new Vector2(x + 1, y - 1));
}
if (Block(x - 1, y) == 0)
{
// LEFT
newColVertices.Add(new Vector2(x, y));
newColVertices.Add(new Vector2(x, y - 1));
}
if (Block(x + 1, y) == 0)
{
// RIGHT
newColVertices.Add(new Vector2(x + 1, y));
newColVertices.Add(new Vector2(x + 1, y - 1));
}
}
}
Be aware, I’m a beginner.