Advertisement
Guest User

Untitled

a guest
Jan 24th, 2020
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.10 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System;
  5. using System.Runtime.Serialization.Formatters.Binary;
  6. using System.IO;
  7.  
  8. [Serializable]
  9. class BlockData
  10. {
  11. public Block.BlockType[,,] matrix;
  12.  
  13. public BlockData(){}
  14.  
  15. public BlockData(Block[,,] b)
  16. {
  17. matrix = new Block.BlockType[World.chunkSize,World.chunkSize,World.chunkSize];
  18. for(int z = 0; z < World.chunkSize; z++)
  19. for(int y = 0; y < World.chunkSize; y++)
  20. for(int x = 0; x < World.chunkSize; x++)
  21. {
  22. matrix[x,y,z] = b[x,y,z].bType;
  23. }
  24. }
  25. }
  26.  
  27. public class Chunk {
  28.  
  29. public Material cubeMaterial;
  30. public Material fluidMaterial;
  31. public Block[,,] chunkData;
  32. public GameObject chunk;
  33. public GameObject fluid;
  34. public enum ChunkStatus {DRAW,DONE,KEEP};
  35. public ChunkStatus status;
  36. public ChunkMB mb;
  37. BlockData bd;
  38. public bool changed = false;
  39. public bool treeCreated = false;
  40.  
  41.  
  42.  
  43. string BuildChunkFileName(Vector3 v)
  44. {
  45. return Application.persistentDataPath + "/savedata/Chunk_" +
  46. (int)v.x + "_" +
  47. (int)v.y + "_" +
  48. (int)v.z +
  49. "_" + World.chunkSize +
  50. "_" + World.radius +
  51. ".dat";
  52. }
  53.  
  54. bool Load() //read data from file
  55. {
  56. string chunkFile = BuildChunkFileName(chunk.transform.position);
  57. if(File.Exists(chunkFile))
  58. {
  59. BinaryFormatter bf = new BinaryFormatter();
  60. FileStream file = File.Open(chunkFile, FileMode.Open);
  61. bd = new BlockData();
  62. bd = (BlockData) bf.Deserialize(file);
  63. file.Close();
  64. //Debug.Log("Loading chunk from file: " + chunkFile);
  65. return true;
  66. }
  67. return false;
  68. }
  69.  
  70. public void Save() //write data to file
  71. {
  72. string chunkFile = BuildChunkFileName(chunk.transform.position);
  73.  
  74. if(!File.Exists(chunkFile))
  75. {
  76. Directory.CreateDirectory(Path.GetDirectoryName(chunkFile));
  77. }
  78. BinaryFormatter bf = new BinaryFormatter();
  79. FileStream file = File.Open(chunkFile, FileMode.OpenOrCreate);
  80. bd = new BlockData(chunkData);
  81. bf.Serialize(file, bd);
  82. file.Close();
  83. }
  84.  
  85. //This method deals with the actual building of the chunk and later in the method contains the parameters it will use.
  86. //Such as grass on the top level red and blue blocks at the base of the world and end block at the very bottom
  87. void BuildChunk()
  88. {
  89. bool dataFromFile = false;
  90. dataFromFile = Load();
  91.  
  92. chunkData = new Block[World.chunkSize,World.chunkSize,World.chunkSize];
  93. for(int z = 0; z < World.chunkSize; z++)
  94. for(int y = 0; y < World.chunkSize; y++)
  95. for(int x = 0; x < World.chunkSize; x++)
  96. {
  97. //creates a position for the block from the x,y,z values of the loop
  98. //Chunk can move anywhere but the blocks origin is 0,0,0 of the chunk
  99. Vector3 pos = new Vector3(x,y,z);
  100. int worldX = (int)(x + chunk.transform.position.x);
  101. int worldY = (int)(y + chunk.transform.position.y);
  102. int worldZ = (int)(z + chunk.transform.position.z);
  103.  
  104. if(dataFromFile)
  105. {
  106. chunkData[x,y,z] = new Block(bd.matrix[x, y, z], pos,
  107. chunk.gameObject, this);
  108. continue;
  109. }
  110.  
  111.  
  112. int surfaceHeight = Utils.GenerateHeight(worldX,worldZ);
  113.  
  114. //All the blocks are inputed here at different heights this enables new blocks to be added there heighs and frequency to be inputed
  115.  
  116. if (worldY == 0)
  117. chunkData [x, y, z] = new Block (Block.BlockType.WORLDEND, pos,
  118. chunk.gameObject, this);
  119. else if (worldY <= Utils.GenerateStoneHeight (worldX, worldZ)) {
  120. //values for placement in world /chunk
  121. //Check if the proberbility is <
  122. if (Utils.fBM3D (worldX, worldY, worldZ, 0.01f, 2) < 0.4f && worldY < 40)
  123. chunkData [x, y, z] = new Block (Block.BlockType.BLUE, pos,
  124. chunk.gameObject, this);
  125. else if (Utils.fBM3D (worldX, worldY, worldZ, 0.03f, 3) < 0.41f && worldY < 20)
  126. chunkData [x, y, z] = new Block (Block.BlockType.RED, pos,
  127. chunk.gameObject, this);
  128. else
  129. chunkData [x, y, z] = new Block (Block.BlockType.GREY, pos,
  130. chunk.gameObject, this);
  131. } else if (worldY == surfaceHeight) {
  132. if (Utils.fBM3D (worldX, worldY, worldZ, 0.4F, 2) < 0.4F)
  133. chunkData [x, y, z] = new Block (Block.BlockType.WOODBASE, pos,
  134.  
  135. chunk.gameObject, this);
  136. else {
  137. chunkData [x, y, z] = new Block (Block.BlockType.GREEN, pos,
  138. chunk.gameObject, this);
  139. chunk.gameObject.tag = "Green";
  140. }
  141. } else if (worldY < surfaceHeight) {
  142. chunkData [x, y, z] = new Block (Block.BlockType.BROWN, pos,
  143. chunk.gameObject, this);
  144. chunk.gameObject.tag = "BROWN";
  145. }
  146.  
  147.  
  148. else if(worldY < 65)
  149. chunkData[x,y,z] = new Block(Block.BlockType.WATER, pos,
  150. fluid.gameObject, this);
  151. else
  152. {
  153. chunkData[x,y,z] = new Block(Block.BlockType.AIR, pos,
  154. chunk.gameObject, this);
  155. }
  156. if (chunkData [x, y, z].bType != Block.BlockType.WATER && Utils.fBM3D (worldX, worldY, worldZ, 0.1f, 3) < 0.42f)
  157. chunkData [x, y, z] = new Block (Block.BlockType.AIR, pos,
  158. chunk.gameObject, this);
  159.  
  160. status = ChunkStatus.DRAW;
  161. }
  162. }
  163. public void Redraw()
  164. {
  165. GameObject.DestroyImmediate(chunk.GetComponent<MeshFilter>());
  166. GameObject.DestroyImmediate(chunk.GetComponent<MeshRenderer>());
  167. GameObject.DestroyImmediate(chunk.GetComponent<Collider>());
  168. GameObject.DestroyImmediate(fluid.GetComponent<MeshFilter>());
  169. GameObject.DestroyImmediate(fluid.GetComponent<MeshRenderer>());
  170. GameObject.DestroyImmediate(fluid.GetComponent<Collider>());
  171. DrawChunk();
  172. }
  173.  
  174. //This handles the creation of trees the height setting and so forth of the trees is done in build trees.
  175. // It also handles the drawing of the chunk z/y/x being the parameters of generation
  176. public void DrawChunk()
  177. {
  178.  
  179. if (!treeCreated)
  180. {
  181. for (int z = 0; z < World.chunkSize; z++)
  182. for (int y = 0; y < World.chunkSize; y++)
  183. for (int x = 0; x < World.chunkSize; x++)
  184. {
  185. BuildTrees (chunkData [x, y, z], x, y, z);
  186.  
  187. }
  188. treeCreated = true;
  189.  
  190. }
  191. for(int z = 0; z < World.chunkSize; z++)
  192. for(int y = 0; y < World.chunkSize; y++)
  193. for(int x = 0; x < World.chunkSize; x++)
  194. {
  195. chunkData[x,y,z].Draw();
  196. }
  197.  
  198. CombineQuads(chunk.gameObject, cubeMaterial);
  199. MeshCollider collider = chunk.gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider;
  200. collider.sharedMesh = chunk.transform.GetComponent<MeshFilter>().mesh;
  201.  
  202. CombineQuads(fluid.gameObject, fluidMaterial);
  203. status = ChunkStatus.DONE;
  204. }
  205.  
  206. //This is where the height and the requirements for a tree are set
  207. void BuildTrees(Block trunk, int x, int y, int z)
  208. {
  209. if (trunk.bType != Block.BlockType.WOODBASE) //if chunk is not a wood base just return
  210. return;
  211.  
  212. Block t = trunk.GetBlock (x, y + 1, z); //Get chunk block y + 1 above the base of the tree (Wood)
  213. if (t != null)
  214.  
  215. {
  216. t.SetType (Block.BlockType.WOOD); //set to wood
  217. Block t1 = t.GetBlock (x, y + 2, z); //go up tree build up
  218. if (t1 != null)
  219. {
  220. t1.SetType (Block.BlockType.WOOD);
  221.  
  222. //building the leaves after the tree has hit required height
  223. for (int i = -1; i <= 1; i++)
  224. for (int j = -1; j <= 1; j++)
  225. for (int k = 3; k <= 4; k++)
  226. {
  227. Block t2 = trunk.GetBlock (x + i, y + k, z + j);
  228. if (t2 != null)
  229. t2.SetType (Block.BlockType.LEAVES);
  230. else
  231. return;
  232. }
  233.  
  234. Block t3 = t1.GetBlock (x, y + 5, z);
  235. if (t3 != null)
  236. {
  237. t3.SetType (Block.BlockType.LEAVES); // place one on top at the end for top of tree
  238. }
  239. }
  240. }
  241. }
  242.  
  243. public Chunk(){}
  244. // Use this for initialization
  245. public Chunk (Vector3 position, Material c, Material t) {
  246.  
  247. chunk = new GameObject(World.BuildChunkName(position));
  248. chunk.transform.position = position;
  249. fluid = new GameObject(World.BuildChunkName(position)+"_F");
  250. fluid.transform.position = position; //holds fluid block meshes instead
  251.  
  252. mb = chunk.AddComponent<ChunkMB>();
  253. mb.SetOwner(this);
  254. cubeMaterial = c;
  255. fluidMaterial = t;//holding material before building the chunk (The fluid material)
  256. BuildChunk();
  257. }
  258.  
  259. //This is the intial script that uses combining of the four sides of a plane creating a cube.
  260. public void CombineQuads(GameObject o, Material m)
  261. {
  262. //1. Combine all children meshes
  263. MeshFilter[] meshFilters = o.GetComponentsInChildren<MeshFilter>();
  264. CombineInstance[] combine = new CombineInstance[meshFilters.Length];
  265. int i = 0;
  266. while (i < meshFilters.Length) {
  267. combine[i].mesh = meshFilters[i].sharedMesh;
  268. combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
  269. i++;
  270. }
  271.  
  272. //2. Create a new mesh on the parent object
  273. MeshFilter mf = (MeshFilter) o.gameObject.AddComponent(typeof(MeshFilter));
  274. mf.mesh = new Mesh();
  275.  
  276. //3. Add combined meshes on children as the parent's mesh
  277. mf.mesh.CombineMeshes(combine);
  278.  
  279. //4. Create a renderer for the parent
  280. MeshRenderer renderer = o.gameObject.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
  281. renderer.material = m;
  282.  
  283. //5. Delete all uncombined children
  284. foreach (Transform quad in o.transform) {
  285. GameObject.Destroy(quad.gameObject);
  286. }
  287.  
  288. }
  289.  
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement