Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2022-11-12 13:10:03 +01:00

152 lines
5.7 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace Assets.Scripts {
public class World : MonoBehaviour {
public int seed;
public Transform player;
public Vector3 spawn;
public BiomeAttributes biome;
public Material material;
public BlockType[] blockTypes;
private readonly Chunk[,] _chunks = new Chunk[VoxelData.WorldSizeInChunks, VoxelData.WorldSizeInChunks];
private readonly List<ChunkCoord> _activeChunks = new List<ChunkCoord>();
private ChunkCoord _playersLastChunk;
private void Start() {
Random.InitState(seed);
spawn = new Vector3(VoxelData.WorldSizeInBlocks / 2f,
VoxelData.ChunkHeight / 2f,
VoxelData.WorldSizeInBlocks / 2f);
GenerateWorld();
_playersLastChunk = GetChunkCoord(player.position);
}
private void Update() {
ChunkCoord playerChunk = GetChunkCoord(player.position);
if (!playerChunk.Equals(_playersLastChunk)) {
_playersLastChunk = playerChunk;
CheckViewDistance();
}
}
private void GenerateWorld() {
for (int x = VoxelData.WorldSizeInChunks / 2 - VoxelData.ViewDistance; x < VoxelData.WorldSizeInChunks / 2 + VoxelData.ViewDistance; x++) {
for (int z = VoxelData.WorldSizeInChunks / 2 - VoxelData.ViewDistance; z < VoxelData.WorldSizeInChunks / 2 + VoxelData.ViewDistance; z++) {
CreateNewChunk(x, z);
}
}
player.position = spawn;
}
public ChunkCoord GetChunkCoord(Vector3 absPosition) {
int x = Mathf.FloorToInt(absPosition.x / VoxelData.ChunkWidth);
int z = Mathf.FloorToInt(absPosition.z / VoxelData.ChunkWidth);
return new ChunkCoord(x, z);
}
private void CheckViewDistance() {
ChunkCoord coord = GetChunkCoord(player.position);
ChunkCoord[] previouslyActiveChunks = _activeChunks.ToArray();
_activeChunks.Clear();
for (int x = coord.x - VoxelData.ViewDistance; x < coord.x + VoxelData.ViewDistance; x++) {
for (int z = coord.z - VoxelData.ViewDistance; z < coord.z + VoxelData.ViewDistance; z++) {
if (!IsChunkInWorld(new ChunkCoord(x, z))) continue;
Chunk chunk = _chunks[x, z];
if (chunk == null)
CreateNewChunk(x, z);
else if (!chunk.IsActive) {
chunk.IsActive = true;
}
_activeChunks.Add(new ChunkCoord(x, z));
}
}
foreach (ChunkCoord chunk in previouslyActiveChunks) {
if (!_activeChunks.Contains(chunk))
_chunks[chunk.x, chunk.z].IsActive = false;
}
}
private void CreateNewChunk(int x, int z) {
_chunks[x, z] = new Chunk(new ChunkCoord(x, z), this);
_activeChunks.Add(new ChunkCoord(x, z));
}
public bool IsChunkInWorld(ChunkCoord coord) {
return (coord.x > 0 && coord.x < VoxelData.WorldSizeInChunks - 1 &&
coord.z > 0 && coord.z < VoxelData.WorldSizeInChunks - 1);
}
public bool IsBlockInWorld(Vector3 pos) {
return (pos.x >= 0 && pos.x < VoxelData.WorldSizeInBlocks &&
pos.y >= 0 && pos.y < VoxelData.ChunkHeight &&
pos.z >= 0 && pos.z < VoxelData.WorldSizeInBlocks);
}
public byte GenerateBlock(Vector3 position) {
Vector3Int pos = new Vector3Int(Mathf.FloorToInt(position.x),
Mathf.FloorToInt(position.y),
Mathf.FloorToInt(position.z));
if (!IsBlockInWorld(position)) return 0;
if (pos.y == 0) return 1;
//Generate Block based on 2D Perlin Noise
int terrainHeight = Mathf.FloorToInt(Noise.Get2DNoise(new Vector2(pos.x, pos.z), 0, biome.terrainScale) * biome.terrainHeight + biome.solidGroundHeight);
int blockValue = 0;
if (pos.y < terrainHeight) blockValue = 2;
if (pos.y < terrainHeight && pos.y > terrainHeight - 4) blockValue = 5;
if (pos.y == terrainHeight) blockValue = 3;
if (blockValue == 2) {
foreach (var lode in biome.lodes) {
if ((pos.y > lode.minHeight && pos.y < lode.maxHeight) && Noise.Get3DNoise(pos, lode.offset, lode.scale, lode.threshold))
blockValue = lode.blockID;
}
}
return (byte)blockValue;
}
}
[System.Serializable]
public class BlockType {
public string blockName;
public bool isSolid;
[Header("Texture Values")]
public int backFaceTexture;
public int frontFaceTexture;
public int topFaceTexture;
public int bottomFaceTexture;
public int leftFaceTexture;
public int rightFaceTexture;
//Back - Front - Top - Bottom - Left - Right
public int GetTextureID(int faceIndex) {
switch (faceIndex) {
case 0: return backFaceTexture;
case 1: return frontFaceTexture;
case 2: return topFaceTexture;
case 3: return bottomFaceTexture;
case 4: return leftFaceTexture;
case 5: return rightFaceTexture;
default: return 0;
}
}
}
}