[Unity]Terrainに生やした草をスクリプトから消す


今作ってるゾンビゲーのコンテンツの中でterrainに生やした草を部分的に消せるようにする必要が出てきたので、テストしてみました。

まず透明のキューブをフィールド内に配置して、コライダーを「is trigger」にします。

適当な位置にキューブを配置して、terrainの草が生えてる場所に重なるように配置。

次に新しいスクリプトを作成して、キューブにアタッチします。スクリプトの名前は適当に作ってます。

以下、キューブに接触している部分の草を消すコードです。

    public float grassClearRadius = 5f;
    public int detailLayer = 0;

    private Terrain terrain;

    void Start()
    {
        terrain = Terrain.activeTerrain;



        TerrainData runtimeData = Instantiate(terrain.terrainData);
        terrain.terrainData = runtimeData;


    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject == terrain.gameObject)
        {
            ClearGrass(transform.position, grassClearRadius);
        }
    }

    void ClearGrass(Vector3 pos, float radius)
    {
        if (terrain == null) return;

        TerrainData data = terrain.terrainData;
        int detailResolution = data.detailResolution;

        Vector3 terrainPos = pos - terrain.transform.position;
        int centerX = (int)(terrainPos.x / data.size.x * detailResolution);
        int centerY = (int)(terrainPos.z / data.size.z * detailResolution);
        int size = Mathf.CeilToInt(radius / data.size.x * detailResolution);

        int[,] cleared = new int[size, size];
        data.SetDetailLayer(centerX - size / 2, centerY - size / 2, detailLayer, cleared);
    }

ontriggerenterで対象となるterrainと同じterrainならcleargrass関数を呼び出します。

grassClearRadiusが草を消す半径。detailLayerが草のレイヤー。

startの中でterrainの元データを壊さないようにしています。※これを入れないと実行終了後のデータも編集されてしまった記憶有り

ClearGrassの中でキューブの位置の指定した範囲の草を削除しています。