Advertisement
Placido_GDD

World

Mar 8th, 2022
1,061
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.91 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class World : MonoBehaviour
  6. {
  7.     public Transform player;
  8.     public Vector3 spawnPosition;
  9.     public Material mat;
  10.     public Material transparentMat;
  11.     public BlockType[] blockTypes;
  12.     public int seed;
  13.     public BiomeAttributes biome;
  14.     Chunk[,] chunks = new Chunk[VoxelData.WorldSizeInChunks,VoxelData.WorldSizeInChunks];
  15.  
  16.     List<chunkCoord> activeChunks = new List<chunkCoord>();
  17.     chunkCoord playerLastChunkCoord;
  18.     public chunkCoord playerChunkCoord;
  19.     List<chunkCoord> chunksToCreate = new List<chunkCoord>();
  20.     List<Chunk> chunksToUpdate = new List<Chunk>();
  21.     bool applyingModifications;
  22.  
  23.     Queue<Queue<VoxelMod>> modifications = new Queue<Queue<VoxelMod>>();
  24.     public Queue<Chunk> chunksToDraw   = new Queue<Chunk>();
  25.     public GameObject creativeInventoryWindow;
  26.     public GameObject cursorSlot;
  27.     private bool _inUI = false;
  28.  
  29.     public bool inUI
  30.     {
  31.         get { return _inUI; }
  32.         set {
  33.             _inUI = value;
  34.             if (_inUI)
  35.             {
  36.                 Cursor.lockState = CursorLockMode.None;
  37.                 creativeInventoryWindow.SetActive(true);
  38.                 cursorSlot.SetActive(true);
  39.             }
  40.                
  41.             else
  42.             {
  43.                 Cursor.lockState = CursorLockMode.Locked;
  44.                 creativeInventoryWindow.SetActive(false);
  45.                 cursorSlot.SetActive(false);
  46.             }
  47.                
  48.         }
  49.     }
  50.     public GameObject debugScreen;
  51.     private void Start()
  52.     {
  53.         Random.InitState(seed);
  54.  
  55.         spawnPosition = new Vector3(VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth / 2.0f, VoxelData.ChunkHeight -50f, (VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth) / 2.0f);
  56.         GenerateWorld();
  57.         playerLastChunkCoord = GetChunkCoordFromVector3(player.position);
  58.     }
  59.  
  60.     private void Update()
  61.     {
  62.         playerChunkCoord = GetChunkCoordFromVector3 (player.position);
  63.  
  64.         //--Update chunks if the player moves from the chunk they are currently on--//
  65.         if (!playerChunkCoord.Equals(playerLastChunkCoord))
  66.         {
  67.             CheckViewDistance();
  68.         }
  69.         if (!applyingModifications)
  70.         {
  71.             ApplyModifications();
  72.         }
  73.         if (chunksToCreate.Count > 0)
  74.         {
  75.             CreateChunk();
  76.         }
  77.         if(chunksToUpdate.Count > 0)
  78.         {
  79.             UpdateChunks();
  80.         }
  81.  
  82.         if(chunksToDraw.Count > 0)
  83.             lock(chunksToDraw)
  84.             {
  85.                 if (chunksToDraw.Peek().isEditable)
  86.                 {
  87.                     chunksToDraw.Dequeue().CreateMesh();
  88.                 }
  89.             }
  90.         if (Input.GetKeyDown(KeyCode.F3))
  91.         {
  92.             debugScreen.SetActive(!debugScreen.activeSelf);
  93.         }
  94.     }
  95.     void GenerateWorld()
  96.     {
  97.         for (int x = (VoxelData.WorldSizeInChunks / 2) - VoxelData.viewDistanceInChunks; x < (VoxelData.WorldSizeInChunks / 2) + VoxelData.viewDistanceInChunks; x++)
  98.         {
  99.             for (int z = (VoxelData.WorldSizeInChunks / 2) - VoxelData.viewDistanceInChunks; z < (VoxelData.WorldSizeInChunks / 2) + VoxelData.viewDistanceInChunks; z++)
  100.             {
  101.                chunks[x,z] = new Chunk (new chunkCoord(x,z),this,true);
  102.                activeChunks.Add(new chunkCoord(x,z));
  103.             }
  104.         }
  105.        
  106.         player.position = spawnPosition;
  107.     }
  108.  
  109.     void CreateChunk()
  110.     {
  111.         chunkCoord c = chunksToCreate[0];
  112.         chunksToCreate.RemoveAt(0);
  113.         activeChunks.Add(c);
  114.         chunks[c.x, c.z].Init();
  115.     }
  116.  
  117.     void UpdateChunks()
  118.     {
  119.         bool updated = false;
  120.         int index = 0;
  121.        
  122.         while (!updated && index < chunksToUpdate.Count - 1)
  123.         {
  124.             if (chunksToUpdate[index].isEditable)
  125.             {
  126.                 chunksToUpdate[index].UpdateChunk();
  127.                 chunksToUpdate.RemoveAt(index);
  128.                 updated = true;
  129.             }
  130.             else
  131.             {
  132.                 index++;
  133.             }
  134.         }
  135.     }
  136.  
  137.     void ApplyModifications()
  138.     {
  139.         applyingModifications = true;
  140.  
  141.         while (modifications.Count > 0)
  142.         {
  143.             Queue<VoxelMod> queue = modifications.Dequeue();
  144.             while (queue.Count > 0)
  145.             {
  146.                 VoxelMod v = queue.Dequeue();
  147.                 chunkCoord c = GetChunkCoordFromVector3(v.position);
  148.                 if (chunks[c.x, c.z] == null)
  149.                 {
  150.                     chunks[c.x, c.z] = new Chunk(c, this, true);
  151.                     activeChunks.Add(c);
  152.                 }
  153.                 chunks[c.x, c.z].modifications.Enqueue(v);
  154.  
  155.             if (!chunksToUpdate.Contains(chunks[c.x, c.z]))
  156.                 chunksToUpdate.Add(chunks[c.x, c.z]);
  157.             }
  158.         }
  159.         applyingModifications = false;
  160.     }
  161.     chunkCoord GetChunkCoordFromVector3(Vector3 pos)
  162.     {
  163.         int x = Mathf.FloorToInt(pos.x / VoxelData.ChunkWidth);
  164.         int z = Mathf.FloorToInt(pos.z / VoxelData.ChunkWidth);
  165.         return new chunkCoord(x, z);
  166.     }
  167.  
  168.     public Chunk GetChunkFromVector3(Vector3 pos)
  169.     {
  170.         int x = Mathf.FloorToInt(pos.x / VoxelData.ChunkWidth);
  171.         int z = Mathf.FloorToInt(pos.z / VoxelData.ChunkWidth);
  172.         return chunks[x, z];
  173.     }
  174.     void CheckViewDistance()
  175.     {
  176.  
  177.         //Start with a list of active chunks
  178.         //Do a check for chunks within view distance
  179.         //Set chunks to active when in view distance
  180.         //Set chunks to inactive when outside view distance
  181.        chunkCoord coord = GetChunkCoordFromVector3(player.position);
  182.         playerLastChunkCoord = playerChunkCoord;
  183.         List<chunkCoord> previouslyActiveChunks = new List<chunkCoord>(activeChunks) ;
  184.         for (int x = coord.x - VoxelData.viewDistanceInChunks; x < coord.x + VoxelData.viewDistanceInChunks; x++)
  185.         {
  186.             for (int z = coord.z - VoxelData.viewDistanceInChunks; z < coord.z + VoxelData.viewDistanceInChunks; z++)
  187.             {
  188.                 if (isChunkInWorld(new chunkCoord(x,z)))
  189.                 {
  190.                     if (chunks[x, z] == null)
  191.                     {
  192.                         chunks[x,z] = new Chunk(new chunkCoord(x,z),this,false);
  193.                         chunksToCreate.Add(new chunkCoord(x,z));
  194.                     }
  195.                     else if (!chunks[x, z].isActive)
  196.                     {
  197.                         chunks[x, z].isActive = true;
  198.                        
  199.                     }
  200.                     activeChunks.Add(new chunkCoord(x, z));
  201.                 }
  202.                 for (int i = 0; i < previouslyActiveChunks.Count; i++)
  203.                 {
  204.                     if (previouslyActiveChunks[i].Equals(new chunkCoord(x, z)))
  205.                     {
  206.                         previouslyActiveChunks.RemoveAt(i);
  207.                     }
  208.                 }
  209.             }
  210.         }
  211.         foreach (chunkCoord c in previouslyActiveChunks)
  212.         {
  213.             chunks[c.x, c.z].isActive = false;
  214.         }
  215.     }
  216.  
  217.     public bool VoxelCheck(Vector3 pos) //checks for voxels present
  218.     {
  219.         chunkCoord thisChunk = new chunkCoord(pos);
  220.        if(!isChunkInWorld(thisChunk)|| pos.y < 0 || pos.y > VoxelData.ChunkHeight)
  221.             return false;
  222.         if (chunks[thisChunk.x, thisChunk.z] != null && chunks[thisChunk.x, thisChunk.z].isEditable)
  223.         {
  224.             return blockTypes[chunks[thisChunk.x, thisChunk.z].GetVoxelFromGlobalVector3(pos)].isSolid;
  225.         }
  226.  
  227.         return blockTypes[GetVoxel(pos)].isSolid;
  228.     }
  229.  
  230.     public bool CheckIfVoxelTransparent(Vector3 pos) //checks for voxels present
  231.     {
  232.         chunkCoord thisChunk = new chunkCoord(pos);
  233.         if (!isChunkInWorld(thisChunk) || pos.y < 0 || pos.y > VoxelData.ChunkHeight)
  234.             return false;
  235.         if (chunks[thisChunk.x, thisChunk.z] != null && chunks[thisChunk.x, thisChunk.z].isEditable)
  236.         {
  237.             return blockTypes[chunks[thisChunk.x, thisChunk.z].GetVoxelFromGlobalVector3(pos)].isTransparent;
  238.         }
  239.  
  240.         return blockTypes[GetVoxel(pos)].isTransparent;
  241.     }
  242.     public byte GetVoxel(Vector3 pos)
  243.     {
  244.         int yPos = Mathf.FloorToInt(pos.y);
  245.         // Immutable Pass//
  246.         // if outside world return air
  247.         if (!isVoxelInWorld(pos))
  248.             return 0;
  249.         //if bottom block return bedrock
  250.         if (yPos == 0)
  251.             return 1;
  252.         //Basic Terrain Pass//
  253.         int terrainHeight = Mathf.FloorToInt(biome.terrainHeight * Noise.Get2DPerlin(new Vector2(pos.x,pos.z),0,biome.terrainScale)) + biome.solidGroundHeight;
  254.         byte voxelValue = 0;
  255.         if (yPos == terrainHeight)
  256.         {
  257.             voxelValue = 3; //grass
  258.         }
  259.         else if (yPos < terrainHeight && yPos > terrainHeight - 4)
  260.         {
  261.             voxelValue = 5;
  262.         }
  263.         else if (yPos > terrainHeight)
  264.             return 0; //returns air if ypos is higher than terrain Height
  265.         else
  266.             voxelValue = 2; //returns stone
  267.         //Second Pass//
  268.         if (voxelValue == 2)
  269.         {
  270.             foreach (Lode lode in biome.lodes)
  271.             {
  272.                 if(yPos > lode.minHeight && yPos < lode.maxHeight) //checks if lode is in between min and max height
  273.                     if (Noise.Get3DPerlin(pos, lode.noiseOffset, lode.scale, lode.threshold))
  274.                     {
  275.                         voxelValue = lode.blockID;
  276.                     }
  277.             }
  278.         }
  279.         //Tree pass//
  280.         if (yPos == terrainHeight)
  281.         {
  282.             if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treeZoneScale) > biome.treeZoneThreshold)
  283.             {
  284.                 if (Noise.Get2DPerlin(new Vector2(pos.x, pos.z), 0, biome.treePlacementScale) > biome.treePlacementThreshold)
  285.                 {
  286.                     modifications.Enqueue(Structure.MakeTree(pos,biome.minTreeHeight,biome.maxTreeHeight));
  287.                 }
  288.             }
  289.                
  290.         }
  291.  
  292.             return voxelValue;
  293.     }
  294.  
  295.  
  296.     bool isChunkInWorld(chunkCoord coord)
  297.     {
  298.         if(coord.x > 0 && coord.x < VoxelData.WorldSizeInChunks - 1 && coord.z > 0 && coord.z < VoxelData.WorldSizeInChunks - 1 )
  299.             return true;
  300.         else
  301.             return false;
  302.     }
  303.  
  304.     bool isVoxelInWorld(Vector3 pos)
  305.     {
  306.         if (pos.x >= 0 && pos.x < VoxelData.WorldSizeInVoxels && pos.y >= 0 && pos.y < VoxelData.ChunkHeight && pos.z >= 0 && pos.z < VoxelData.WorldSizeInVoxels)
  307.             return true;
  308.         else
  309.             return false;
  310.     }
  311. }
  312.  
  313. [System.Serializable]
  314. public class BlockType {
  315.  
  316.     public string name;
  317.     public bool isSolid;
  318.     public bool isTransparent;
  319.     public Sprite Icon;
  320.     public int maxStackSize;
  321.  
  322.     [Header("Texture Values")]
  323.     public int backFaceTexture;
  324.     public int frontFaceTexture;
  325.     public int topFaceTexture;
  326.     public int bottomFaceTexture;
  327.     public int leftFaceTexture;
  328.     public int rightFaceTexture;
  329.     // Face order:Back,Front,Top,Bottom,Left,Right
  330.  
  331.     public int GetTextureID(int faceIndex)
  332.     {
  333.         switch (faceIndex)
  334.         {
  335.             case 0:
  336.                 return backFaceTexture;
  337.             case 1:
  338.                 return frontFaceTexture;
  339.             case 2:
  340.                 return topFaceTexture;
  341.             case 3:
  342.                 return bottomFaceTexture;
  343.             case 4:
  344.                 return leftFaceTexture;
  345.             case 5:
  346.                 return rightFaceTexture;
  347.             default:
  348.                 Debug.Log("Error in GetTextureID: Invalid face index");
  349.                 return 0;
  350.  
  351.         }
  352.     }
  353. }
  354.  
  355. public class VoxelMod
  356. {
  357.     public Vector3 position;
  358.     public byte id;
  359.  
  360.     public VoxelMod()
  361.     {
  362.         position = new Vector3();
  363.         id = 0;
  364.     }
  365.     public VoxelMod(Vector3 _position, byte _id)
  366.     {
  367.         position = _position;
  368.         id = _id;
  369.     }
  370. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement