I have a game with a chunk mesh based system like Minecraft. In the MainSystem script I create a World instance and then I can render it. But after I render it from the Start method, if I want to change a block and render it in the Update method it doesn't change although the byte array "ChunkData" have changed. What i'm doing wrong?
Here's the MainSystem script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Game.Mechanics.UI;
using Game.Mechanics.ChunkSystems;
namespace Game
{
public class MainSystem : MonoBehaviour
{
private UIsystem uisystem;
World myWorld;
public Material material;
private void Awake()
{
uisystem = GameObject.Find("Scripter").GetComponent();
}
// Start is called before the first frame update
void Start()
{
Application.targetFrameRate = 144;
uisystem.StartGameCall();
myWorld = new World(16, 16, 16, 16, 16, true, material);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("t"))
{
myWorld.WorldChunks[0, 0].ChangeBlock(new Vector3Int(7, 7, 7), 0);
myWorld.RenderWorld();
}
}
}
}
(Ignore the uisystem and the namespaces)
And Here's the Chunk Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Game
{
namespace Mechanics
{
namespace ChunkSystems
{
public class Chunk
{
//mesh variables
[System.NonSerialized] private List Triangles;
[System.NonSerialized] private List Vertexs;
[System.NonSerialized] private List UVs;
//chunk scale
[System.NonSerialized] private int tx;
[System.NonSerialized] private int ty;
[System.NonSerialized] private int tz;
//the object of the chunk.
[System.NonSerialized] public GameObject myGameObject;
[System.NonSerialized] private byte[,,] ChunkData;
//how many voxels are in chunk.
[System.NonSerialized] public int voxelsInChunk;
//MeshFilter
[System.NonSerialized] private MeshFilter filter;
//set variables of chunk.
public Chunk(int tx, int ty, int tz, GameObject reference)
{
this.tx = tx;
this.ty = ty;
this.tz = tz;
InitChunk(tx, ty, tz);
myGameObject = reference;
}
//render the chunk.
public void RenderChunk()
{
Vertexs.Clear();
Triangles.Clear();
UVs.Clear();
SetDefaultChunk();
CreateChunk(16, 16, 16);
}
//Init the chunk.
public void InitChunk(int tx, int ty, int tz)
{
ChunkData = new byte[tx+2, ty+2, tz+2];
for (int x = 0; x < tx+2; x++)
{
for(int y = 0; y < ty+2; y++)
{
for(int z = 0; z < tz+1; z++)
{
ChunkData[x, y, z] = 0;
}
}
}
Vertexs = new List();
Triangles = new List();
UVs = new List();
}
//set chunk in default settings.
public void SetDefaultChunk()
{
for(int x = 0; x < tx; x++)
{
for(int y = 0; y < ty; y++)
{
for(int z = 0; z < tz; z++)
{
ChangeBlock(new Vector3Int(x, y, z), 2);
}
}
}
}
//change a block in the chunk.
public void ChangeBlock(Vector3Int position, byte texture)
{
ChunkData[position.x + 1, position.y + 1, position.z + 1] = texture;
}
//change a block and render.
public void ChangeBlockAndRender(Vector3Int position, byte texture)
{
ChunkData[position.x + 1, position.y + 1, position.z + 1] = texture;
RenderChunk();
}
//create the variables of mesh.
private void CreateChunk(int xt, int yt, int zt)
{
voxelsInChunk = 0;
for (int x = 0; x < xt; x++)
{
for(int y = 0; y < yt; y++)
{
for(int z = 0; z < zt; z++)
{
if (!(ChunkData[x+1,y+1,z+1] == 0))
{
if(ChunkData[x,y+1,z+1] == 0 ||ChunkData[x+2,y+1,z+1] == 0 || ChunkData[x+1,y,z+1] == 0 || ChunkData[x+1,y+2,z+1] == 0 || ChunkData[x+1,y+1,z] == 0 || ChunkData[x+1,y+1,z+2] == 0)
{
AddCubeToChunk(new Vector3(x, y, z), ChunkData[x + 1, y + 1, z + 1]);
}
}
}
}
}
CreateMesh();
}
//adding the voxels to variables.
private void AddCubeToChunk(Vector3 position, float texture)
{
for (int i = 0; i < 24; i++)
{
Vertexs.Add(BlockMeshData.BlockVerts[i] + position);
}
UVs.AddRange(BlockMeshData.GetUVs(texture));
for (int i = 0; i < 36; i++)
{
Triangles.Add(BlockMeshData.VoxelTriangles[i] + voxelsInChunk * 24);
}
voxelsInChunk++;
}
//creating the mesh and updating it.
private void CreateMesh()
{
filter = myGameObject.GetComponent();
Mesh mesh = new Mesh();
mesh.Clear();
mesh.name = "chunk";
mesh.vertices = Vertexs.ToArray();
mesh.triangles = Triangles.ToArray();
mesh.uv = UVs.ToArray();
mesh.RecalculateNormals();
if(!(filter.sharedMesh == null))
{
filter.sharedMesh.Clear();
}
filter.sharedMesh = mesh;
}
}
}
}
}
And for last the World Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Game
{
namespace Mechanics
{
namespace ChunkSystems
{
public class World
{
//World scale
public int twx;
public int twz;
//Chunks in world scale
public int tcx;
public int tcz;
//the chunks
public Chunk[,] WorldChunks;
//the textures
public Material WorldTexture;
//init the chunk and set all the variables
public World(int TWX, int TWZ, int tcx, int tcy, int tcz, bool renderAndInit, Material worldTexture)
{
WorldChunks = new Chunk[TWX, TWZ];
WorldTexture = worldTexture;
twx = TWX;
twz = TWZ;
this.tcx = tcx;
this.tcz = tcz;
for(int x = 0; x < TWX; x++)
{
for(int z = 0; z < TWZ; z++)
{
WorldChunks[x, z] = new Chunk(tcx, tcy, tcz, null);
}
}
if (renderAndInit)
{
Init();
RenderWorld();
}
}
//init the chunk.
public void Init()
{
for(int x = 0; x < twx; x++)
{
for(int z = 0; z < twz; z++)
{
GameObject NewChunk = new GameObject("Chunk" + x + "," + z, typeof(MeshFilter), typeof(MeshRenderer));
NewChunk.transform.position = new Vector3(x * tcx, 0f, z * tcz);
NewChunk.GetComponent().material = WorldTexture;
WorldChunks[x, z].myGameObject = NewChunk;
}
}
}
//render the chunk.
public void RenderWorld()
{
for(int x = 0; x < twx; x++)
{
for(int z = 0; z < twz; z++)
{
WorldChunks[x, z].RenderChunk();
}
}
}
}
}
}
}
Thanks for your time! And yes, i tested to call the different renders and the changes block methods of the Chunk and the World.
↧