Пример #1
0
        void OnDrawGizmos()
        {
            if (isVisible && UnityEditor.Selection.activeGameObject == gameObject)
            {
                Gizmos.matrix = transform.localToWorldMatrix;
                Gizmos.color  = Color.grey;

                Vector3 size   = new Vector3(TerrainUtils.TERRAIN_TILE_SIZE, 2, TerrainUtils.TERRAIN_TILE_SIZE);
                Vector3 center = size / 2;
                Gizmos.DrawWireCube(center, size);

                Vector3 csize = new Vector3(TerrainUtils.GRASS_TILE_CELL_SIZE, 1.5f, TerrainUtils.GRASS_TILE_CELL_SIZE);
                for (int i = 0; i < TerrainUtils.GRASS_TILE_CELL_DIM; i++)
                {
                    for (int j = 0; j < TerrainUtils.GRASS_TILE_CELL_DIM; j++)
                    {
                        GrassTileCell cell = cellMap[i, j];

                        if (cell != null)
                        {
                            Vector3 ccenter = new Vector3(i * TerrainUtils.GRASS_TILE_CELL_SIZE, 0, j * TerrainUtils.GRASS_TILE_CELL_SIZE) + csize / 2;
                            Gizmos.DrawWireCube(ccenter, csize);
                        }
                    }
                }

                Gizmos.color = Color.clear;
            }
        }
Пример #2
0
        public void OnUpdate(int updateFrame)
        {
            if (!isVisible)
            {
                return;
            }

            if (isDirty)
            {
                bool updateMesh = false;

                for (int i = 0; i < cellList.Count; i++)
                {
                    GrassTileCell cell = cellList[i];

                    if (cell.isTurbulence || cell.turbulenceScale > 1)
                    {
                        updateMesh = true;

                        float n = (!cell.isTurbulence) ? cell.turbulenceScale : cell.turbulenceScale * cell.turbulenceScaleFactor;
                        cell.waveSpeed += cell.waveSpeedStep * ((n - 1) / 2 + 1);

                        uv3[cell.vertStart + 0].x = n;
                        uv3[cell.vertStart + 0].y = cell.waveSpeed - ((float)cell.waveSpeedStart + cell.waveSpeedStep * (float)updateFrame);
                        uv3[cell.vertStart + 1].x = uv3[cell.vertStart + 0].x;
                        uv3[cell.vertStart + 1].y = uv3[cell.vertStart + 0].y;

                        if (cell.isTurbulence)
                        {
                            cell.turbulenceScaleFactor += 0.15f;
                            if (cell.turbulenceScaleFactor > 1)
                            {
                                cell.turbulenceScaleFactor = 1;
                                cell.isTurbulence          = false;
                            }
                        }
                        else
                        {
                            cell.turbulenceScale        = n > 1 ? n * 0.95f : 1;
                            cell.turbulenceScaleFactor *= 0.95f;
                        }
                    }
                }

                if (updateMesh)
                {
                    meshFilter.sharedMesh.uv3 = uv3;
                }
                else
                {
                    isDirty = false;
                }
            }
        }
