public void OnDisable()
        {
#if QINSHI
            for (int i = 0; i < subscribes.Count; i++)
            {
                Utility.EventSystem.Unsubscribe(subscribes[i]);
            }
#endif
            subscribes.Clear();

            TerrainGrassTile[,] tile = rollMap.GetAll();
            for (int i = 0; i < tile.GetLength(0); i++)
            {
                for (int j = 0; j < tile.GetLength(1); j++)
                {
                    if (tile[i, j] != null)
                    {
                        GameObject.Destroy(tile[i, j].gameObject);
                    }
                }
            }
            rollMap = null;
            for (int i = 0; i < tilePool.objects.Count; i++)
            {
                GameObject.Destroy(tilePool.objects[i].gameObject);
            }
            tilePool = null;
            meshPool = null;
            GameObject.Destroy(recyle.gameObject);
            recyle = null;
            taskList.Clear();
        }
        public void OnEnable()
        {
            m_instance = this;
#if QINSHI
            subscribes.Add(Utility.EventSystem.Subscribe <Vector3, float, float>("add_disturbance", "grass", AddDisturbance));
#endif
            terrain     = GetComponent <Terrain>();
            terrainData = terrain.terrainData;
            terrain.detailObjectDistance = 0;

            UpdatePatchVisible();

            recyle = new GameObject("recyle").transform;
            recyle.SetParent(transform, false);

            details   = terrain.terrainData.detailPrototypes;
            materials = new Material[details.Length];
            for (int i = 0; i < details.Length; i++)
            {
                materials[i]             = new Material(material);// new Material(shader);
                materials[i].mainTexture = details[i].prototypeTexture;
                materials[i].SetFloat("_GrassMinWidth", details[i].minWidth);
                materials[i].SetFloat("_GrassMaxWidth", details[i].maxWidth);
                materials[i].SetFloat("_GrassMinHeight", details[i].minHeight);
                materials[i].SetFloat("_GrassMaxHeight", details[i].maxHeight);
                materials[i].SetColor("_WavingTint", terrain.terrainData.wavingGrassTint);
                materials[i].SetColor("_GrassColor", (details[i].dryColor + details[i].healthyColor) * 0.5f);
                materials[i].SetFloat("_ViewDistance", grassViewDistance);
                materials[i].SetVector("_TerrainOffsetSize", new Vector4(terrain.transform.position.x, terrain.transform.position.z, terrainData.size.x, terrainData.size.z));
                if (terrain.lightmapIndex >= 0 && terrain.lightmapIndex < LightmapSettings.lightmaps.Length)
                {
                    materials[i].SetTexture("_Lightmap", LightmapSettings.lightmaps[terrain.lightmapIndex].lightmapColor);
                }

                int[,] density    = terrain.terrainData.GetDetailLayer(0, 0, terrain.terrainData.detailResolution, terrain.terrainData.detailResolution, i);
                short[,] sDensity = new short[density.GetLength(0), density.GetLength(1)];
                for (int x = 0; x < density.GetLength(0); x++)
                {
                    for (int y = 0; y < density.GetLength(1); y++)
                    {
                        sDensity[x, y] = (short)density[x, y];
                    }
                }
                detailDensity.Add(sDensity);
            }



            UpdateGrassShaderParams();

            meshPool        = new Pool <TerrainGrass>();
            meshPool.funNew = () => {
                GameObject obj = new GameObject("grass");
                obj.transform.SetParent(transform);
                //obj.layer = terrain.gameObject.layer;
                TerrainGrass grass = obj.AddComponent <TerrainGrass>();
                grass.Init(terrain, soft);
                return(grass);
            };

            tilePool        = new Pool <TerrainGrassTile>();
            tilePool.funNew = () => {
                GameObject obj = new GameObject("tile");
                obj.transform.SetParent(transform);
                TerrainGrassTile tile = obj.AddComponent <TerrainGrassTile>();
                return(tile);
            };

            rollNum = (int)((grassViewDistance * 2 - 0.1f) / PatchSize) + 1;

            rollMap           = new RollMap <TerrainGrassTile>(rollNum, rollNum, -10000, -10000);
            rollMap.funDelete = (TerrainGrassTile tile) => {
                if (tile)
                {
                    tile.gameObject.SetActive(false);
                    tile.transform.SetParent(recyle, false);
                    tilePool.Recycle(tile);
                    for (int i = 0; i < tile.grassList.Count; i++)
                    {
                        meshPool.Recycle(tile.grassList[i]);
                        tile.transform.SetParent(recyle, false);
                    }
                    taskList.RemoveAll((TerrainGrassTile item) => item == tile);
                }
            };
            rollMap.funNew = CreateNode;

            if (terrain.lightmapIndex >= 0 && terrain.lightmapIndex < LightmapSettings.lightmaps.Length)
            {
                Shader.SetGlobalTexture("_GrassLightmap", LightmapSettings.lightmaps[terrain.lightmapIndex].lightmapColor);
            }
        }