Unity3D 游戏技术开发之Native2D特性研究


欢迎来到unity学习unity培训unity企业培训教育专区,这里有很多U3D资源U3D培训视频U3D教程U3D常见问题U3D项目源码,我们致力于打造业内unity3d培训、学习第一品牌。

 

一、精灵(Sprite)与精灵图集 

虽然我们将Unity3D的2D特性成为Native2D,不过事实上Natvite只是相对于第三方插件而言的,从本质上Unity3D的2D仍然是属于 3D的范畴。精灵(Sprite)是我们走进Native2D的第一个组件,所以的2D特性都是以这个组件作为基础。学习过2D游戏开发的朋友应该知道精 灵其实就是我们在2D世界里一张贴图。好了,下面我们创建一个新的项目来演示如何使用Sprite组件吧!第一个让我们激动人心的特性是我们可以在创建项 目的时候就决定一个项目是3D游戏还是2D游戏,如图,这里我们直接选择2D,因为我们今天要探索的是Unity3D的Native2D特性文章出处【狗刨学习网】。

 

 

 

进入Unity后我们将注意到Unity的工具栏上会出现一个2D/3D的选项按钮且在当前场景中2D按钮被激活,这意味着这是一个2D项目,通过切换 该按钮我们可以发现,Unity3D的Native2D就是将Unity3D的Z轴固定以后的效果,所以从本质上来讲Unity3D的Native2D还 是3D引擎在2D效果下的一种实现。 

 

 

我们注意到Sprite组件中有一个最重要的SpriteRenderer组件,该组件负责的是对Sprite的渲染,我们可以通过指定Sprite这个属性来指定的渲染的资源。我们选择其中的一个图片资源,可以看到其属性窗口: 

 

 

其中TextureType用来指明贴图的类型,这里我们选择Sprite类型,因为只有这种类型的贴图才能提供给Sprite组件来使用。 SpriteMod用来指定精灵是一张单个的图还是一系列图集,我们注意到这张图片是一个帧动画序列,所以我们应该选择Multiple类型。接下来,我 们单击SpriteEditor按钮打开精灵编辑器,目的是将这些精灵图集分割成单个的图片。如果大家阅读过博主刚开始学习Unity3D时写过的文章, 一定记得博主曾经用PhotoShop将一张帧动画序列图用切图的方式分割出来,再通过绘制贴图的方式来实现帧动画吧。这样是不是很麻烦啊?没关 系,Unity3D的Nativie2D提供的精灵编辑器可以帮你快速地完成这一工作。文章出处:狗刨学习网。我们打开精灵编辑器: 

 

 

大家可以看到这里博主将这张图片分割成了16个图片。这里有一个技巧是可以通过Trim按钮获得大小一致的图块,因为精灵编辑器可以帮助你判断图形的边 界。这样做的好处是Unity可以帮你生成16张个帧动画序列,从而你可以任意地调用某一帧动画,然而资源管理器中并不会生成相应的文件,这样可以节省项 目资源的大小。文章出处:狗刨学习网。如图: 

 

 

好了,接下来,我们来编写脚本来展示如何使用这组精灵动画: 

 

1. using UnityEngine;   

2. using System.Collections;   

3.    

