Ejemplo n.º 1
0
    public void AddBrick(Vector3 pos)
    {
        BrickInformation bi   = WorldInformation[pos];
        GameObject       mesh = bi.mesh;

        bi.bt = BrickType.rock;
        GenerateMesh(mesh);
        UpdateBricks(pos);
    }
Ejemplo n.º 2
0
    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);
    }
Ejemplo n.º 3
0
    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;
                    }
                }
            }
        }
    }
Ejemplo n.º 4
0
    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();
            }
        }
    }
Ejemplo n.º 5
0
    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();
    }
Ejemplo n.º 6
0
    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();
    }
Ejemplo n.º 7
0
    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);
            }
        }
    }
Ejemplo n.º 8
0
    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;
                        }
                    }
                }
            }
        }
    }