Пример #3
0
        public void AddTurbulence(Vector3 pos, float radius, float scale)
        {
            if (!gameObject.activeSelf)
            {
                return;
            }

            float posx = pos.x - basePos.x;
            float posz = pos.z - basePos.z;

            float x1 = posx - radius;
            float x2 = posx + radius;

            float z1 = posz - radius;
            float z2 = posz + radius;

            // out of bounds
            if (x1 > TerrainUtils.TERRAIN_TILE_SIZE || x2 < 0f || z1 > TerrainUtils.TERRAIN_TILE_SIZE || z2 < 0f)
            {
                return;
            }

            int cx1 = TerrainUtils.PosToGrid(x1, TerrainUtils.GRASS_TILE_CELL_SIZE, TerrainUtils.GRASS_TILE_CELL_DIM);
            int cx2 = TerrainUtils.PosToGrid(x2, TerrainUtils.GRASS_TILE_CELL_SIZE, TerrainUtils.GRASS_TILE_CELL_DIM);
            int cz1 = TerrainUtils.PosToGrid(z1, TerrainUtils.GRASS_TILE_CELL_SIZE, TerrainUtils.GRASS_TILE_CELL_DIM);
            int cz2 = TerrainUtils.PosToGrid(z2, TerrainUtils.GRASS_TILE_CELL_SIZE, TerrainUtils.GRASS_TILE_CELL_DIM);

            if (scale < 0)
            {
                scale = 0;
            }

            if (scale > 1f)
            {
                radius *= scale;
            }

            for (int i = cz1; i <= cz2; i++)
            {
                for (int j = cx1; j <= cx2; j++)
                {
                    GrassTileCell cell = cellMap[j, i];

                    if (cell != null)
                    {
                        float cx = TerrainUtils.GridToPos(j, TerrainUtils.GRASS_TILE_CELL_SIZE) + TerrainUtils.GRASS_TILE_CELL_HALF_SIZE;
                        float cz = TerrainUtils.GridToPos(i, TerrainUtils.GRASS_TILE_CELL_SIZE) + TerrainUtils.GRASS_TILE_CELL_HALF_SIZE;

                        float dis = Mathf.Sqrt((cx - posx) * (cx - posx) + (cz - posz) * (cz - posz));
                        if (dis > radius)
                        {
                            continue;
                        }

                        float f = (1f - dis / radius) * 8f + 1f;
                        f *= scale;
                        if (cell.turbulenceScale < f)
                        {
                            cell.turbulenceScale = f;
                            float ff = Mathf.Acos((cx - posx) / dis);
                            if (cz < posz)
                            {
                                ff = 2 * Mathf.PI - ff;
                            }
                            cell.waveSpeed = 256 * ff / (2 * Mathf.PI);
                            if (cell.turbulenceScaleFactor < 0.1f)
                            {
                                cell.turbulenceScaleFactor = 0.1f;
                            }
                            cell.isTurbulence = true;
                            isDirty           = true;
                        }
                    }
                }
            }
        }
