Unity3D游戏开发之使用Unity3D开发2D游戏 (一)

        今天要和你们分享的是基于Unity3D开发2D游戏,博主一直钟爱于国产武侠RPG,这个我在开始写Unity3D游戏开发系列文章的时候就已经说过了,因此咱们今天要作的就是利用Unity3D来实如今2D游戏中人物的走动控制。下面就请你们跟随个人一块儿来见证Unity3D强大的魅力吧。首先咱们建立一个项目,建立新场景,咱们首先建立一个Plane并将其命名为MainMap,而后咱们在项目中添加一个Resources文件夹,将事先准备好的地图文件Map0复制到这个目录下,而后咱们将这个图片拖拽到MainMap上,咱们将MainMap的旋转参数Rotatiion设置为90,180,0,使其与摄像机垂直,而后将摄像机的Projection投影属性设置为 orthographic正交模式,这时咱们就可以在屏幕中看到经典的余杭镇场景了。若是咱们须要对场景进行进一步的优化的话,能够经过调整摄像机的投影面积大小和距离来实现。参数设置能够参考这里:数组



       接下来,咱们再次建立一个Plane将其命名为Player,这就是咱们今天要出场的角色李逍遥啦,和准备地图相似,咱们将李逍遥的贴图直接拖拽到Player上。刚开始角色会比较大,和画面不协调,咱们能够经过调整Scale参数来缩放咱们的角色,调整到合适的范围。这里咱们直接使用了一张完整的地图,在实际的游戏开发中,一个场景地图多是由不少瓦片构成的,所谓瓦片,就是指被分割成若干个能够拼接起来的图片。咱们知道,仙剑奇侠传做为一款经典的单机游戏,除了剧情之外,就是那些经典、动听的音乐啦,在Unity3D中实现音乐播放是很简单的事情,咱们选定MainMap,为主场景添加一个AudioSource组件,并将背景音乐拖拽到AudioSource的AudioClip属性框中,选中Loop使其循环,接下来咱们点击运行,运行效果以下图:oop


       接下类,就是今天的重头戏啦,咱们今天的主要任务是经过Unity3D的2D帧动画绘制来实现人物的动画和控制,因此接下来咱们在项目目录下增长一个Script文件下,新建一个叫作Person的脚本,该脚本封装了咱们对人物角色的控制和帧动画的绘制方法。首先咱们来准备一组素材:学习





           从名称的命名上,咱们就能够看出这是角色在上下左右四个方向上的连续动画图片。下面,咱们在Resources目录下建立下面的目录结构,并将上面的图片分别放在对应的文件夹下,咱们在脚本中会引用下面的资源:优化


         下面开始编写脚本:动画

 

using UnityEngine;
using System.Collections;

public class Person : MonoBehaviour {
	//定义角色对象
	private GameObject mHero;
	//定义人物向上动画数组
	private Object[] UpAnim;
	//定义人物向下动画数组
	private Object[] DownAnim;
	//定义人物向左动画数组
	private Object[] LeftAnim;
	//定义人物向右动画数组
	private Object[] RightAnim;
	//当前帧索引
	private int mFrameIndex;
	//当前时间
	private float mTotalTime;
	//定义每秒帧数为10
	private float mFPS=10;
	//定义当前人物动画
	private Object[] NowAnim;
	private Object[] LastAnim;
	//定义角色行动速度
	private float mSpeed=5;
	//角色当前状态
	private PersonState mState=PersonState.Stand;
	
	//定义角色状态枚举
	private enum PersonState
	{
	   Stand,
	   Walk
	}
	
	void OnGUI()
	{
	   GUI.Label(new Rect(10,10,180,40),"李逍遥位置:"+mHero.transform.position.ToString());
	}
	
	void Start () 
	{
	   //获取人物
	   mHero=GameObject.Find("Player");
	   //获取动画数组
	   UpAnim=Resources.LoadAll("UpAnim");
	   DownAnim=Resources.LoadAll("DownAnim");
	   LeftAnim=Resources.LoadAll("LeftAnim");
	   RightAnim=Resources.LoadAll("RightAnim");
	   //定义默认动画
	   NowAnim=UpAnim;
	   LastAnim=NowAnim;
	}
	