4. public class SpriteScript : MonoBehaviour {   

5.    

6.     //向上的精灵集合   

7.     public Sprite[] UpSprites;   

8.     //向下的精灵集合   

9.     public Sprite[] DownSprites;   

10.     //向左的精灵集合   

11.     public Sprite[] LeftSprites;   

12.     //向右的精灵集合   

13.     public Sprite[] RightSprites;   

14.    

15.     //上一次使用的精灵集合   

16.     private Sprite[] lastSprites;   

17.     //当前使用的精灵集合   

18.     private Sprite[] currentSprites;   

19.    

20.     //当前帧序列索引   

21.     private int index=0;   

22.     //每秒帧数   

23.     private float fps=10;   

24.     //当前经历时间   

25.     private float currentTime=0;   

26.    

27.     //角色当前状态   

28.     private PlayerState state;   

29.    

30.     //精灵渲染器   

31.     private SpriteRenderer renderer=null;   

32.    

33.     void Start ()    

34.     {   

35.         //初始化角色状态   

36.         state=PlayerState.Idle;   

37.         //初始化角色精灵集合   

38.         currentSprites=UpSprites;   

39.         lastSprites=currentSprites;   

40.         //获取精灵渲染器   

41.         renderer=GetComponent<SpriteRenderer>();   

42.     }   

43.        

44.    

45.     void FixedUpdate ()    

46.     {   

47.         if(Input.GetAxis("Horizontal")==1){   

48.             state=PlayerState.Walk;   

49.             SetSprites(RightSprites);   

50.             MoveTo(new Vector2(Time.deltaTime * 2.5F,0));   

51.         }else if(Input.GetAxis("Horizontal")==-1){   

52.             state=PlayerState.Walk;   

53.             SetSprites(LeftSprites);   

54.             MoveTo(new Vector2(-Time.deltaTime * 2.5F,0));   

55.         }else if(Input.GetAxis("Vertical")==1){   

56.             state=PlayerState.Walk;   

57.             SetSprites(UpSprites);   

58.             MoveTo(new Vector2(0,Time.deltaTime * 2.5F));   

59.         }else if(Input.GetAxis("Vertical")==-1){   

60.             state=PlayerState.Walk;   

61.             SetSprites(DownSprites);   

62.             MoveTo(new Vector2(0,-Time.deltaTime * 2.5F));   

63.         }else if(!Input.anyKey){   

64.             state=PlayerState.Idle;   

65.         }   

66.         DrawSprites(currentSprites);   

67.     }   

68.    

69.     //角色移动   

70.     private void MoveTo(Vector2 offest)   

71.     {   

72.        //根据偏移量计算角色位置   

73.        float x=transform.position.x + offest.x;   

74.        float y=transform.position.y + offest.y;   

75.        //使用2D刚体组件来移动精灵   

76.        this.rigidbody2D.MovePosition(new Vector2(x,y));   

77.     }   

78.    

79.     //设置当前精灵集合   

80.     private void SetSprites(Sprite[] sprites)   

81.     {   

82.         currentSprites=sprites;   

83.         //如果当前精灵集合和上一次使用的精灵集合不等则表明要切换精灵集合   

84.         if(currentSprites!=lastSprites)   

85.         {   

86.            lastSprites=currentSprites;   

87.            index=0;   

88.         }   

89.     }   

90.    

91.     //绘制当前精灵集合   

92.     private void DrawSprites(Sprite[] sprites)   

93.     {   

94.       //如果角色处于站立状态则显示第一帧   

95.       if(state==PlayerState.Idle){   

96.          renderer.sprite=sprites[0];   

97.       }else{   

98.          currentTime+=Time.deltaTime;   

99.          //如果当前时间大于帧动画渲染时间则需要渲染新的帧动画   

100.          if(currentTime>1/fps){   

101.             //使索引增加并将当前时间清零以便于重新计数   

102.             index+=1;   

103.             currentTime=0;   

104.             //使索引连续画面循环   

105.             if(index>=sprites.Length){   

106.                index=0;   

107.             }   

108.          }   

109.       }   

110.       //渲染   

111.       renderer.sprite=sprites[index];   

112.     }   

113.       

114.     #region 角色状态枚举定义#   

115.     enum PlayerState   

116.     {   

117.         Walk,   

118.         Idle   

119.     }   

120.     #endregion   

121. }   

那么,我们来看看实际的运行效果吧: 

 

这是一个控制人物沿着上、下、左、右四个方向进行移动的动画效果,我们很容易就实现了。不过,我们代码似乎写了不少啊,那么有没有一种更好的方法呢? 在Unity3D没有推出2D组件的时候,我们可以以贴图的形式来绘制一个Sprite,对于这种帧动画序列图片,我们可以通过offset来决定贴图上 要显示的位置。不过这种方法似乎只对普通的贴图管用,对于Sprite无能为力。博主个人还是喜欢使用这种方式,毕竟有了精灵编辑器后,切图就是一件很简 单的事情了。下面,我们再来给出一个通用的脚本,该脚本可以实现任何连续帧动画的循环播放,适合在游戏中表现相对玩家来说静止的效果,比如在游戏中飘扬的 旗子、飞来飞去的小鸟等等: 

 

1. using UnityEngine;   

2. using System.Collections;   

3.    

4. public class FightScript: MonoBehaviour {   

5.    

6.     //序列帧动画集合   

7.     public Sprite[] Animations;   

8.     //当前帧序列索引   

9.     private int index=0;   

10.     //每秒帧数   

11.     public float fps=10;   

12.     //当前经历时间   

13.     private float currentTime=0;   

14.     //精灵渲染器   

15.     private SpriteRenderer renderer;   

16.    

17.     void Start()   

18.     {   

19.         //获取精灵渲染器   

20.         renderer=GetComponent<SpriteRenderer>();   

21.     }   

22.    

23.     void FixedUpdate ()    

24.     {   

25.         DrawSprite();   

26.     }   

27.    

28.     //提供一个外部接口以便于随时改变动画   

29.     public void SetAnimations(Sprite[] sprites,int index)   

30.     {   

31.         this.Animations=sprites;   

32.         this.index=index;   

33.     }   

34.    

35.     //根据精灵集合播放动画   

36.     void DrawSprite()   

37.     {   

38.         currentTime+=Time.deltaTime;   

39.         //如果当前时间大于帧动画渲染时间则需要渲染新的帧动画   

40.         if(currentTime>1/fps){   

41.             //使索引增加并将当前时间清零以便于重新计数   

42.             index+=1;   

43.             currentTime=0;   

44.             //使索引连续画面循环   

45.             if(index>=Animations.Length){   

46.                 index=0;   

47.             }   

48.         }   

49.        //渲染   

50.        renderer.sprite=Animations[index];   

51.     }   

52. }   

 

这个脚本的特点是只要指定了一系列帧动画序列,就可以让动画从某一帧开始循环播放动画。下面,我们添加两个带有攻击效果的Sprite: 

 

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页