Unity在不同地板發(fā)出不同的聲音(上)
本文為該功能的上半部分,文章有參考很多大佬的文檔,具體會在本文最后標(biāo)注參考內(nèi)容
這個(gè)功能的目的是為了實(shí)現(xiàn)一個(gè)功能,讓角色在不同的地面發(fā)出不同的聲音

原理
Unity搭建的場景一般有兩種情況,一種是Terrain即用地形工具刷出來的地形,另一種是模型,即非地形工具的單獨(dú)模型,所以需要把地形與非地形分開
非地形的可以直接通過Layer來判斷聲音,而地形的則只能通過RGB顏色來判斷聲音,RGB顏色判斷不是那么方便,但是地形也只能這樣判斷,實(shí)在沒找到別的辦法
這里的實(shí)現(xiàn)方式是通過標(biāo)記Layer來區(qū)分不同的材質(zhì),其中地形設(shè)置成一個(gè)單獨(dú)的Layer
可能有人有個(gè)問題,是不是可以獲取物體的材質(zhì)名字來識別具體是什么材質(zhì),這樣的話就可以不用標(biāo)記Layer了,可以是可以,但是實(shí)際運(yùn)用中不少物體擁有一堆材質(zhì),并不是一個(gè)單獨(dú)材質(zhì),所以用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));
? ? ? ? }
? ? }
這個(gè)功能掛載在角色身上,就可以獲得角色踩在的Layer的名字,但是要怎么觸發(fā)呢,這里通過的方式是在動畫上掛載事件的方式執(zhí)行的,這個(gè)屬于動畫基礎(chǔ)部分了,這里就不詳細(xì)講了

我們可以用一個(gè)代碼來實(shí)現(xiàn)它
?public void setFootStepRunSound()
? ? {
//執(zhí)行LyaerCheck()
}

設(shè)置物體Lyaer
既然我們可以獲得物體的Layer了,所以我們可以為不同的Layer設(shè)置不同的聲音,比如我這有個(gè)木樓梯,我可以設(shè)置成Wood,即木頭的聲音

我們用一個(gè)簡單的代碼就可以實(shí)現(xiàn)以下效果
?public void LyaerCheck()
? ? {
? ? ? ? if (Physics.Raycast(transform.position, Vector3.down, out rh, distance))
? ? ? ? {
? ? ? ? ? ? switch (LayerMask.LayerToName(rh.transform.gameObject.layer))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case "Wood":
? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出木頭的聲音");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case "Front":
? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出地形的聲音");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出默認(rèn)的聲音");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? }


通過RGB判斷地形
我們用一個(gè)簡單的代碼就可判斷地形的RGBA顏色
?public Transform playerTransform;
? ? public Terrain t;
? ? public int posX;
? ? public int posZ;
? ? public float[] textureValues;
? ? void Start()
? ? {
? ? ? ? t = Terrain.activeTerrain;
? ? ? ? playerTransform = gameObject.transform;
? ? }
//在需要的地方運(yùn)行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];
? ? }
我們運(yùn)行一下游戲,在地上跑一下,記錄一下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("發(fā)出木頭的聲音");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case "Front":
? ? ? ? ? ? ? ? ? ? checkTerrainTexture.GetTerrainTexture();
? ? ? ? ? ? ? ? ? ? //草地
? ? ? ? ? ? ? ? ? ? if (checkTerrainTexture.textureValues[1] > 0.8f)
? ? ? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出草地的聲音");
? ? ? ? ? ? ? ? ? ? else if (checkTerrainTexture.textureValues[2] > 0.8f)
? ? ? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出沙地的聲音");
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出默認(rèn)的聲音");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? Debug.Log("發(fā)出默認(rèn)的聲音");
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? }

本期就到這里了,下一期我們將分享如何把這些發(fā)出的聲音注釋用Fmod來接入
參考資料:
在 Unity 中使用 FMOD 實(shí)現(xiàn)腳步 – 亞歷山德羅·法馬 (alessandrofama.com)
注:之后會發(fā)個(gè)視頻教程,這個(gè)是用來參考的筆記,如果看不懂可以點(diǎn)我頭像查找相關(guān)視頻,如果找不到視頻那就是視頻還沒發(fā)