你们好,我是秦元培。我參加了CSDN2014博客之星的评选,欢迎你们为我投票,同一时候但愿在新的一年里你们能继续支持个人博客。 dom
你们晚上好。我是秦元培,欢迎你们关注个人博客,个人博客地址是blog.csdn.net/qinyuanpei。终于到了更新博客的时间。从昨天下午開始,博主開始设计一个跑酷的游戏,到晚上睡觉前这个游戏已经基本完毕。ide
博主今天早上七点钟就起来了,到早上十点钟终于把整个游戏写完了。动画
因此,今天的博客的主题就是《Unity3D游戏开发之跑酷游戏项目解说》。this
从博主自身来考虑这件事情。当你选择作本身热爱的事情的时候。你的心里必定是充满激情和勇气的。你愿意看到本身的努力。你愿意看到本身的付出,咱们成长是为了促进自我对认知的不断无缺,因此咱们应该以一种虔诚、谦恭的态度来对待咱们的生命。咱们也许没法选择出身,但咱们可以选择向本身喜欢的生活去努力。spa
也许我和这些人真的不是一个世界的人吧。很是多事情在今天都给出告终局,对于这样的人我已经没有再尝试与之交流的想法了,也许大学四年平平淡淡,留给个人仅仅有本身才干体会的孤独吧。.net
好了。不说个人事情了,咱们正式開始今天的内容吧!设计
1、游戏策划code
游戏採用2D界面,角色从左到右奔跑。在路段中随机生成障碍物和金币,玩家需要使用跳跃功能躲开障碍物。在游戏中玩家收集的金币数目越多,奔跑的距离越长,玩家的得分就越高。orm
咱们终于实现的界面效果如图所看到的,首先咱们来说一下游戏的原理,咱们这里这里採用的方法是路段固定,移动摄像机的方法。换句话说,当角色開始移动后,摄像机和场景尾随角色缓缓向右移动。对象
当角色跑完每一个路段距离的2/3时。计算下一路段的位置,并在该位置生成一个新的路段,这样在游戏场景中可以产生无限远的路段,当某一路段离开摄像机视野时,立刻将其销毁。于此同一时候,咱们在每一个路段上随机产生障碍物和金币。而后对角色作碰撞检測就能够。
2、角色控制
角色控制这里,咱们仅仅关注角色的状态,即角色是处于奔跑状态仍是死亡状态。经过这一状态,咱们针对角色採取不一样的处理方式。假设角色处于奔跑状态,则更新角色位置、摄像机位置、背景位置,不然角色将在被障碍物撞到之后倒地死亡。
咱们来一块儿看如下的脚本:
using UnityEngine; using System.Collections; public class Player : MonoBehaviour { //定义角色移动速度 public float mMoveSpeed=2.5F; //摄像机 private Transform mCamera; //背景图片 private Transform mBackground; //角色是否在奔跑 private bool isRuning=true; //场景中路段总数目 private int mCount=1; //路段预设 public GameObject CubeWay; //死亡动画播放次数 private int DeathCount=0; //收集的金币数目 private int mCoinCount=0; public int CoinCount { get { return mCoinCount; } } //当前奔跑距离 private int mLength=0; public int Length { get { return mLength; } } //当前得分 private int mGrade=0; public int Grade { get { return mGrade; } } void Start () { //获取相机 mCamera=Camera.main.transform; //获取背景 mBackground=GameObject.Find("Background").transform; } void Update () { //假设角色处于奔跑状态则移动角色、相机和场景 if(isRuning) { Move(); CreateCubeWay(); Jump(); UpdateData(); }else { Death(); } } /// <summary> /// 更新玩家的游戏数据 /// </summary> private void UpdateData() { //计算奔跑距离 mLength=(int)((transform.position.x+25)*25); //计算玩家得分 mGrade=(int)(mLength*0.8+mCoinCount*0.2); } ///角色死亡 private void Death() { //为避免死亡动画在每一帧都更新,使用DeathCount限制其运行 if(DeathCount<=1) { //播放死亡动画 transform.animation.Play("Lose"); //次数+1 DeathCount+=1; //保存当前记录 //PlayerPrefs.SetInt("这里填入一个惟一的值",Grade); } } private void Jump() { //这里不能使用刚体结构,因此使用手动方法实现跳跃 if(Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButton(0)) { while(transform.position.y<=1) { float y=transform.position.y+0.02F; transform.position=new Vector3(transform.position.x,y,transform.position.z); transform.animation.Play("Jump"); } StartCoroutine("Wait"); } } IEnumerator Wait() { yield return new WaitForSeconds(0.8F); //角色落地继续奔跑 while(transform.position.y>0.125F) { float y=transform.position.y-0.02F; transform.position=new Vector3(transform.position.x,y,transform.position.z); transform.animation.Play("Run"); } } //移动角色、相机和场景 private void Move() { //让角色从左到右開始奔跑 transform.Translate(Vector3.forward * mMoveSpeed * Time.deltaTime); //移动摄像机 mCamera.Translate(Vector3.right * mMoveSpeed * Time.deltaTime); //移动背景 mBackground.Translate(Vector3.left * mMoveSpeed * Time.deltaTime); } //建立新的路段 private void CreateCubeWay() { //当角色跑完一个路段的的2/3时,建立新的路段 //用角色跑过的总距离计算前面n-1个路段的距离即为在第n个路段上跑过的距离 if(transform.position.x+30-(mCount-1)*50 >=50*2/3) { //克隆路段 //这里从第一个路段的位置開始计算新路段的距离 GameObject mObject=(GameObject)Instantiate(CubeWay,new Vector3(-5F+mCount * 50F,0F,-2F),Quaternion.identity); mObject.transform.localScale=new Vector3(50F,0.25F,1F); //路段数加1 mCount+=1; } } void OnTriggerEnter(Collider mCollider) { //假设碰到的是金币,则金币消失,金币数目加1; if(mCollider.gameObject.tag=="Coin") { Destroy(mCollider.gameObject); mCoinCount+=1; } //假设碰到的是障碍物,则游戏结束 else if(mCollider.gameObject.tag=="Rock") { isRuning=false; } } }在这里咱们需要关注如下的内容:
一、Update()方法及Move()、Jump()、CreateCubeWay()、Death()方法,因为这是角色在奔跑过程当中的核心控制方法。
二、CreateCubeWay()方法的做用是在玩家跑完每一个路段的2/3时,在指定的位置生成新的路段。
假设当前场景中共同拥有n个路段,玩家在每一个路段上奔跑的距离=用玩家从起点到当前位置的长度-前面n-1个路段的距离。经过这样的方法咱们可以推断玩家在每一个路段上的相对位置。在肯定了这个位置后,咱们将其与路段长度的2/3比較,假设大于或者等于这个距离,则生成新的路段。且第n+1个路段的位置等于第一个路段的位置+n个路段的总长度。由此,咱们就实现了在指定的位置生成新的路段,使场景中源源不断的生成新的路段。
三、玩家收集金币和障碍物的碰撞检測都是在OnTrigger方法中实现的,咱们使用了一个bool类型的标识变量isRuning来表示角色的状态,此状态直接影响Update()方法的运行,你们可以从代码中本身去寻找。
四、这里角色的跳跃是经过脚本模拟出来的,因为这里使用刚体彷佛不能实现博主想实现的那种效果,你们可以參考Jump()方法。
3、场景布设
这里咱们2D平面做为游戏的背景。使用NGUI来显示界面文字内容。
在Unity3D场景中使用NGUI需要相机和Anchor设置为同一层级,并设置相机的景深,这样两个相机系统都能工做了。路段CubeWay是一个预设体Cube,负责在CubeWay上生成金币和障碍物。该对象关联在Player脚本上。
玩家角色是一个3D的人物模型。终于场景布设效果如图所看到的:
4、预设定义
在这个游戏中需要重用的对象有路段CubeWay、金币Coin、障碍物Rock,咱们分别来看他们的脚本:
using UnityEngine; using System.Collections; public class CubeWay : MonoBehaviour { //在道路上显示的金币、障碍物 public GameObject[] mObjects; void Start () { //在每段路段上随机产生20到50个物品 int mCount=Random.Range(20,50); for(int i=0;i<mCount;i++) { Instantiate(mObjects[0],new Vector3(Random.Range(this.transform.position.x-25,this.transform.position.x+25),1F,-2F), Quaternion.Euler(new Vector3(90F,180F,0F))); } //在每段路段上随机产生5到10个障碍物 mCount=Random.Range(5,10); for(int i=0;i<mCount;i++) { Instantiate(mObjects[1],new Vector3(Random.Range(this.transform.position.x-25,this.transform.position.x+25),0.5F,-2F), Quaternion.Euler(new Vector3(90F,180F,0F))); } } //当离开摄像机视野时立刻销毁 void OnBecameInvisible() { Destroy(this.gameObject); } }
using UnityEngine; using System.Collections; public class Coin : MonoBehaviour { //这里是一个控制金币旋转的脚本 void Update () { transform.Rotate(Vector3.forward * 50F * Time.deltaTime); } //当离开摄像机视野时立刻销毁 void OnBecameInvisible() { Destroy(this.gameObject); } }
using UnityEngine; using System.Collections; public class Rock : MonoBehaviour { //当离开摄像机视野时立刻销毁 void OnBecameInvisible() { Destroy(this.gameObject); } }
这里Rock、Coin将绑定到CubeWay的mObjects。
五、游戏管理
最后是界面的数据更新啦,脚本定义例如如下:
using UnityEngine; using System.Collections; public class GameManager : MonoBehaviour { //游戏界面根节点 private Transform GameUI; //玩家 private Transform mPlayer; //界面金币数及距离 private Transform mCoins; private Transform mLength; void Start () { GameUI=GameObject.Find("2DUI").transform; mPlayer=GameObject.Find("People").transform; mCoins=GameUI.FindChild("Anchor/Panel/Coins").transform; mLength=GameUI.FindChild("Anchor/Panel/Length").transform; } void Update () { mCoins.GetComponent<UILabel>().text="金币:" + mPlayer.GetComponent<Player>().CoinCount; mLength.GetComponent<UILabel>().text="距离:" + mPlayer.GetComponent<Player>().Length; } }
但愿今天的内容你们可以喜欢,但愿你们继续支持和关注个人博客,假设咱们对今天的样例稍做改动,就可以实现3D版的跑酷,经典的《神庙逃亡》游戏就是基于Unity3D游戏引擎开发的。
每日箴言:要有美好的但愿,并尽心尽力去追求;要有远大的梦想,并尽心尽力去实现。
喜欢个人博客请记住个人名字:秦元培,个人博客地址是blog.csdn.net/qinyuanpei
转载请注明出处,本文做者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/25510579