Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.IO;
- [Serializable]
- class BlockData
- {
- public Block.BlockType[,,] matrix;
- public BlockData(){}
- public BlockData(Block[,,] b)
- {
- matrix = new Block.BlockType[World.chunkSize,World.chunkSize,World.chunkSize];
- for(int z = 0; z < World.chunkSize; z++)
- for(int y = 0; y < World.chunkSize; y++)
- for(int x = 0; x < World.chunkSize; x++)
- {
- matrix[x,y,z] = b[x,y,z].bType;
- }
- }
- }
- public class Chunk {
- public Material cubeMaterial;
- public Material fluidMaterial;
- public Block[,,] chunkData;
- public GameObject chunk;
- public GameObject fluid;
- public enum ChunkStatus {DRAW,DONE,KEEP};
- public ChunkStatus status;
- public ChunkMB mb;
- BlockData bd;
- public bool changed = false;
- public bool treeCreated = false;
- string BuildChunkFileName(Vector3 v)
- {
- return Application.persistentDataPath + "/savedata/Chunk_" +
- (int)v.x + "_" +
- (int)v.y + "_" +
- (int)v.z +
- "_" + World.chunkSize +
- "_" + World.radius +
- ".dat";
- }
- bool Load() //read data from file
- {
- string chunkFile = BuildChunkFileName(chunk.transform.position);
- if(File.Exists(chunkFile))
- {
- BinaryFormatter bf = new BinaryFormatter();
- FileStream file = File.Open(chunkFile, FileMode.Open);
- bd = new BlockData();
- bd = (BlockData) bf.Deserialize(file);
- file.Close();
- //Debug.Log("Loading chunk from file: " + chunkFile);
- return true;
- }
- return false;
- }
- public void Save() //write data to file
- {
- string chunkFile = BuildChunkFileName(chunk.transform.position);
- if(!File.Exists(chunkFile))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(chunkFile));
- }
- BinaryFormatter bf = new BinaryFormatter();
- FileStream file = File.Open(chunkFile, FileMode.OpenOrCreate);
- bd = new BlockData(chunkData);
- bf.Serialize(file, bd);
- file.Close();
- }
- //This method deals with the actual building of the chunk and later in the method contains the parameters it will use.
- //Such as grass on the top level red and blue blocks at the base of the world and end block at the very bottom
- void BuildChunk()
- {
- bool dataFromFile = false;
- dataFromFile = Load();
- chunkData = new Block[World.chunkSize,World.chunkSize,World.chunkSize];
- for(int z = 0; z < World.chunkSize; z++)
- for(int y = 0; y < World.chunkSize; y++)
- for(int x = 0; x < World.chunkSize; x++)
- {
- //creates a position for the block from the x,y,z values of the loop
- //Chunk can move anywhere but the blocks origin is 0,0,0 of the chunk
- Vector3 pos = new Vector3(x,y,z);
- int worldX = (int)(x + chunk.transform.position.x);
- int worldY = (int)(y + chunk.transform.position.y);
- int worldZ = (int)(z + chunk.transform.position.z);
- if(dataFromFile)
- {
- chunkData[x,y,z] = new Block(bd.matrix[x, y, z], pos,
- chunk.gameObject, this);
- continue;
- }
- int surfaceHeight = Utils.GenerateHeight(worldX,worldZ);
- //All the blocks are inputed here at different heights this enables new blocks to be added there heighs and frequency to be inputed
- if (worldY == 0)
- chunkData [x, y, z] = new Block (Block.BlockType.WORLDEND, pos,
- chunk.gameObject, this);
- else if (worldY <= Utils.GenerateStoneHeight (worldX, worldZ)) {
- //values for placement in world /chunk
- //Check if the proberbility is <
- if (Utils.fBM3D (worldX, worldY, worldZ, 0.01f, 2) < 0.4f && worldY < 40)
- chunkData [x, y, z] = new Block (Block.BlockType.BLUE, pos,
- chunk.gameObject, this);
- else if (Utils.fBM3D (worldX, worldY, worldZ, 0.03f, 3) < 0.41f && worldY < 20)
- chunkData [x, y, z] = new Block (Block.BlockType.RED, pos,
- chunk.gameObject, this);
- else
- chunkData [x, y, z] = new Block (Block.BlockType.GREY, pos,
- chunk.gameObject, this);
- } else if (worldY == surfaceHeight) {
- if (Utils.fBM3D (worldX, worldY, worldZ, 0.4F, 2) < 0.4F)
- chunkData [x, y, z] = new Block (Block.BlockType.WOODBASE, pos,
- chunk.gameObject, this);
- else {
- chunkData [x, y, z] = new Block (Block.BlockType.GREEN, pos,
- chunk.gameObject, this);
- chunk.gameObject.tag = "Green";
- }
- } else if (worldY < surfaceHeight) {
- chunkData [x, y, z] = new Block (Block.BlockType.BROWN, pos,
- chunk.gameObject, this);
- chunk.gameObject.tag = "BROWN";
- }
- else if(worldY < 65)
- chunkData[x,y,z] = new Block(Block.BlockType.WATER, pos,
- fluid.gameObject, this);
- else
- {
- chunkData[x,y,z] = new Block(Block.BlockType.AIR, pos,
- chunk.gameObject, this);
- }
- if (chunkData [x, y, z].bType != Block.BlockType.WATER && Utils.fBM3D (worldX, worldY, worldZ, 0.1f, 3) < 0.42f)
- chunkData [x, y, z] = new Block (Block.BlockType.AIR, pos,
- chunk.gameObject, this);
- status = ChunkStatus.DRAW;
- }
- }
- public void Redraw()
- {
- GameObject.DestroyImmediate(chunk.GetComponent<MeshFilter>());
- GameObject.DestroyImmediate(chunk.GetComponent<MeshRenderer>());
- GameObject.DestroyImmediate(chunk.GetComponent<Collider>());
- GameObject.DestroyImmediate(fluid.GetComponent<MeshFilter>());
- GameObject.DestroyImmediate(fluid.GetComponent<MeshRenderer>());
- GameObject.DestroyImmediate(fluid.GetComponent<Collider>());
- DrawChunk();
- }
- //This handles the creation of trees the height setting and so forth of the trees is done in build trees.
- // It also handles the drawing of the chunk z/y/x being the parameters of generation
- public void DrawChunk()
- {
- if (!treeCreated)
- {
- for (int z = 0; z < World.chunkSize; z++)
- for (int y = 0; y < World.chunkSize; y++)
- for (int x = 0; x < World.chunkSize; x++)
- {
- BuildTrees (chunkData [x, y, z], x, y, z);
- }
- treeCreated = true;
- }
- for(int z = 0; z < World.chunkSize; z++)
- for(int y = 0; y < World.chunkSize; y++)
- for(int x = 0; x < World.chunkSize; x++)
- {
- chunkData[x,y,z].Draw();
- }
- CombineQuads(chunk.gameObject, cubeMaterial);
- MeshCollider collider = chunk.gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider;
- collider.sharedMesh = chunk.transform.GetComponent<MeshFilter>().mesh;
- CombineQuads(fluid.gameObject, fluidMaterial);
- status = ChunkStatus.DONE;
- }
- //This is where the height and the requirements for a tree are set
- void BuildTrees(Block trunk, int x, int y, int z)
- {
- if (trunk.bType != Block.BlockType.WOODBASE) //if chunk is not a wood base just return
- return;
- Block t = trunk.GetBlock (x, y + 1, z); //Get chunk block y + 1 above the base of the tree (Wood)
- if (t != null)
- {
- t.SetType (Block.BlockType.WOOD); //set to wood
- Block t1 = t.GetBlock (x, y + 2, z); //go up tree build up
- if (t1 != null)
- {
- t1.SetType (Block.BlockType.WOOD);
- //building the leaves after the tree has hit required height
- for (int i = -1; i <= 1; i++)
- for (int j = -1; j <= 1; j++)
- for (int k = 3; k <= 4; k++)
- {
- Block t2 = trunk.GetBlock (x + i, y + k, z + j);
- if (t2 != null)
- t2.SetType (Block.BlockType.LEAVES);
- else
- return;
- }
- Block t3 = t1.GetBlock (x, y + 5, z);
- if (t3 != null)
- {
- t3.SetType (Block.BlockType.LEAVES); // place one on top at the end for top of tree
- }
- }
- }
- }
- public Chunk(){}
- // Use this for initialization
- public Chunk (Vector3 position, Material c, Material t) {
- chunk = new GameObject(World.BuildChunkName(position));
- chunk.transform.position = position;
- fluid = new GameObject(World.BuildChunkName(position)+"_F");
- fluid.transform.position = position; //holds fluid block meshes instead
- mb = chunk.AddComponent<ChunkMB>();
- mb.SetOwner(this);
- cubeMaterial = c;
- fluidMaterial = t;//holding material before building the chunk (The fluid material)
- BuildChunk();
- }
- //This is the intial script that uses combining of the four sides of a plane creating a cube.
- public void CombineQuads(GameObject o, Material m)
- {
- //1. Combine all children meshes
- MeshFilter[] meshFilters = o.GetComponentsInChildren<MeshFilter>();
- CombineInstance[] combine = new CombineInstance[meshFilters.Length];
- int i = 0;
- while (i < meshFilters.Length) {
- combine[i].mesh = meshFilters[i].sharedMesh;
- combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
- i++;
- }
- //2. Create a new mesh on the parent object
- MeshFilter mf = (MeshFilter) o.gameObject.AddComponent(typeof(MeshFilter));
- mf.mesh = new Mesh();
- //3. Add combined meshes on children as the parent's mesh
- mf.mesh.CombineMeshes(combine);
- //4. Create a renderer for the parent
- MeshRenderer renderer = o.gameObject.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
- renderer.material = m;
- //5. Delete all uncombined children
- foreach (Transform quad in o.transform) {
- GameObject.Destroy(quad.gameObject);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement