Unity3D之简单的帧动画

算是第一篇非转载的文章了~

在这里推荐个Unity3d很多功能效果的脚本集合的网站,也是部门老大发现给我的~

http://wiki.unity3d.com/index.php?title=Scripts/General


本人也是个初级的开发者,这里只是作为一个学习的总结,如果哪里的理解错了,欢迎纠正。


帧动画的实现可以用第三方的插件,类似2DToolkit,可以很容易的实现帧动画,但有时还是不要太过于依赖第三方的插件。有时间还是得自己研究如何实现,不能一直穿着别人的内裤啊~



这个是本次项目的最终效果图:



关于在Unity3d下如何用代码生成面,这里雨松MOMO已经有相关的博文:

http://www.xuanyusong.com/archives/780


理解下一张Material的坐标系,这里用了网上找的一张图片:

每个Material都有自己的这个坐标系。

而如果需要把一张纹理贴到一个面上,则需要把贴图上的UV坐标(UV坐标就是上面的坐标系)对应到面的每个顶点上,如图(又是网上的图片):

比如有下面一张图片:


图片总宽高为:192x152,单张精灵的宽高为48x38;

如果我们只想显示左上角的1张图片,代码如下

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class ViewImage : MonoBehaviour {  
  5.       
  6.       
  7.     public int widthCount , heightCount;  
  8.       
  9.     //图片的宽高比例//  
  10.     public float width = 48,height = 38;  
  11.       
  12.     //素材贴图//  
  13.     public Material material;  
  14.       
  15.     //顶点数//  
  16.     private int verticesCount = 4;  
  17.       
  18.       
  19.     private Vector2 size;  
  20.       
  21.     private Mesh mesh;  
  22.       
  23.     public int frameIndex = 0;  
  24.       
  25.     private MeshRenderer meshRenderer;  
  26.   
  27.     // Use this for initialization  
  28.     void Start () {  
  29.         initFace();  
  30.     }  
  31.     /// <summary>  
  32.     /// 初始化一个面  
  33.     /// </summary>  
  34.     private void initFace(){  
  35.         //得到MeshFilter对象//  
  36.         MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();  
  37.         if(meshFilter == null){  
  38.             //为null时,自动添加//  
  39.             meshFilter = gameObject.AddComponent<MeshFilter>();  
  40.             meshRenderer = gameObject.AddComponent<MeshRenderer>();  
  41.             meshRenderer.sharedMaterial = material;  
  42.         }  
  43.         //得到对应的网格对象//  
  44.         mesh = meshFilter.mesh;  
  45.           
  46.         //三角形顶点的坐标数组//  
  47.         Vector3[] vertices = new Vector3[verticesCount];  
  48.   
  49.         //得到三角形的数量//  
  50.         int trianglesCount = verticesCount - 2;  
  51.   
  52.         //三角形顶点数组//  
  53.         int[] triangles   = new int[verticesCount *3];    
  54.           
  55.         float tmpWidth = 1.0f;  
  56.         float tmpHeight = 1.0f ;  
  57.           
  58.         vertices[0] = new Vector3(0,0,0);  
  59.         vertices[1] = new Vector3(0,tmpHeight,0);  
  60.         vertices[2] = new Vector3(tmpWidth,0,0);  
  61.         vertices[3] = new Vector3(tmpWidth,tmpHeight,0);          
  62.           
  63.         mesh.vertices = vertices;  
  64.           
  65.         /* 
  66.          *  
  67.          * 如果下面的顶点连线看不明白,看这里 
  68.         triangles[0] = 0; 
  69.         triangles[1] = 1; 
  70.         triangles[2] = 2; 
  71.         triangles[3] = 1; 
  72.         triangles[4] = 3; 
  73.         triangles[5] = 2; 
  74.         */  
  75.           
  76.         //起始三角形顶点//  
  77.         int start = 0;  
  78.   
  79.         //结束三角形的顶点//  
  80.         int end = 2;  
  81.   
  82.         for(int i = start; i <end; i++)  
  83.         {  
  84.             for(int j = 0; j < 3; j++)  
  85.             {  
  86.                 if( i%2 ==0)  
  87.                 {  
  88.                     triangles[3*i + j] = i +j;  
  89.                 }else  
  90.                 {  
  91.                     triangles[3*i + j] = i + 2-j;  
  92.                 }  
  93.             }  
  94.         }  
  95.           
  96.           
  97.   
  98.         mesh.triangles = triangles;       
  99.           
  100.         Vector3 localScale = new Vector3(width,height,1.0f);  
  101.         transform.localScale = localScale;  
  102.         size =  new Vector2 (1.0f / widthCount , 1.0f / heightCount);  
  103.         setUVPosition(frameIndex,mesh);  
  104.           
  105.     }  
  106.       
  107.       
  108.       
  109.     //设置uv坐标  
  110.     private void setUVPosition(int index,Mesh mesh){  
  111.               
  112.         //得到相对于图片的行列坐标//  
  113.         int uIndex = index % widthCount;    //列坐标//  
  114.         int vIndex = index / heightCount;   //行坐标//  
  115.           
  116.         //左下角的坐标点;//  
  117.         Vector2 vertices0 =  new Vector2 (uIndex * size.x, 1.0f - size.y - vIndex * size.y);  
  118.         //左上角坐标//  
  119.         Vector2 vertices1 = new Vector2(vertices0.x , vertices0.y + size.y);  
  120.         //右下角坐标//  
  121.         Vector2 vertices2 = new Vector2(vertices0.x + size.x , vertices0.y );  
  122.         //右上角坐标//  
  123.         Vector2 vertices3 = new Vector2(vertices0.x + size.x , vertices0.y + size.y);  
  124.           
  125.         mesh.uv = new Vector2[]{vertices0 , vertices1 , vertices2 , vertices3};  
  126.           
  127.   
  128.     }  
  129. }  

代码上面都有注释,这里关于用图片的素材球的Shader说明下,一开始我用Transparent/Diffuse,但是在运行时,切换uv坐标时控制台打印了Shader wants normals, but the mesh  doesn't have them 这个消息。Google下也不知道为什么,最后用Unlit/Transparent就没有打印了,所以哪位大神知道原因告诉我下~~


继续,现在已经可以从一张大贴图中显示其中的一张图片了,接下来整理成动画就是把这些帧图片整合在一起,在Update里头切换就KO了,代码如下:

[csharp]  view plain copy
  1. //控制动画帧数//  
  2. public int[] aniArray;    
  3. void Update(){  
  4.     if(Time.frameCount % 8 == 0){  
  5.         int len = aniArray.Length;  
  6.           
  7.           
  8.         int curIndex = aniArray[frameIndex];  
  9.           
  10.         setUVPosition(curIndex,mesh);  
  11.           
  12.         frameIndex ++;  
  13.           
  14.         frameIndex %= len;  
  15.           
  16.     }  
  17.       
  18.       
  19. }  

下面是项目的一张截图,用红线圈起来的部分是动画帧的下标数组。

WidgetCount:大贴图x方向上有多少张图片。

HeightCount:大贴图y方向上有多少张图片。

Width:分隔的小贴图的宽度。

Height:f分隔的小贴图的高度。

FrameIndex:当前播放到第几帧的下标。

Ani Array:帧动画的下标集合数组。



O了,这篇其实好早就在写,但一直没去完成..今天光棍就顺便完成掉~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值