/// <summary> Set block under cursor </summary> /// <param name="adjacent"> Use block adjacent to surface (adding a block) </param> void SetTargetVoxel(BlockType ty, bool adjacent = false) { Ray ray; if (Cursor.visible) { ray = Camera.main.ScreenPointToRay(Input.mousePosition); } else { ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); } if (Physics.Raycast(ray, out RaycastHit hit)) { Vector3 p = hit.point + hit.normal * (adjacent ? 0.5f : -0.5f); CombinedVoxelMesh chunk = (world2 == null) ? world.WorldToChunk(p) : world2.WorldToChunk(p); Vector3Int xyz = chunk.WorldToXYZ(p), size = chunk.settings.size; if (xyz.x < 0 || xyz.y < 0 || xyz.z < 0 || xyz.x >= size.x || xyz.y >= size.y || xyz.z >= size.z) { return; } if (!destroyBedrock && chunk.voxels[chunk.XYZtoIndex(xyz)].ty == BlockType.Bedrock) { return; } chunk.voxels[chunk.XYZtoIndex(xyz)].ty = ty; chunk.Regenerate(); } }
void Start() { chunks = new CombinedVoxelMesh[size.x * size.y]; CombinedVoxelMesh CVM = chunkPrefab.GetComponent <CombinedVoxelMesh>(); Vector3Int chunkSize = CVM.settings.size; csx = chunkSize.x; csz = chunkSize.z; StartCoroutine(GenChunks()); }
IEnumerator GenChunks() { chunks = new CVM_Chunk[RadCount(radius)]; instMap = new Dictionary <Vector2Int, CombinedVoxelMesh>(chunks.Length); voxelMap = new Dictionary <Vector2Int, Voxel[]>(chunks.Length); Vector3Int chunkSize = chunkPrefab.GetComponent <CombinedVoxelMesh>().settings.size; csx = chunkSize.x; csy = chunkSize.y; csz = chunkSize.z; viewPos = GetViewpos(); posStack = new Stack <Vector2Int>(chunks.Length); int i = 0; for (float y = 0.5f - radius, rsq = (radius + bias) * (radius + bias); y < radius; y++) { for (float x = 0.5f - radius; x < radius; x++) { if (x * x + y * y <= rsq) { Vector2Int xz = viewPos + new Vector2Int((int)(x - 0.5f), (int)(y - 0.5f)); GameObject o = Instantiate(chunkPrefab, new Vector3(xz.x * chunkSize.x, 0f, xz.y * chunkSize.z), Quaternion.identity, transform); CombinedVoxelMesh CVM = o.GetComponent <CombinedVoxelMesh>(); chunks[i++] = new CVM_Chunk(xz, viewPos, CVM); instMap[xz] = CVM; voxelMap[xz] = CVM.voxels; o.name = $"Chunk {i}"; if (i % 256 == 0) { print($"{i} Chunks Generated"); } yield return(null); } } } print($"{i} Chunks Generated"); generated = true; }
void OnValidate() { noiseLayers = Mathf.Clamp(noiseLayers, 1, 16); if (noiseScale.x == 0 || noiseScale.y == 0 || noiseScale.z == 0) { return; } Validated?.Invoke(); if (CombinedVoxelMesh.instances.Count > 0) { CombinedVoxelMesh inst = CombinedVoxelMesh.instances[0]; if (coro != null) { inst.StopCoroutine(coro); coro = null; } coro = inst.StartCoroutine(InspectorRegen()); } }
IEnumerator InspectorRegen() { List <CombinedVoxelMesh> insts = CombinedVoxelMesh.instances; Debug.Log($"Regenerate {insts.Count} Chunks"); for (int i = 0; i < insts.Count; i++) { CombinedVoxelMesh chunk = insts[i]; for (int j = 0; j < chunk.voxels.Length; j++) { chunk.voxels[j].ty = BlockType.Air; } chunk.FillVoxels(); yield return(null); chunk.Regenerate(); } Debug.Log($"{insts.Count} Chunks Regenerated"); }
public CVM_Chunk(Vector2Int pos, Vector2Int center, CombinedVoxelMesh cVM) { this.pos = pos; this.center = center; CVM = cVM; }
IEnumerator UpdateChunks(Vector2Int vpos, int msLimit = 5) { viewPos = vpos; if (coro != null) { StopCoroutine(coro); coro = null; } sw.Restart(); for (float y = 0.5f - radius, rsq = (radius + bias) * (radius + bias); y < radius; y++) { for (float x = 0.5f - radius; x < radius; x++) { if (x * x + y * y <= rsq) { Vector2Int p = vpos + new Vector2Int((int)(x - 0.5f), (int)(y - 0.5f)); if (!instMap.ContainsKey(p)) { posStack.Push(p); } } } } for (int i = 0; i < chunks.Length; i++) { CVM_Chunk c = chunks[i]; Vector2 dif = c.pos + new Vector2(0.5f, 0.5f) - vpos; if (dif.x * dif.x + dif.y * dif.y > (radius + bias) * (radius + bias)) { Vector2Int nPos = posStack.Pop(); if (instMap.ContainsKey(nPos)) { print("taken!"); } CombinedVoxelMesh cvm = c.CVM; instMap.Remove(c.pos); instMap[nPos] = cvm; chunks[i].pos = nPos; cvm.gameObject.transform.position = new Vector3(nPos.x * csx, 0f, nPos.y * csz); if (voxelMap.ContainsKey(nPos)) { cvm.voxels = voxelMap[nPos]; } else { cvm.voxels = voxelMap[nPos] = new Voxel[cvm.voxels.Length]; cvm.FillVoxels(); } cvm.Regenerate(); if (sw.ElapsedMilliseconds >= msLimit) { sw.Restart(); yield return(null); } } chunks[i].center = vpos; } posStack.Clear(); /*for (int i = 0; i < chunks.Length; i++) { * CVM_Chunk c = chunks[i]; * Vector2 dif = c.pos + new Vector2(0.5f, 0.5f) - vpos; * * if (dif.x * dif.x + dif.y * dif.y > (radius + bias) * (radius + bias)) { * Vector2Int nPos = c.center + vpos - c.pos - new Vector2Int(1, 1); * * if (instMap.ContainsKey(nPos)) print("taken!"); * * CombinedVoxelMesh cvm = c.CVM; * instMap.Remove(c.pos); * instMap[nPos] = cvm; * chunks[i].pos = nPos; * * cvm.gameObject.transform.position = new Vector3(nPos.x * csx, 0f, nPos.y * csz); * * if (voxelMap.ContainsKey(nPos)) * cvm.voxels = voxelMap[nPos]; * else { * cvm.voxels = voxelMap[nPos] = new Voxel[cvm.voxels.Length]; * cvm.FillVoxels(); * } * cvm.Regenerate(); * * if (sw.ElapsedMilliseconds >= msLimit) { * sw.Restart(); * yield return null; * } * } * * chunks[i].center = vpos; * }*/ }