好久未更新,一些习惯还是应该要好好坚持啊。最近发现Android上一个很好的应用,希望每天可以坚持看一个视频,了解下最新的科技动态和演讲,也推荐给大家使用!
这次内容主要讲如何使用sprite sheets制作2D动画。在Unity中,实际上已经有很多插件可以完成这个工作,例如2dTookit,新版的Unity中支持2D应该也会提供类似的功能了。虽然如此,我还是希望通过这篇文章可以更深入地理解2D动画的原理。说到动画的原理,先要提到一个名词,sprite atlas,也可以称为image sequence,实际上就是一张大图中包含了很多张小图,如下:
当我们按照一定速率滚动这张图时,就会发现图片动起来了,这我们应该都有经验,以前看小人书快速翻动时就发现小人在动。这里实际上也是这个原理。
Properties { _MainTex ("Base (RGB)", 2D) = "white" {} // Create the properties below _TexWidth ("Sheet Width", float) = 0.0 _CellAmount ("Cell Amount", float) = 0.0 _Speed ("Speed", Range(0.01, 32)) = 12 }
CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; //Create the connection to the properties inside of the //CG program float _TexWidth; float _CellAmount; float _Speed;
//Lets store our UVs in a seperate variable float2 spriteUV = IN.uv_MainTex;之后,我们将使用该变量计算新的UV坐标。
//Lets calculate the width of a singe cell in our //sprite sheet and get a uv percentage that each cel takes up. float cellPixelWidth = _TexWidth/_CellAmount; float cellUVPercentage = cellPixelWidth/_TexWidth;但通过观察代码可以发现,缩短为一行即可:
//Lets calculate the width of a singe cell in our //sprite sheet and get a uv percentage that each cel takes up. float cellUVPercentage = 1.0/_CellAmount;
//Lets get a stair step value out of time so we can increment //the uv offset float timeVal = fmod(_Time.y * _Speed, _CellAmount); timeVal = ceil(timeVal);
//Animate the uv‘s forward by the width precentage of //each cell float xValue = spriteUV.x; xValue += cellUVPercentage * timeVal * _CellAmount; xValue *= cellUVPercentage;同样,观察cellUVPercentage的计算式,可以简化上述代码如下:
//Animate the uv‘s forward by the width precentage of //each cell float xValue = spriteUV.x; xValue += timeVal; xValue *= cellUVPercentage;
spriteUV = float2(xValue, spriteUV.y); half4 c = tex2D (_MainTex, spriteUV); o.Albedo = c.rgb; o.Alpha = c.a;
Shader "Custom/AnimateSprites" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} // Create the properties below _TexWidth ("Sheet Width", float) = 0.0 _CellAmount ("Cell Amount", float) = 0.0 _Speed ("Speed", Range(0.01, 32)) = 12 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; //Create the connection to the properties inside of the //CG program float _TexWidth; float _CellAmount; float _Speed; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { //Lets store our UVs in a seperate variable float2 spriteUV = IN.uv_MainTex; //Lets calculate the width of a singe cell in our //sprite sheet and get a uv percentage that each cel takes up. float cellUVPercentage = 1.0/_CellAmount; //Lets get a stair step value out of time so we can increment //the uv offset float timeVal = fmod(_Time.y * _Speed, _CellAmount); timeVal = ceil(timeVal); //Animate the uv‘s forward by the width precentage of //each cell float xValue = spriteUV.x; xValue += timeVal; xValue *= cellUVPercentage; spriteUV = float2(xValue, spriteUV.y); half4 c = tex2D (_MainTex, spriteUV); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
float cellUVPercentage = 1.0/_CellAmount;
float timeVal = fmod(_Time.y * _Speed, _CellAmount); timeVal = ceil(timeVal);
float xValue = spriteUV.x; xValue += timeVal; xValue *= cellUVPercentage;第一行首先声明一个新的变量xValue,用于存储用于图片采样的x坐标。它首先被初始为surf函数的输入参数In的横坐标。类型为Input的输入参数In代表输入的texture的UV坐标,范围为0到1。第二行向原值加上小图的整数偏移量,最后为了只显示一张小图,我们还需将x值乘以小图所占百分比cellUVPercentage。
Shader "Custom/AnimateSprites" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} // Create the properties below _CellAmount ("Cell Amount", float) = 0.0 _TimeValue ("Time Value", float) = 0.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; //Create the connection to the properties inside of the //CG program float _CellAmount; float _TimeValue; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { //Lets store our UVs in a seperate variable float2 spriteUV = IN.uv_MainTex; //Lets calculate the width of a singe cell in our //sprite sheet and get a uv percentage that each cel takes up. float cellUVPercentage = 1.0/_CellAmount; //Animate the uv‘s forward by the width precentage of //each cell float xValue = spriteUV.x; xValue += _TimeValue; xValue *= cellUVPercentage; spriteUV = float2(xValue, spriteUV.y); half4 c = tex2D (_MainTex, spriteUV); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
using UnityEngine; using System.Collections; public class SpriteAnimator : MonoBehaviour { public float speed = 5.0f; public int cellAmount = 0; float timeValue = 0.0f; void Start () { transform.renderer.material.SetFloat("_CellAmount", cellAmount); } // Update is called once per frame void FixedUpdate () { timeValue = Mathf.Ceil(Time.time * speed % 9); transform.renderer.material.SetFloat("_TimeValue", timeValue); } }
【Unity Shaders】Using Textures for Effects——让sprite sheets动起来
原文:http://blog.csdn.net/candycat1992/article/details/18662601