	void FixedUpdate()
	{
	   //向左
	   if(Input.GetKey(KeyCode.A))
	   {
	      SetAnimation(LeftAnim);
	      this.mState=PersonState.Walk;
	      mHero.transform.Translate(Vector3.right*Time.deltaTime*mSpeed);
	   }
	   //向右
	   if(Input.GetKey(KeyCode.D))
	   {
	      SetAnimation(RightAnim);
	      this.mState=PersonState.Walk;
	      mHero.transform.Translate(Vector3.right*Time.deltaTime*(-mSpeed));
	   }
	   //向上
	   if(Input.GetKey(KeyCode.W))
	   {
	      SetAnimation(UpAnim);
	      this.mState=PersonState.Walk;
	      mHero.transform.Translate(Vector3.forward*Time.deltaTime*(-mSpeed));
	   }
	   //向下
	   if(Input.GetKey(KeyCode.S))
	   {
	      SetAnimation(DownAnim);
	      this.mState=PersonState.Walk;
	      mHero.transform.Translate(Vector3.forward*Time.deltaTime*mSpeed);
	      Vector3 mHeroPos=mHero.transform.position;
	   }
	   DrawTexture(NowAnim);
	}
	
	void Update () 
	{
	   //松开键位时
	   if(Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D) 
	   || Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.W))
	   {
	      this.mState=PersonState.Stand;
	   }
	}
	
	void DrawTexture(Object[] mAnim)
	{
	   //若是角色当前状态为站立,则显示帧动画中的第一帧
	   if(mState==PersonState.Stand)
	   {
	     mHero.renderer.material.mainTexture=(Texture)mAnim[0];
	   }
	   //不然绘制帧动画
	   else
	   {
	      mTotalTime+=Time.deltaTime;
	      if(mTotalTime>=1.0/mFPS)
	      {
	         mFrameIndex++;
	         mTotalTime=0;
	         if(mFrameIndex>=mAnim.Length)
	         {
	           mFrameIndex=0;
	         }
	      }
	        mHero.renderer.material.mainTexture=(Texture)mAnim[mFrameIndex];
	   }
	}
	
	void SetAnimation(Object[] mAnim)
	{
	   NowAnim=mAnim;
	   if(!LastAnim.Equals(NowAnim))
	   {
	      this.mFrameIndex=0;
	      LastAnim=NowAnim;
	   }
	}
}

         在上面的这部分脚本中,咱们在Start()方法中加载了咱们预先设定好的资源,而后在FixedUpdate()方法判断用户行为,并根据用户按下的键来肯定要绘制的帧动画,咱们假定每秒的帧数为10,则每帧显示的时间为0.1秒,若是从上一次刷新到如今的时间超过或者等于这个时间,则表示咱们须要更新帧画面了。而当帧画面的索引和该帧动画数组内元素个数相等的时候,则意味着开始循环绘制这组帧动画。咱们在上面定义了一我的物状态的枚举类型,这里只是简单的定义了两种类型,即Stand和Walk类型,当用户按下控制键时此类型的值为Walk,当用户松开控制键时此类型的值为Stand,和上一篇文章不一样,这里调用的是 FixedUpdate()方法,而不是Update()方法,缘由是Update()f方法更新的时间咱们没法控制,而FixedUpdate()方法的时间则能够经过Edit->Project Setting->time->Fixed Timestep来指定,具体的你们能够本身阅读代码,这里就很少说了,剩下的事情就是把脚本绑定到Player上,咱们运行一下:this



         就目前这个解决方案而言,存在如下几个问题:code

         一、人物范围控制,换句话说就是如何保证人物不会从这些房屋、篱笆上直接穿过去orm

         二、人物向下移动时,会钻到地底下对象

         三、摄像机如何跟随人物实现平移blog

         四、小地图的实现

          五、场景地图范围控制

          针对以上问题,伴随着博主学习Unity3D的深刻,咱们将在后面的文章中一一为你们解决,请你们关注个人博客,谢谢!