Unity3D游戏开发跑酷游戏项目实例

一、游戏策划

游戏采用2D界面,角色从左到右奔跑,在路段中随机生成障碍物和金币,玩家需要使用跳跃功能躲开障碍物,在游戏中玩家收集的金币数目越多,奔跑的距离越长,玩家的得分就越高。我们最终实现的界面效果如图所示,首先我们来讲一下游戏的原理,我们这里这里采用的方法是路段固定,移动摄像机的方法。换句话说,当角色开始移动后,摄像机和场景跟随角色缓缓向右移动。当角色跑完每一个路段距离的2/3时,计算下一路段的位置,并在该位置生成一个新的路段,这样在游戏场景中可以产生无限远的路段,当某一路段离开摄像机视野时,立即将其销毁。于此同时,我们在每一个路段上随机产生障碍物和金币,然后对角色做碰撞检测即可。

 二、角色控制

角色控制这里,我们只关注角色的状态,即角色是处于奔跑状态还是死亡状态。通过这一状态,我们针对角色采取不同的处理方式。如果角色处于奔跑状态,则更新角色位置、摄像机位置、背景位置,否则角色将在被障碍物撞到以后倒地死亡。我们来一起看下面的脚本:

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; 
 } 
 } 
}

在这里我们需要关注下面的内容:

1、Update()方法及Move()、Jump()、CreateCubeWay()、Death()方法,因为这是角色在奔跑过程中的核心控制方法。

2、CreateCubeWay()方法的作用是在玩家跑完每一个路段的2/3时,在指定的位置生成新的路段。假设当前场景中共有n个路段,玩家在每一个路段上奔跑的距离=用玩家从起点到当前位置的长度-前面n-1个路段的距离。通过这种方法我们可以判断玩家在每一个路段上的相对位置。在确定了这个位置后,我们将其与路段长度的2/3比较,如果大于或者等于这个距离,则生成新的路段,且第n+1个路段的位置等于第一个路段的位置+n个路段的总长度。由此,我们就实现了在指定的位置生成新的路段,使场景中源源不断的生成新的路段。

3、玩家收集金币和障碍物的碰撞检测都是在OnTrigger方法中实现的,我们使用了一个bool类型的标识变量isRuning来表示角色的状态,此状态直接影响Update()方法的执行,大家可以从代码中自己去寻找。

4、这里角色的跳跃是通过脚本模拟出来的,因为这里使用刚体似乎不能实现如果想实现的那种效果,大家可以参考Jump()方法。

三、场景布设

这里我们2D平面作为游戏的背景,使用NGUI来显示界面文字内容。在Unity3D场景中使用NGUI需要相机和Anchor设置为同一层级,并设置相机的景深,这样两个相机系统都能工作了。路段CubeWay是一个预设体Cube,负责在CubeWay上生成金币和障碍物,该对象关联在Player脚本上。玩家角色是一个3D的人物模型,最终场景布设效果如图所示:

四、预设定义

在这个游戏中需要重用的对象有路段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); 
 } 
}

其中CubeWay就是一个Cube、Coin是一个圆柱体,为了让金币看起来好看点,我们让金币在空中旋转起来、Rock就是一个平面贴图。这里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; 
 } 
}

好了,到现在整个游戏已经讲解完了。

未经允许不得转载:第一Unity3D » Unity3D游戏开发跑酷游戏项目实例

赞 (1)