Пример #4
0
        private void BuildGrassTile(GrassTileData d)
        {
            if (d == null || d.textureIndeics == null)
            {
                return;
            }

            int grassCount   = 0;
            int grassCounter = 0;
            int grassSkip    = 2;

            for (int i = 0; i < d.textureIndeics.Length; i++)
            {
                for (int l = 0; l < TerrainUtils.GRASS_TILE_CELL_DIM; l++)
                {
                    for (int m = 0; m < TerrainUtils.GRASS_TILE_CELL_DIM; m++)
                    {
                        int idx = l * TerrainUtils.GRASS_TILE_CELL_DIM + m;

                        int texPos = d.texture[idx];
                        if (texPos != i || d.size[idx] <= 0)
                        {
                            continue;
                        }
                        if (grassCounter++ % grassSkip != 0)
                        {
                            continue;
                        }

                        grassCount++;
                    }
                }
            }
            if (grassCount <= 0)
            {
                return;
            }
            grassCounter = 0;

            Random.seed = d.seed;

            Vector3 tilePos = new Vector3();

            tilePos.x = (float)d.posX * TerrainUtils.TERRAIN_TILE_SIZE;
            tilePos.z = (float)d.posZ * TerrainUtils.TERRAIN_TILE_SIZE;
            tilePos.y = TerrainUtils.GetTerrainHeight(tilePos.x + TerrainUtils.TERRAIN_TILE_HALF_SIZE, tilePos.z + TerrainUtils.TERRAIN_TILE_HALF_SIZE);

            List <GrassTileCell> cellList = new List <GrassTileCell>();

            GrassTileCell[,] cellMap = new GrassTileCell[TerrainUtils.GRASS_TILE_CELL_DIM, TerrainUtils.GRASS_TILE_CELL_DIM];

            Vector3[]  vertices  = new Vector3[grassCount * 4];
            Color32[]  colors    = new Color32[grassCount * 4];
            Vector2[]  uvs       = new Vector2[grassCount * 4];
            Vector2[]  uv3       = new Vector2[grassCount * 4];
            Vector3[]  normals   = new Vector3[grassCount * 4];
            List <int> triangles = new List <int>();

            int vertIndex = 0;

            for (int i = 0; i < d.textureIndeics.Length; i++)
            {
                int texIndex = d.textureIndeics[i];

                Texture2D tex    = null;
                Rect      rect   = default(Rect);
                float     aspect = 1f;
                GetTexture(texIndex, ref tex, ref rect, ref aspect);

                for (int l = 0; l < TerrainUtils.GRASS_TILE_CELL_DIM; l++)
                {
                    for (int m = 0; m < TerrainUtils.GRASS_TILE_CELL_DIM; m++)
                    {
                        int idx = l * TerrainUtils.GRASS_TILE_CELL_DIM + m;

                        int texPos = d.texture[idx];
                        int size   = d.size[idx];

                        if (texPos != i || d.size[idx] <= 0)
                        {
                            continue;
                        }
                        if (grassCounter++ % grassSkip != 0)
                        {
                            continue;
                        }

                        float gx        = (float)m * TerrainUtils.GRASS_TILE_CELL_SIZE + Random.Range(0f, 0.26f);
                        float gz        = (float)l * TerrainUtils.GRASS_TILE_CELL_SIZE + Random.Range(0f, 0.26f);
                        float gy        = TerrainUtils.GetTerrainHeight(gx + tilePos.x, gz + tilePos.z) - tilePos.y;
                        int   rotation  = Random.Range(0, 63);
                        int   waveSpeed = Random.Range(0, 255);

                        float sx = gx;
                        float sz = gz;
                        float r  = Mathf.Deg2Rad * ((float)rotation / 64f * -60f + -30f);
                        float s  = (float)size;
                        float hw = aspect / 2f;

                        float hwsinr = hw * Mathf.Sin(r);
                        float hwcosr = hw * Mathf.Cos(r);

                        vertices[vertIndex + 0].x = -hwcosr * s + sx;
                        vertices[vertIndex + 0].y = 1 * s + gy;
                        vertices[vertIndex + 0].z = -hwsinr * s + sz;
                        vertices[vertIndex + 1].x = hwcosr * s + sx;
                        vertices[vertIndex + 1].y = 1 * s + gy;
                        vertices[vertIndex + 1].z = hwsinr * s + sz;
                        vertices[vertIndex + 2].x = -hwcosr * s + sx;
                        vertices[vertIndex + 2].y = 0 * s + gy;
                        vertices[vertIndex + 2].z = -hwsinr * s + sz;
                        vertices[vertIndex + 3].x = hwcosr * s + sx;
                        vertices[vertIndex + 3].y = 0 * s + gy;
                        vertices[vertIndex + 3].z = hwsinr * s + sz;

                        r  = Mathf.Deg2Rad * (Random.Range(0, 360f) * -60f + -30f);
                        sx = gx + Random.Range(-1f, 1f) * hw * s;
                        sz = gz + Random.Range(-1f, 1f) * hw * s;

                        uvs[vertIndex + 0].x = rect.xMin;
                        uvs[vertIndex + 0].y = rect.yMax - 0.01f;
                        uvs[vertIndex + 1].x = rect.xMax;
                        uvs[vertIndex + 1].y = rect.yMax - 0.01f;
                        uvs[vertIndex + 2].x = rect.xMin;
                        uvs[vertIndex + 2].y = rect.yMin;
                        uvs[vertIndex + 3].x = rect.xMax;
                        uvs[vertIndex + 3].y = rect.yMin;

                        colors[vertIndex + 0] = useColors[texIndex];
                        colors[vertIndex + 1] = useColors[texIndex];
                        colors[vertIndex + 2] = useColors[texIndex];
                        colors[vertIndex + 3] = useColors[texIndex];

                        uv3[vertIndex + 0].x = 1;
                        uv3[vertIndex + 0].y = waveSpeed;
                        uv3[vertIndex + 1].x = 1;
                        uv3[vertIndex + 1].y = waveSpeed;
                        uv3[vertIndex + 2].x = 0f;
                        uv3[vertIndex + 2].y = 0f;
                        uv3[vertIndex + 3].x = 0f;
                        uv3[vertIndex + 3].y = 0f;

                        normals[vertIndex + 0].x = 0f;
                        normals[vertIndex + 0].y = 1f;
                        normals[vertIndex + 0].z = 0f;
                        normals[vertIndex + 1].x = 0f;
                        normals[vertIndex + 1].y = 1f;
                        normals[vertIndex + 1].z = 0f;
                        normals[vertIndex + 2].x = 0f;
                        normals[vertIndex + 2].y = 1f;
                        normals[vertIndex + 2].z = 0f;
                        normals[vertIndex + 3].x = 0f;
                        normals[vertIndex + 3].y = 1f;
                        normals[vertIndex + 3].z = 0f;

                        triangles.Add(vertIndex + 0);
                        triangles.Add(vertIndex + 1);
                        triangles.Add(vertIndex + 2);
                        triangles.Add(vertIndex + 1);
                        triangles.Add(vertIndex + 3);
                        triangles.Add(vertIndex + 2);

                        GrassTileCell cell = new GrassTileCell();
                        cell.vertStart             = vertIndex;
                        cell.waveSpeed             = (float)waveSpeed;
                        cell.waveSpeedStart        = waveSpeed;
                        cell.waveSpeedStep         = 1 + Random.Range(0.0f, 1.0f);
                        cell.turbulenceScale       = 1;
                        cell.turbulenceScaleFactor = 0.1f;
                        cell.isTurbulence          = true;

                        cellList.Add(cell);
                        cellMap[m, l] = cell;

                        vertIndex += 4;
                    }
                }
            }

            // create grass tile
            string     tileName   = string.Format("GrassTile({0},{1})", d.posX, d.posZ);
            GameObject gameObject = new GameObject(tileName);

            gameObject.transform.parent        = transform;
            gameObject.transform.localPosition = Vector3.zero;
            gameObject.transform.localRotation = Quaternion.identity;
            gameObject.transform.localScale    = Vector3.one;
            gameObject.hideFlags = HideFlags.DontSaveInEditor;
            gameObject.layer     = LayerMask.NameToLayer("Terrain");

            gameObject.transform.localPosition = tilePos;

            Mesh mesh = new Mesh();

            mesh.vertices  = vertices;
            mesh.uv        = uvs;
            mesh.colors32  = colors;
            mesh.normals   = normals;
            mesh.uv3       = uv3;
            mesh.triangles = triangles.ToArray();

            MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>();

            if (meshFilter == null)
            {
                meshFilter = gameObject.AddComponent <MeshFilter>();
            }
            meshFilter.sharedMesh = mesh;

            MeshRenderer meshRenderer = gameObject.GetComponent <MeshRenderer>();

            if (meshRenderer == null)
            {
                meshRenderer = gameObject.AddComponent <MeshRenderer>();
            }
            meshRenderer.sharedMaterial    = packedMaterial;
            meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
            mesh.MarkDynamic();

            GrassTile tile = gameObject.GetComponent <GrassTile>();

            if (tile == null)
            {
                tile = gameObject.AddComponent <GrassTile>();
            }
            tile.basePos      = tilePos;
            tile.cellList     = cellList;
            tile.cellMap      = cellMap;
            tile.meshRenderer = meshRenderer;
            tile.meshFilter   = meshFilter;
            tile.uv3          = uv3;
            tile.Init();
            tileList.Add(tile);
        }