跑酷游戏 unity设计思路

2015年01月21日 09:40 0 点赞 0 评论 更新于 2025-11-21 14:39

只要深入学习 Unity,跑酷游戏的设计思路并不难理解。整个设计过程可分为五步:第一步,游戏策划;第二步,角色控制;第三步,场景布设;第四步,预设定义;第五步,游戏管理。下面我们来详细了解具体过程。

一、游戏策划

游戏采用 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,负责在其上生成金币和障碍物,该对象关联在 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 是一个 CubeCoin 是一个圆柱体,为了让金币看起来更美观,让其在空中旋转;Rock 是一个平面贴图。RockCoin 将绑定到 CubeWaymObjects 数组中。

五、游戏管理

最后是界面的数据更新,脚本定义如下:

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 游戏引擎开发的。希望大家喜欢今天的内容,继续支持和关注我的博客。

作者信息

feifeila

feifeila

共发布了 3994 篇文章