【Unity】複数のテレイン上でテレインレイヤーによって足音を変える

投稿者: | 2021-04-04

複数あるテレイン上で、プレイヤーがいる場所のアルファマップを取得して、テレインレイヤーによって足音を変えてみます。

まず2つのテレインをおいて、三種類のテレインレイヤーでテクスチャを塗りました。

同じオブジェクトの上で場所によって足音を変えるで足音を変えるときに、テレインの上にいれば、最も濃く塗られているテレインレイヤーのインデックスを調べて足音を変えます。

float[] slatmap = new float[0];
[SerializeField] AudioClip[] m_FootstepSounds_soil; // 土の足音
[SerializeField] AudioClip[] m_FootstepSounds_gravel; // 砂利の足音

// 足音を変える
void SwitchFootStepAudio(RaycastHit hitInfo)
{
    switch (hitInfo.collider.tag)
    {
        case "Terrain":

            // テレインデータ
            TerrainData terrainData = hitInfo.collider.gameObject.GetComponent<Terrain>().terrainData;

            // アルファマップ 
            float[,,] alphaMaps = terrainData.GetAlphamaps(Mathf.FloorToInt(hitInfo.textureCoord.x * terrainData.alphamapWidth), Mathf.FloorToInt(hitInfo.textureCoord.y * terrainData.alphamapHeight), 1, 1);

            int layerCount = terrainData.alphamapLayers; // テレインレイヤーの数

            // 他のテレインに移ったら配列の要素数を変える
            if (slatmap.Length != layerCount) slatmap = new float[layerCount];

            // 三番目の配列を取り出す
            for (int i = 0; i < layerCount; i++)
            {
                slatmap[i] = alphaMaps[0, 0, i];
            }

            // 最大値のインデックス
            int maxIndex = Array.IndexOf(slatmap, Mathf.Max(slatmap));

            // テレインを名前で判別
            switch (hitInfo.collider.name)
            {

                case "Terrain":

                    // テレインレイヤーによって足音を変える
                    switch (maxIndex)
                    {
                        case 0:
                            footstepSounds = m_FootstepSounds_gravel;
                            break;
                        case 1:
                            footstepSounds = m_FootstepSounds_marble;
                            break;
                        case 2:
                            footstepSounds = m_FootstepSounds_soil;
                            break;
                        default:
                            footstepSounds = m_FootstepSounds;
                            break;
                    }
                    break;

                case "Terrain_(-10.0, 0.0, 0.0)":

                    // テレインレイヤーによって足音を変える
                    switch (maxIndex)
                    {
                        case 0:
                            footstepSounds = m_FootstepSounds_marble;
                            break;
                        case 1:
                            footstepSounds = m_FootstepSounds_soil;
                            break;
                        default:
                            footstepSounds = m_FootstepSounds;
                            break;
                    }
                    break;
            }

            break;

        case "Floor":
//...
}

テレインレイヤーのインデックスは、インスペクタのTerrain Layersの順番と同です。左から砂利、大理石、土の順に並んでいるので、switch文でその通りに場合分けしました。

しかし、もう一方のテレインでは、テレインレイヤーの数も順番も違います。

なので、テレインをオブジェクトの名前で判別して、処理を変えています。

足音はフリー素材からUnity用の足音の音源を作るの方法で作って、スクリプトにアタッチしています。

これで、複数のテレイン上でテレインレイヤーによって足音を変えられました。

【Unity】複数のテレイン上でテレインレイヤーによって足音を変える」への2件のフィードバック

  1. bb

    コメント失礼致します。

    float[] slatmap = new float[0];
    [SerializeField] AudioClip[] m_FootstepSounds_soil; // 土の足音
    [SerializeField] AudioClip[] m_FootstepSounds_gravel; // 砂利の足音

    ↑のコードはどのスクリプトのどこに差し込めばいいのでしょうか?

    返信
    1. nekoromorph 投稿作成者

      スタンダードアセットのFirstPersonControllerクラスで宣言しています。

      namespace UnityStandardAssets.Characters.FirstPerson
      { 
          [RequireComponent(typeof(CharacterController))]
          [RequireComponent(typeof(AudioSource))]
          public class FirstPersonController : MonoBehaviour
          {
      
      	// このブロック
      
      
          }
      }

      足音を変えるメソッドは、こちらの中盤のように、同じスクリプトのPlayFootStepAudioメソッドの中で使っています。

      返信

コメントを残す

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