今天要和你们分享的是基于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的深刻,咱们将在后面的文章中一一为你们解决,请你们关注个人博客,谢谢!