public void AddBrick(Vector3 pos) { BrickInformation bi = WorldInformation[pos]; GameObject mesh = bi.mesh; bi.bt = BrickType.rock; GenerateMesh(mesh); UpdateBricks(pos); }
public void AddWaterBlock(Vector3 pos) { BrickInformation bi = WorldInformation[pos]; GameObject mesh = bi.mesh; bi.bt = BrickType.air; bi.waterLevel = 9; GenerateMesh(mesh); var neighbors = GetImmediateNeighbors(pos); FlowingWater.Add(bi); }
public void TreeUpdate() { //NEEDS TO BE REDONE float seasonGrassLimit = cd.seasonData[gt.season].GrowthValue / 5f; int growthRate = 1; if (gt.season == Season.Spring) { growthRate = 3; } else if (gt.season == Season.Summer) { growthRate = 1; } else if (gt.season == Season.Autumn) { growthRate = 2; } else if (gt.season == Season.Winter) { growthRate = 4; } List <Vector3> surface = lg.SurfaceBricks.Where(p => p.Value.bt == BrickType.dirt).Select(p => p.Key).ToList();//lg.WorldInformation.Where(p => p.Value.SurfaceBrick && p.Value.bt == BrickType.dirt).Select(p => p.Key).ToList(); FastNoiseLite fnl = TreeGeneration(seed + 10); int limitPerUpdate = growthRate; foreach (Vector3 pos in surface.OrderBy(a => Guid.NewGuid())) { BrickInformation bi = lg.WorldInformation[pos]; float height = Mathf.Clamp(fnl.GetNoise(pos.x, pos.z), 0, 1); if (height < seasonGrassLimit) //grow grass { if (!bi.tree) { GameObject go = Instantiate(treePrefab); go.transform.position = pos + new Vector3(0, 0.5f, 0); bi.TreeObjects = go; bi.tree = true; limitPerUpdate--; if (limitPerUpdate <= 0) { break; } } } } }
public void UpdateBricks(Vector3 pos) { List <Vector3> Neighbors = GetNeighbors(pos, 1, true); foreach (Vector3 neighbor in Neighbors) { BrickInformation neighBrick = WorldInformation[neighbor]; //recheck if you are a surface brick if (neighBrick.bt != BrickType.air) { BrickInformation aboveNeighBrick = WorldInformation[neighbor + Vector3.up]; if (aboveNeighBrick.bt == BrickType.air && !aboveNeighBrick.water) { neighBrick.SurfaceBrick = true; if (!SurfaceBricks.ContainsKey(neighbor)) { SurfaceBricks.Add(neighbor, neighBrick); } } else { neighBrick.SurfaceBrick = false; if (SurfaceBricks.ContainsKey(neighbor)) { SurfaceBricks.Remove(neighbor); } } } if (!neighBrick.SurfaceBrick && neighBrick.grassObjects.Count > 0) { foreach (GameObject go in neighBrick.grassObjects) { Destroy(go); } neighBrick.grassObjects.Clear(); } } }
public void GenerateMesh(GameObject meshGO) { Mesh m = new Mesh(); //m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; MeshFilter mf = meshGO.GetComponent <MeshFilter>(); MeshRenderer mr = meshGO.GetComponent <MeshRenderer>(); mr.material = terrainMat; mf.mesh = m; //List<Vector3> normals = new List<Vector3>(); List <int> triangles = new List <int>(); List <Vector3> Verts = new List <Vector3>(); List <Vector3> allNormals = new List <Vector3>(); List <Vector2> allUVs = new List <Vector2>(); foreach (Vector3 pos in MeshChunks[meshGO]) { BrickInformation bi = WorldInformation[pos]; if (bi.bt == BrickType.air && bi.waterLevel == 0) { continue; } //Vector3 pos = pair.Key; List <Vector3> airNeighbors = GetAirNeighbors(pos); foreach (Vector3 airNeighbor in airNeighbors) { Vector3 v = airNeighbor - pos; if (WorldInformation.ContainsKey(airNeighbor)) { BrickInformation biNeighbor = WorldInformation[airNeighbor]; if (v == Vector3.up && !biNeighbor.water) { bi.SurfaceBrick = true; if (!SurfaceBricks.ContainsKey(pos)) { SurfaceBricks.Add(pos, bi); } } } List <Vector3> newVertexs = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); //messy but I dont wanna calc perpendiculars if (bi.bt == BrickType.air && bi.waterLevel > 0) { if (v.x != 0) { newVertexs = new List <Vector3>() { pos + new Vector3(v.x / 2f, (bi.waterLevel * .1f - .5f), .5f), pos + new Vector3(v.x / 2f, -.5f, .5f), pos + new Vector3(v.x / 2f, (bi.waterLevel * .1f - .5f), -.5f), pos + new Vector3(v.x / 2f, -.5f, -.5f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } else if (v.y < 0) { newVertexs = new List <Vector3>() { pos + new Vector3(.5f, v.y / 2f, .5f), pos + new Vector3(.5f, v.y / 2f, -.5f), pos + new Vector3(-.5f, v.y / 2f, .5f), pos + new Vector3(-.5f, v.y / 2f, -.5f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } else if (v.y > 0) { newVertexs = new List <Vector3>() { pos + new Vector3(.5f, (bi.waterLevel * .1f - .5f), .5f), pos + new Vector3(.5f, (bi.waterLevel * .1f - .5f), -.5f), pos + new Vector3(-.5f, (bi.waterLevel * .1f - .5f), .5f), pos + new Vector3(-.5f, (bi.waterLevel * .1f - .5f), -.5f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } else if (v.z != 0) { newVertexs = new List <Vector3>() { pos + new Vector3(.5f, (bi.waterLevel * .1f - .5f), v.z / 2f), pos + new Vector3(-.5f, (bi.waterLevel * .1f - .5f), v.z / 2f), pos + new Vector3(.5f, -.5f, v.z / 2f), pos + new Vector3(-.5f, -.5f, v.z / 2f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } } else { if (v.x != 0) { newVertexs = new List <Vector3>() { pos + new Vector3(v.x / 2f, .5f, .5f), pos + new Vector3(v.x / 2f, -.5f, .5f), pos + new Vector3(v.x / 2f, .5f, -.5f), pos + new Vector3(v.x / 2f, -.5f, -.5f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } else if (v.y != 0) { newVertexs = new List <Vector3>() { pos + new Vector3(.5f, v.y / 2f, .5f), pos + new Vector3(.5f, v.y / 2f, -.5f), pos + new Vector3(-.5f, v.y / 2f, .5f), pos + new Vector3(-.5f, v.y / 2f, -.5f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } else if (v.z != 0) { newVertexs = new List <Vector3>() { pos + new Vector3(.5f, .5f, v.z / 2f), pos + new Vector3(-.5f, .5f, v.z / 2f), pos + new Vector3(.5f, -.5f, v.z / 2f), pos + new Vector3(-.5f, -.5f, v.z / 2f), }; for (int i = 0; i < 4; i++) { normals.Add(v); } } } if (v.x > 0 || v.y > 0 || v.z > 0) { triangles.Add(Verts.Count()); triangles.Add(Verts.Count() + 3); triangles.Add(Verts.Count() + 2); triangles.Add(Verts.Count()); triangles.Add(Verts.Count() + 1); triangles.Add(Verts.Count() + 3); } else { triangles.Add(Verts.Count() + 0); triangles.Add(Verts.Count() + 2); triangles.Add(Verts.Count() + 3); triangles.Add(Verts.Count() + 0); triangles.Add(Verts.Count() + 3); triangles.Add(Verts.Count() + 1); } Verts.AddRange(newVertexs); allNormals.AddRange(normals); List <Vector2> UVs = new List <Vector2>(); if (bi.bt == BrickType.dirt) { if (v == Vector3.up) { UVs.Add(new Vector2(64f / 1280f, 127f / 1280f)); UVs.Add(new Vector2(64f / 1280f, 64f / 1280f)); UVs.Add(new Vector2(0f / 1280f, 127f / 1280f)); UVs.Add(new Vector2(0f / 1280f, 64f / 1280f)); } else { UVs.Add(new Vector2(63f / 1280f, 63f / 1280f)); UVs.Add(new Vector2(63f / 1280f, 0)); UVs.Add(new Vector2(0, 63f / 1280f)); UVs.Add(new Vector2(0, 0)); } } else if (bi.bt == BrickType.rock) { UVs.Add(new Vector2(127f / 1280f, 64f / 1280f)); UVs.Add(new Vector2(127f / 1280f, 0f / 1280f)); UVs.Add(new Vector2(64f / 1280f, 64f / 1280f)); UVs.Add(new Vector2(64f / 1280f, 0f / 1280f)); } else if (bi.bt == BrickType.air) { UVs.Add(new Vector2(191f / 1280f, 64f / 1280f)); UVs.Add(new Vector2(191f / 1280f, 0f / 1280f)); UVs.Add(new Vector2(191f / 1280f, 64f / 1280f)); UVs.Add(new Vector2(191f / 1280f, 0f / 1280f)); } allUVs.AddRange(UVs); } } m.Clear(); m.vertices = Verts.ToArray(); m.triangles = triangles.ToArray(); m.normals = allNormals.ToArray(); m.uv = allUVs.ToArray(); m.Optimize(); m.RecalculateBounds(); m.RecalculateTangents(); // m.RecalculateNormals(); }
public void InitialGrassAndTreeSpawn() { MeshRenderer mrTree = TreeMeshs.AddComponent <MeshRenderer>(); mrTree.material = treeMat; MeshFilter mfTree = TreeMeshs.AddComponent <MeshFilter>(); Mesh treeMesh = new Mesh(); mfTree.mesh = treeMesh; MeshRenderer mrGrass = GrassMeshs.AddComponent <MeshRenderer>(); mrGrass.material = grassMat; MeshFilter mfGrass = GrassMeshs.AddComponent <MeshFilter>(); Mesh grassMesh = new Mesh(); mfGrass.mesh = grassMesh; List <int> treeTriangles = new List <int>(); List <Vector3> treeVerts = new List <Vector3>(); List <Vector2> treeUVs = new List <Vector2>(); List <int> grassTriangles = new List <int>(); List <Vector3> grassVerts = new List <Vector3>(); List <Vector2> grassUVs = new List <Vector2>(); float seasonGrassLimit = ge.cd.seasonData[ge.gt.season].GrowthValue * 1.5f; float seasonTreeLimit = ge.cd.seasonData[ge.gt.season].GrowthValue; List <Vector3> surface = SurfaceBricks.Where(p => p.Value.bt == BrickType.dirt).Select(p => p.Key).ToList();//lg.WorldInformation.Where(p => p.Value.SurfaceBrick && p.Value.bt == BrickType.dirt).Select(p => p.Key).ToList(); FastNoiseLite fnlGRASS = ge.GrassGeneration(ge.seed); FastNoiseLite fnlTREE = ge.TreeGeneration(ge.seed + 10); var temp = GetFNLMin(fnlGRASS); float grassMin = temp[0]; float grassMax = temp[1]; temp = GetFNLMin(fnlTREE); float treeMin = temp[0]; float treeMax = temp[1]; foreach (Vector3 pos in surface.OrderBy(a => Guid.NewGuid())) { BrickInformation bi = WorldInformation[pos]; float heightGrass = (fnlGRASS.GetNoise(pos.x, pos.z) - grassMin) / (grassMax - grassMin); float heightTree = (fnlTREE.GetNoise(pos.x, pos.z) - treeMin) / (treeMax - treeMin); if (heightGrass < seasonGrassLimit) //grow grass { if (!bi.grass) { bi.grass = true; for (int i = 0; i < 3; i++) { grassTriangles.Add(treeVerts.Count()); grassTriangles.Add(treeVerts.Count() + 3); grassTriangles.Add(treeVerts.Count() + 2); grassTriangles.Add(treeVerts.Count()); grassTriangles.Add(treeVerts.Count() + 1); grassTriangles.Add(treeVerts.Count() + 3); grassTriangles.Add(treeVerts.Count() + 4); grassTriangles.Add(treeVerts.Count() + 7); grassTriangles.Add(treeVerts.Count() + 6); grassTriangles.Add(treeVerts.Count() + 4); grassTriangles.Add(treeVerts.Count() + 5); grassTriangles.Add(treeVerts.Count() + 7); Vector3 diplacement = new Vector3(UnityEngine.Random.Range(-0.3f, .3f), UnityEngine.Random.Range(-0.05f, 0), UnityEngine.Random.Range(-0.3f, .3f)); grassVerts.Add(pos + new Vector3(0.1f, .7f, 0) + diplacement); grassVerts.Add(pos + new Vector3(0.1f, .5f, 0) + diplacement); grassVerts.Add(pos + new Vector3(-0.1f, .7f, 0) + diplacement); grassVerts.Add(pos + new Vector3(-0.1f, .5f, 0) + diplacement); grassVerts.Add(pos + new Vector3(0, .7f, .1f) + diplacement); grassVerts.Add(pos + new Vector3(0, .5f, .1f) + diplacement); grassVerts.Add(pos + new Vector3(0, .7f, -.1f) + diplacement); grassVerts.Add(pos + new Vector3(0, .5f, -.1f) + diplacement); grassUVs.Add(new Vector2(1, 1)); grassUVs.Add(new Vector2(1, 0)); grassUVs.Add(new Vector2(0, 1)); grassUVs.Add(new Vector2(0, 0)); grassUVs.Add(new Vector2(1, 1)); grassUVs.Add(new Vector2(1, 0)); grassUVs.Add(new Vector2(0, 1)); grassUVs.Add(new Vector2(0, 0)); } } } if (heightTree < seasonTreeLimit) //grow grass { if (!bi.tree) { bi.tree = true; treeTriangles.Add(treeVerts.Count()); treeTriangles.Add(treeVerts.Count() + 3); treeTriangles.Add(treeVerts.Count() + 2); treeTriangles.Add(treeVerts.Count()); treeTriangles.Add(treeVerts.Count() + 1); treeTriangles.Add(treeVerts.Count() + 3); treeTriangles.Add(treeVerts.Count() + 4); treeTriangles.Add(treeVerts.Count() + 7); treeTriangles.Add(treeVerts.Count() + 6); treeTriangles.Add(treeVerts.Count() + 4); treeTriangles.Add(treeVerts.Count() + 5); treeTriangles.Add(treeVerts.Count() + 7); Vector3 diplacement = new Vector3(UnityEngine.Random.Range(-0.3f, .3f), UnityEngine.Random.Range(-0.3f, 0), UnityEngine.Random.Range(-0.3f, .3f)); treeVerts.Add(pos + new Vector3(0.5f, 2.5f, 0) + diplacement); treeVerts.Add(pos + new Vector3(0.5f, .5f, 0) + diplacement); treeVerts.Add(pos + new Vector3(-0.5f, 2.5f, 0) + diplacement); treeVerts.Add(pos + new Vector3(-0.5f, .5f, 0) + diplacement); treeVerts.Add(pos + new Vector3(0, 2.5f, .5f) + diplacement); treeVerts.Add(pos + new Vector3(0, .5f, .5f) + diplacement); treeVerts.Add(pos + new Vector3(0, 2.5f, -.5f) + diplacement); treeVerts.Add(pos + new Vector3(0, .5f, -.5f) + diplacement); treeUVs.Add(new Vector2(1, 1)); treeUVs.Add(new Vector2(1, 0)); treeUVs.Add(new Vector2(0, 1)); treeUVs.Add(new Vector2(0, 0)); treeUVs.Add(new Vector2(1, 1)); treeUVs.Add(new Vector2(1, 0)); treeUVs.Add(new Vector2(0, 1)); treeUVs.Add(new Vector2(0, 0)); } } } treeMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; treeMesh.Clear(); treeMesh.vertices = treeVerts.ToArray(); treeMesh.triangles = treeTriangles.ToArray(); treeMesh.uv = treeUVs.ToArray(); treeMesh.Optimize(); treeMesh.RecalculateBounds(); treeMesh.RecalculateTangents(); grassMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; grassMesh.Clear(); grassMesh.vertices = grassVerts.ToArray(); grassMesh.triangles = grassTriangles.ToArray(); grassMesh.uv = grassUVs.ToArray(); grassMesh.Optimize(); grassMesh.RecalculateBounds(); grassMesh.RecalculateTangents(); }
public void WaterUpdate() { List <BrickInformation> unflowingWater = new List <BrickInformation>(); List <BrickInformation> newFlowingWater = new List <BrickInformation>(); foreach (BrickInformation bi in lg.FlowingWater) { //first check if can flow directly down //if no information, flow everything down 1 if (lg.IsAir(bi.pos + new Vector3(0, -1, 0))) { int newBIWater = 0; int oldBIWater = bi.waterLevel; if (bi.waterLevel <= 9) { newBIWater = bi.waterLevel; oldBIWater = 0; unflowingWater.Add(bi); } else if (bi.waterLevel <= 18) { newBIWater = 9; oldBIWater = bi.waterLevel - 9; } else { newBIWater = bi.waterLevel / 2; oldBIWater = bi.waterLevel / 2; } BrickInformation newBI = lg.WorldInformation[bi.pos + new Vector3(0, -1, 0)]; newBI.waterLevel = newBIWater; bi.waterLevel = oldBIWater; newFlowingWater.Add(newBI); } else { //first check for downflow BrickInformation MinusYBI = lg.WorldInformation[bi.pos + new Vector3(0, -1, 0)]; BrickInformation MinusXBI = lg.WorldInformation[bi.pos + new Vector3(-1, 0, 0)]; BrickInformation PlusXBI = lg.WorldInformation[bi.pos + new Vector3(1, 0, 0)]; BrickInformation MinusZBI = lg.WorldInformation[bi.pos + new Vector3(0, 0, -1)]; BrickInformation PlusZBI = lg.WorldInformation[bi.pos + new Vector3(0, 0, 1)]; List <BrickInformation> sideBricks = new List <BrickInformation>(); sideBricks.Add(MinusXBI); sideBricks.Add(PlusXBI); sideBricks.Add(MinusZBI); sideBricks.Add(PlusZBI); //priority minus y bool DoneFlowing = true; if (MinusYBI.bt == BrickType.air && MinusYBI.waterLevel < 9) { DoneFlowing = false; int waterMov = Mathf.Clamp(9 - MinusYBI.waterLevel, 0, bi.waterLevel); MinusYBI.waterLevel += waterMov; bi.waterLevel -= waterMov; if (bi.waterLevel == 0) { bi.bt = BrickType.air; unflowingWater.Add(bi); } newFlowingWater.Add(MinusYBI); } sideBricks = sideBricks.Where(p => p.bt == BrickType.air).ToList(); if (sideBricks.Any(p => p.waterLevel != bi.waterLevel - 1)) { //a check to make sure at least 1 side brick is not -1 water level, if all -1 water level we stop flowing to prevent "Ping ponging" foreach (BrickInformation sideBrick in sideBricks.OrderBy(p => p.waterLevel)) { if (bi.waterLevel == 0) { break; } if (bi.waterLevel == 1 && !sideBricks.Any(p => p.waterLevel > 1)) { break; } if (sideBrick.waterLevel < bi.waterLevel) { DoneFlowing = false; bi.waterLevel--; sideBrick.waterLevel++; newFlowingWater.Add(sideBrick); } } } if (DoneFlowing) { unflowingWater.Add(bi); } } } //if (gt.minute % 5 == 0) { foreach (GameObject go in lg.FlowingWater.Select(p => p.mesh).Distinct()) { lg.GenerateMesh(go); } } foreach (BrickInformation delete in unflowingWater) { lg.FlowingWater.Remove(delete); } foreach (BrickInformation add in newFlowingWater) { if (!lg.FlowingWater.Contains(add)) { lg.FlowingWater.Add(add); } } }
public void VegetationUpdate() { // if (gt.season == Season.Spring) { float seasonGrassLimit = cd.seasonData[gt.season].GrowthValue; int growthRate = 1; if (gt.season == Season.Spring) { growthRate = 3; } else if (gt.season == Season.Summer) { growthRate = 1; } else if (gt.season == Season.Autumn) { growthRate = 2; } else if (gt.season == Season.Winter) { growthRate = 4; } List <Vector3> surface = lg.SurfaceBricks.Where(p => p.Value.bt == BrickType.dirt).Select(p => p.Key).ToList();//lg.WorldInformation.Where(p => p.Value.SurfaceBrick && p.Value.bt == BrickType.dirt).Select(p => p.Key).ToList(); FastNoiseLite fnl = GrassGeneration(seed); int limitPerUpdate = growthRate; foreach (Vector3 pos in surface.OrderBy(a => Guid.NewGuid())) { BrickInformation bi = lg.WorldInformation[pos]; float height = Mathf.Clamp(fnl.GetNoise(pos.x, pos.z), 0, 1); if (height < seasonGrassLimit) //grow grass { if (!bi.grass) { GameObject go = Instantiate(grassPrefab); go.transform.position = pos + new Vector3(UnityEngine.Random.Range(-.35f, .35f), 0.5f, UnityEngine.Random.Range(-.35f, .35f)); bi.grassObjects.Add(go); bi.grass = true; limitPerUpdate--; if (limitPerUpdate <= 0) { break; } } } else // kill grass { if (bi.grass) { foreach (GameObject go in bi.grassObjects) { Destroy(go); } bi.grassObjects.Clear(); bi.grass = false; limitPerUpdate--; if (limitPerUpdate <= 0) { break; } } } } } }