Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class World : MonoBehaviour
- {
- public Transform player;
- public Vector3 spawnPosition;
- public Material mat;
- public Material transparentMat;
- public BlockType[] blockTypes;
- public int seed;
- public BiomeAttributes biome;
- Chunk[,] chunks = new Chunk[VoxelData.WorldSizeInChunks,VoxelData.WorldSizeInChunks];
- List<chunkCoord> activeChunks = new List<chunkCoord>();
- chunkCoord playerLastChunkCoord;
- public chunkCoord playerChunkCoord;
- List<chunkCoord> chunksToCreate = new List<chunkCoord>();
- List<Chunk> chunksToUpdate = new List<Chunk>();
- bool applyingModifications;
- Queue<Queue<VoxelMod>> modifications = new Queue<Queue<VoxelMod>>();
- public Queue<Chunk> chunksToDraw = new Queue<Chunk>();
- public GameObject creativeInventoryWindow;
- public GameObject cursorSlot;
- private bool _inUI = false;
- public bool inUI
- {
- get { return _inUI; }
- set {
- _inUI = value;
- if (_inUI)
- {
- Cursor.lockState = CursorLockMode.None;
- creativeInventoryWindow.SetActive(true);
- cursorSlot.SetActive(true);
- }
- else
- {
- Cursor.lockState = CursorLockMode.Locked;
- creativeInventoryWindow.SetActive(false);
- cursorSlot.SetActive(false);
- }
- }
- }
- public GameObject debugScreen;
- private void Start()
- {
- Random.InitState(seed);
- spawnPosition = new Vector3(VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth / 2.0f, VoxelData.ChunkHeight -50f, (VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth) / 2.0f);
- GenerateWorld();
- playerLastChunkCoord = GetChunkCoordFromVector3(player.position);
- }
- private void Update()
- {
- playerChunkCoord = GetChunkCoordFromVector3 (player.position);
- //--Update chunks if the player moves from the chunk they are currently on--//
- if (!playerChunkCoord.Equals(playerLastChunkCoord))
- {
- CheckViewDistance();
- }
- if (!applyingModifications)
- {
- ApplyModifications();
- }
- if (chunksToCreate.Count > 0)
- {
- CreateChunk();
- }
- if(chunksToUpdate.Count > 0)
- {
- UpdateChunks();
- }
- if(chunksToDraw.Count > 0)
- lock(chunksToDraw)
- {
- if (chunksToDraw.Peek().isEditable)
- {
- chunksToDraw.Dequeue().CreateMesh();
- }
- }
- if (Input.GetKeyDown(KeyCode.F3))
- {
- debugScreen.SetActive(!debugScreen.activeSelf);
- }
- }
- void GenerateWorld()
- {
- for (int x = (VoxelData.WorldSizeInChunks / 2) - VoxelData.viewDistanceInChunks; x < (VoxelData.WorldSizeInChunks / 2) + VoxelData.viewDistanceInChunks; x++)
- {
- for (int z = (VoxelData.WorldSizeInChunks / 2) - VoxelData.viewDistanceInChunks; z < (VoxelData.WorldSizeInChunks / 2) + VoxelData.viewDistanceInChunks; z++)
- {
- chunks[x,z] = new Chunk (new chunkCoord(x,z),this,true);
- activeChunks.Add(new chunkCoord(x,z));
- }
- }
- player.position = spawnPosition;
- }
- void CreateChunk()
- {
- chunkCoord c = chunksToCreate[0];
- chunksToCreate.RemoveAt(0);
- activeChunks.Add(c);
- chunks[c.x, c.z].Init();
- }
- void UpdateChunks()
- {
- bool updated = false;
- int index = 0;
- while (!updated && index < chunksToUpdate.Count - 1)
- {
- if (chunksToUpdate[index].isEditable)
- {
- chunksToUpdate[index].UpdateChunk();
- chunksToUpdate.RemoveAt(index);
- updated = true;
- }
- else
- {
- index++;
- }
- }
- }
- void ApplyModifications()
- {
- applyingModifications = true;
- while (modifications.Count > 0)
- {
- Queue<VoxelMod> queue = modifications.Dequeue();
- while (queue.Count > 0)
- {
- VoxelMod v = queue.Dequeue();
- chunkCoord c = GetChunkCoordFromVector3(v.position);
- if (chunks[c.x, c.z] == null)
- {
- chunks[c.x, c.z] = new Chunk(c, this, true);
- activeChunks.Add(c);
- }
- chunks[c.x, c.z].modifications.Enqueue(v);
- if (!chunksToUpdate.Contains(chunks[c.x, c.z]))
- chunksToUpdate.Add(chunks[c.x, c.z]);
- }
- }
- applyingModifications = false;
- }
- chunkCoord GetChunkCoordFromVector3(Vector3 pos)
- {
- int x = Mathf.FloorToInt(pos.x / VoxelData.ChunkWidth);
- int z = Mathf.FloorToInt(pos.z / VoxelData.ChunkWidth);
- return new chunkCoord(x, z);
- }
- public Chunk GetChunkFromVector3(Vector3 pos)
- {
- int x = Mathf.FloorToInt(pos.x / VoxelData.ChunkWidth);
- int z = Mathf.FloorToInt(pos.z / VoxelData.ChunkWidth);
- return chunks[x, z];
- }
- void CheckViewDistance()
- {
- //Start with a list of active chunks
- //Do a check for chunks within view distance
- //Set chunks to active when in view distance
- //Set chunks to inactive when outside view distance
- chunkCoord coord = GetChunkCoordFromVector3(player.position);
- playerLastChunkCoord = playerChunkCoord;
- List<chunkCoord> previouslyActiveChunks = new List<chunkCoord>(activeChunks) ;
- for (int x = coord.x - VoxelData.viewDistanceInChunks; x < coord.x + VoxelData.viewDistanceInChunks; x++)
- {
- for (int z = coord.z - VoxelData.viewDistanceInChunks; z < coord.z + VoxelData.viewDistanceInChunks; z++)
- {
- if (isChunkInWorld(new chunkCoord(x,z)))
- {
- if (chunks[x, z] == null)
- {
- chunks[x,z] = new Chunk(new chunkCoord(x,z),this,false);
- chunksToCreate.Add(new chunkCoord(x,z));
- }
- else if (!chunks[x, z].isActive)
- {
- chunks[x, z].isActive = true;
- }
- activeChunks.Add(new chunkCoord(x, z));
- }
- for (int i = 0; i < previouslyActiveChunks.Count; i++)
- {
- if (previouslyActiveChunks[i].Equals(new chunkCoord(x, z)))
- {
- previouslyActiveChunks.RemoveAt(i);
- }
- }
- }
- }
- foreach (chunkCoord c in previouslyActiveChunks)
- {
- chunks[c.x, c.z].isActive = false;
- }
- }
- public bool VoxelCheck(Vector3 pos) //checks for voxels present
- {
- chunkCoord thisChunk = new chunkCoord(pos);
- if(!isChunkInWorld(thisChunk)|| pos.y < 0 || pos.y > VoxelData.ChunkHeight)
- return false;
- if (chunks[thisChunk.x, thisChunk.z] != null && chunks[thisChunk.x, thisChunk.z].isEditable)
- {
- return blockTypes[chunks[thisChunk.x, thisChunk.z].GetVoxelFromGlobalVector3(pos)].isSolid;
- }
- return blockTypes[GetVoxel(pos)].isSolid;
- }
- public bool CheckIfVoxelTransparent(Vector3 pos) //checks for voxels present
- {
- chunkCoord thisChunk = new chunkCoord(pos);
- if (!isChunkInWorld(thisChunk) || pos.y < 0 || pos.y > VoxelData.ChunkHeight)
- return false;
- if (chunks[thisChunk.x, thisChunk.z] != null && chunks[thisChunk.x, thisChunk.z].isEditable)
- {
- return blockTypes[chunks[thisChunk.x, thisChunk.z].GetVoxelFromGlobalVector3(pos)].isTransparent;
- }
- return blockTypes[GetVoxel(pos)].isTransparent;
- }
- public byte GetVoxel(Vector3 pos)
- {
- int yPos = Mathf.FloorToInt(pos.y);
- // Immutable Pass//
- // if outside world return air
- if (!isVoxelInWorld(pos))
- return 0;
- //if bottom block return bedrock
- if (yPos == 0)
- return 1;
- //Basic Terrain Pass//
- int terrainHeight = Mathf.FloorToInt(biome.terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x,pos.z),0,biome.terrainScale)) + biome.solidGroundHeight;
- byte voxelValue = 0;
- if (yPos == terrainHeight)
- {
- voxelValue = 3; //grass
- }
- else if (yPos < terrainHeight && yPos > terrainHeight - 4)
- {
- voxelValue = 5;
- }
- else if (yPos > terrainHeight)
- return 0; //returns air if ypos is higher than terrain Height
- else
- voxelValue = 2; //returns stone
- //Second Pass//
- if (voxelValue == 2)
- {
- foreach (Lode lode in biome.lodes)
- {
- if(yPos > lode.minHeight && yPos < lode.maxHeight) //checks if lode is in between min and max height
- if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold))
- {
- voxelValue = lode.blockID;
- }
- }
- }
- //Tree pass//
- if (yPos == terrainHeight)
- {
- if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treeZoneScale) > biome.treeZoneThreshold)
- {
- if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treePlacementScale) > biome.treePlacementThreshold)
- {
- modifications.Enqueue(Structure.MakeTree(pos,biome.minTreeHeight,biome.maxTreeHeight));
- }
- }
- }
- return voxelValue;
- }
- bool isChunkInWorld(chunkCoord coord)
- {
- if(coord.x > 0 && coord.x < VoxelData.WorldSizeInChunks - 1 && coord.z > 0 && coord.z < VoxelData.WorldSizeInChunks - 1 )
- return true;
- else
- return false;
- }
- bool isVoxelInWorld(Vector3 pos)
- {
- if (pos.x >= 0 && pos.x < VoxelData.WorldSizeInVoxels && pos.y >= 0 && pos.y < VoxelData.ChunkHeight && pos.z >= 0 && pos.z < VoxelData.WorldSizeInVoxels)
- return true;
- else
- return false;
- }
- }
- [System.Serializable]
- public class BlockType {
- public string name;
- public bool isSolid;
- public bool isTransparent;
- public Sprite Icon;
- public int maxStackSize;
- [Header("Texture Values")]
- public int backFaceTexture;
- public int frontFaceTexture;
- public int topFaceTexture;
- public int bottomFaceTexture;
- public int leftFaceTexture;
- public int rightFaceTexture;
- // Face order: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:
- Debug.Log("Error in GetTextureID: Invalid face index");
- return 0;
- }
- }
- }
- public class VoxelMod
- {
- public Vector3 position;
- public byte id;
- public VoxelMod()
- {
- position = new Vector3();
- id = 0;
- }
- public VoxelMod(Vector3 _position, byte _id)
- {
- position = _position;
- id = _id;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement