上面的图片为表面着色器的输入图片,要用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,于是网格上显示第二帧动画,以此类推,当程序运行的时候,动画就开始在网格上播放了。