【Unity】シェーダーを使ったスプライトアニメーション

スプライト画像はtktk様よりお借りしました。
環境
- Unity 2021.2.11f1
- Build-in Rendering Pipline
スプライトアニメーション
1枚の画像にコマをすべていれ、コマを切り替えることでアニメーションをさせることを
スプライトアニメーションといいます。
今回は、ShaderLab を使ってスプライトアニメーションを実装します。
SpriteAnimation.shader
https://gist.github.com/went5/659c0b7ff351e697863cef4fd3f07e58
実装に使うスプライト
以下の画像は私が制作したものなので、ご自由にお使いください。

スプライトを表示する
fixed4 frag(v2f i):SV_Target
{
fixed4 color = tex2D(_MainTex, i.uv);
clip(color.a - 0.1);
return color;
}
vertex シェーダーから受け取った uv座標をtex2d関数に入れて、テクスチャを表示します。
clip関数を使うことでアルファが0.1以下の時に、ピクセルの描画を破棄することができます。
スプライトの一部分を表示する

fixed4 frag(v2f i):SV_Target
{
i.uv = float2(i.uv.x / 5.0 , i.uv.y / 5.0);
fixed4 color = tex2D(_MainTex, i.uv);
clip(color.a - 0.1);
return color;
}
UV座標は左下が(0,0)で右上が(1,1)となっています。
左下の「20」を表示するには、X座標と Y 座標ともに 1/5 倍すると求められます。
なぜ 1/5 かというと、5列5行となっていてすべてのコマが正方形だからです。
スプライトの一部分を切り替える

fixed4 frag(v2f i):SV_Target
{
int row = 4 - ((uint)_Time.y / 5) % 5;
int column = (uint)_Time.y % 5;
i.uv = float2(i.uv.x / 5.0 + column / 5.0, i.uv.y / 5.0 + row / 5.0);
fixed4 color = tex2D(_MainTex, i.uv);
clip(color.a - 0.1);
return color;
}
列について
列(column)に注目します。
先ほどの部分切り取りしたUV座標のXに1/5を足すと、1つ右のコマにずらすことができます。
コードで表すと以下のようになります。
int nextColumn = i.uv.x / 5.0 + 1/5;
hlsl
次は、時間によってどんどん右のコマにずらす方法を教えていきます。
(uint)_Time.y はシーンがロードされてからの秒数を整数部分のみ取得できる処理です。
このまま使うと、4より大きくなってしまうので、 % を使って [0,4]の範囲に収めます。
行について
次は、行(row)に注目します。
行は5秒ごとに次の行に行くような処理にしたいため、5で割ります。
そうすると int 同士の計算となるため、小数点が切り捨てられ5秒立つまで0が返ってきます。
行と同じく、4より大きくしないように % を使って[0,4]の範囲に収めます。
そして、一番上の行から進めたいので、4から引くようにします。
アニメーション速度の調整

fixed4 frag(v2f i):SV_Target {
int row = 4 -(uint)(_Time.y * _Speed) / 5 % 5;
int column = (uint)(_Time.y *_Speed) % 5;
i.uv = float2(i.uv.x / 5.0 + column / 5.0, i.uv.y / 5.0 + row / 5.0);
fixed4 color = tex2D(_MainTex, i.uv);
clip(color.a - 0.1);
return color;
}
時間にアニメーション速度をかけると、時間の速さを上げることができます。
uint でキャストしたあとの時間にかけないように注意してください。
今回は 5×5 のスプライトでしたが、 2×6など他のスプライトでも対応できるように
数値をプロパティに出すと汎用性が上がります。
その説明は割愛させていただきますが、気になる方は冒頭のソースコードをご確認ください。
Table of contents