Unity 場景草的擺動與優化
場景地形如果使用mesh來做,就不能使用Unity的草系統了。因此模擬了一套草的系統,且支援草與人物的互動,即當玩家走過草堆,草會做出相應的搖擺。
首先,在場景中的草是會自己左右搖擺,這些動畫都放在了頂點shader中完成。在美術做草的mesh中,加了要求。草的UV座標有一個規則,即草根部頂點的UV座標的y為0.
這樣,在shader中,就可以通過uv座標來判斷哪些頂點需要搖擺,哪些不需要(很明顯,草根的頂點是不需要搖擺的)。
先把頂點變換到世界座標系下,呼叫下列函式,來改變頂點的位置。玩家與草的互動資訊是儲存在mesh的uv1中的,這個資料時每幀更新的。
float4 GrassRock(float4 pos, float2 uv, float2 uv1 float dir)
{
if (uv.y > 0.99)
{
float windx = 0;
float windz = 0;
if ( dir >0 )
{
windx = sin(_Time.y * _WindSpeed);
}
else
{
windz = cos(_Time.y * _WindSpeed);
}
if (uv1.x >0)
{
float percentage = 1- uv1.x/(_totalTime);
if (dir < 0)
{
windx += sin(uv1.x * _RockSpeed) * _RockPower * percentage ;
windz += cos(uv1.x * _RockSpeed) * _RockPower * percentage ;
}
else
{
windx -= sin(uv1.x * _RockSpeed) * _RockPower * percentage ;
windz -= cos(uv1.x * _RockSpeed) * _RockPower * percentage ;
}
}
pos.x += windx;
pos.z += windz;
}
return pos;
}
如果場景中,存在大量的草,則需要對草做一些優化。做法是,場景編輯人員在場景中擺好草後。沒放一棵草,都會根據草的prefab的名字來給該gameobject命名(相同的prefab的草的名字就一樣)。草的gameobject是掛在場景mesh的object上面的。在進入遊戲的時候,對同一個場景mesh下的grass進行合併,規則是相同名字的grass合併成一個大的mesh。這樣繪製的效率很高。當然,如果場景很大,草很分散,有時候合併會造成不必要的效能開銷,所以在編輯的時候,加入了批次的概念,也就是grass命名的時候,編輯人員可以指定批次,相同批次的才會合併成一個mesh。
這樣效率得到很大提升!