【Unity】テレインのプレイヤーがいる場所のアルファマップを取得する

投稿者: | 2020-08-15

テレインのプレイヤーが立っている場所にどのテレインレイヤーがどのくらい塗られているかを調べてみます。

FirstPersonControllerクラスのFixedUpdate()で地面に向かって球体のレイを飛ばすので、それがtrueのときに当たったのがテレインなら、当たった場所のアルファマップを取得します。

アルファマップは三次元の配列で、三番目の配列の各要素は対応するテレインレイヤーがどのくらいの割合で塗られているかを示す値のようで、全て合計するとほぼ1になりました。参考:https://docs.unity3d.com/ja/current/ScriptReference/TerrainData.GetAlphamaps.html

RaycastHit hitInfo;
if (/* スフィアキャスト */)
{

    string hitColliderTag = hitInfo.collider.tag;

    if (hitColliderTag == "Terrain")
    {
        TerrainData terrainData = hitInfo.collider.gameObject.GetComponent<Terrain>().terrainData; // テレインデータを取得
        int _x = Mathf.FloorToInt(hitInfo.textureCoord.x * terrainData.alphamapWidth); // 読み込む場所のX座標
        int _y = Mathf.FloorToInt(hitInfo.textureCoord.y * terrainData.alphamapHeight); // 読み込む場所のY座標
        var alphamaps = terrainData.GetAlphamaps(_x, _y, 1, 1); // プレイヤーがいる場所のアルファマップを取得

        terrainText.text = "0 : " + alphamaps[0, 0, 0] + "\n" +
            "1 : " + alphamaps[0, 0, 1] + "\n" +
            "2 : " + alphamaps[0, 0, 2] + "\n" +
            "3 : " + alphamaps[0, 0, 3] + "\n" +
            "4 : " + alphamaps[0, 0, 4] + "\n" +
            "5 : " + alphamaps[0, 0, 5] + "\n" +
            "6 : " + alphamaps[0, 0, 6];

    }

テレインに付けたタグで判断して、テレインならテレインデータを取得します。RaycastHitにレイが当たった場所のテクスチャ座標が含まれているので、それとアルファマップの縦横の長さをかけて、レイが当たった場所のアルファマップ上の座標を求めて、その部分のアルファマップを取得します。

7色で塗られたテレインを歩いてみると、冒頭のGifのようにプレイヤーがいる場所の色によってアルファマップの値が変わるのがわかります。

アルファマップの三番目の配列のインデックスは、Terrainコンポーネントに追加されているテレインレイヤーと対応していて、インスペクタに追加されたのと同じ順番になっています。

冒頭のGifでも、プレイヤーの立っている場所が白いときは0番目が1になり、赤い時は1番目が1、それ以降も2:黄色、3:青、4:緑、5:茶、6:黒の順番です。

試しに黄色を削除、再追加することで、黄色以降を一つずつ前にずらして黄色を一番うしろに回してみました。

するとテレインレイヤーに対応するインデックスも同様に一つずれました。

3番目だった青が2番目、緑が3番目とずれて、最後の6番目が黄色になっています。この順番はTerrainData.terrainLayersの順番と同じようです。

上のGifでは、アルファマップと同じインデックスのテレインレイヤーの名前を表示しています。

terrainText.text = terrainData.terrainLayers[0].name +" : " + alphamaps[0, 0, 0] + "\n" +
    terrainData.terrainLayers[1].name + " : " + alphamaps[0, 0, 1] + "\n" +
    terrainData.terrainLayers[2].name + " : " + alphamaps[0, 0, 2] + "\n" +
    terrainData.terrainLayers[3].name + " : " + alphamaps[0, 0, 3] + "\n" +
    terrainData.terrainLayers[4].name + " : " + alphamaps[0, 0, 4] + "\n" +
    terrainData.terrainLayers[5].name + " : " + alphamaps[0, 0, 5] + "\n" +
    terrainData.terrainLayers[6].name + " : " + alphamaps[0, 0, 6];

また、インデックスがテレインレイヤーの数以上だとエラーになります。TerrainData.alphamapLayersやTerrainData.terrainLayers.Lengthでテレインレイヤーの数を確認できます。

色が混ざっているとき

テレインレイヤーを重ねて塗っている場合、各テレインレイヤーがどのくらい塗られているかがわかります。

だいたい見た目通りではないでしょうか。

コメントを残す

メールアドレスが公開されることはありません。