上面的图片为表面着色器的输入图片,要用Shader实现动画效果。
首先,定义属性:
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TexWidth("Sheet Width",float) = 0.0
_CellAmount("Cell Amount",float) = 0.0
_Speed("Speed",Range(0.01,32)) = 12
}
_MainTex即为上面图片的输入接口,_TexWidth为图片的像素长度,以上图片导入到Unity中,大小为1024*256,所以_TexWidth的值应为1024,_CellAmount是上图中动画帧的个数,数一下为9,_Speed是动画播放的速度。
然后,开始编写表面着色器的代码:
void surf (Input IN, inout SurfaceOutput o) {
float2 spriteUV = IN.uv_MainTex;
float cellPixelWidth = _TexWidth/_CellAmount;//计算每个动画帧的长度
float cellUVPercentage = cellPixelWidth/_TexWidth;//计算每个动画帧的百分比
float timeVal = fmod(_Time.y*_Speed,_CellAmount);//时间乘以速度取模动画帧数量
timeVal = ceil(timeVal);//进一法取整
float xValue = spriteUV.x;
xValue += cellUVPercentage*timeVal*_CellAmount;
xValue *= cellUVPercentage;
spriteUV = float2(xValue,spriteUV.y);
half4 c = tex2D (_MainTex, spriteUV);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
在这个实现里面,计算timeVal是为了确定要播放动画帧中的第几帧,而xValue += cellUVPercentage*timeVal*_CellAmount很具有迷惑性,其实相当于xValue += timeVal,当时间为0时,vimeVal为0,UV的x值缩小了_CellAmount倍,所以网格中只显示第一帧动画,当时间慢慢增加,timeVal变成1时,xValue加1,再乘以cellUVPercentage,相当于位移了cellUVPercentage,于是网格上显示第二帧动画,以此类推,当程序运行的时候,动画就开始在网格上播放了。