欢迎光临散文网 会员登陆 & 注册

Unity在不同地板发出不同的声音(上)

2023-04-26 12:00 作者:枫2  | 我要投稿

本文为该功能的上半部分,文章有参考很多大佬的文档,具体会在本文最后标注参考内容

这个功能的目的是为了实现一个功能,让角色在不同的地面发出不同的声音

原理

Unity搭建的场景一般有两种情况,一种是Terrain即用地形工具刷出来的地形,另一种是模型,即非地形工具的单独模型,所以需要把地形与非地形分开

非地形的可以直接通过Layer来判断声音,而地形的则只能通过RGB颜色来判断声音,RGB颜色判断不是那么方便,但是地形也只能这样判断,实在没找到别的办法

这里的实现方式是通过标记Layer来区分不同的材质,其中地形设置成一个单独的Layer

可能有人有个问题,是不是可以获取物体的材质名字来识别具体是什么材质,这样的话就可以不用标记Layer了,可以是可以,但是实际运用中不少物体拥有一堆材质,并不是一个单独材质,所以用Layer更靠谱

获得物体Layer

public RaycastHit rh;

public float distance = 10.0f;

    public void LyaerCheck()

    {

        if (Physics.Raycast(transform.position, Vector3.down, out rh, distance))

        {

            //LayerMask.LayerToName 可以获得Layer的名字,如果直接rh.transform.gameObject.layer,返回的是编号

            Debug.Log(LayerMask.LayerToName(rh.transform.gameObject.layer));

        }

    }

这个功能挂载在角色身上,就可以获得角色踩在的Layer的名字,但是要怎么触发呢,这里通过的方式是在动画上挂载事件的方式执行的,这个属于动画基础部分了,这里就不详细讲了

我们可以用一个代码来实现它

 public void setFootStepRunSound()

    {

//执行LyaerCheck()

}


设置物体Lyaer

既然我们可以获得物体的Layer了,所以我们可以为不同的Layer设置不同的声音,比如我这有个木楼梯,我可以设置成Wood,即木头的声音

我们用一个简单的代码就可以实现以下效果

 public void LyaerCheck()

    {

        if (Physics.Raycast(transform.position, Vector3.down, out rh, distance))

        {


            switch (LayerMask.LayerToName(rh.transform.gameObject.layer))

            {

                case "Wood":

                    Debug.Log("发出木头的声音");

                    break;

                case "Front":

                    Debug.Log("发出地形的声音");

                    break;

                default:

                    Debug.Log("发出默认的声音");

                    break;

            }

        }

    }


通过RGB判断地形

我们用一个简单的代码就可判断地形的RGBA颜色

 public Transform playerTransform;

    public Terrain t;

    public int posX;

    public int posZ;

    public float[] textureValues;

    void Start()

    {

        t = Terrain.activeTerrain;

        playerTransform = gameObject.transform;

    }

//在需要的地方运行GetTerrainTexture()即可获得地面的颜色

    public void GetTerrainTexture()

    {

        ConvertPosition(playerTransform.position);

        CheckTexture();

    }

    void ConvertPosition(Vector3 playerPosition)

    {

        Vector3 terrainPosition = playerPosition - t.transform.position;

        Vector3 mapPosition = new Vector3

        (terrainPosition.x / t.terrainData.size.x, 0,

        terrainPosition.z / t.terrainData.size.z);

        float xCoord = mapPosition.x * t.terrainData.alphamapWidth;

        float zCoord = mapPosition.z * t.terrainData.alphamapHeight;

        posX = (int)xCoord;

        posZ = (int)zCoord;

    }

    void CheckTexture()

    {

        float[,,] aMap = t.terrainData.GetAlphamaps(posX, posZ, 1, 1);

        textureValues[0] = aMap[0, 0, 0];

        textureValues[1] = aMap[0, 0, 1];

        textureValues[2] = aMap[0, 0, 2];

        textureValues[3] = aMap[0, 0, 3];

    }


我们运行一下游戏,在地上跑一下,记录一下RGBA值

然后修改下代码

 public void LyaerCheck()

    {

        if (Physics.Raycast(transform.position, Vector3.down, out rh, distance))

        {


            switch (LayerMask.LayerToName(rh.transform.gameObject.layer))

            {

                case "Wood":

                    Debug.Log("发出木头的声音");

                    break;

                case "Front":

                    checkTerrainTexture.GetTerrainTexture();

                    //草地

                    if (checkTerrainTexture.textureValues[1] > 0.8f)

                        Debug.Log("发出草地的声音");

                    else if (checkTerrainTexture.textureValues[2] > 0.8f)

                        Debug.Log("发出沙地的声音");

                    else

                        Debug.Log("发出默认的声音");

                    break;

                default:

                    Debug.Log("发出默认的声音");

                    break;

            }

        }

    }

本期就到这里了,下一期我们将分享如何把这些发出的声音注释用Fmod来接入

参考资料:

在 Unity 中使用 FMOD 实现脚步 – 亚历山德罗·法马 (alessandrofama.com)

注:之后会发个视频教程,这个是用来参考的笔记,如果看不懂可以点我头像查找相关视频,如果找不到视频那就是视频还没发


Unity在不同地板发出不同的声音(上)的评论 (共 条)

分享到微博请遵守国家法律