AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > Unity3D

【Unity C#编程】跑动游戏(5):游戏结束等

51自学网 2014-05-24 http://www.51zixue.net

游戏结束

在GUI管理器中给游戏结束添加一个操控。和游戏开始事件的过程差不多,但是在这个情况下我们得再次启用管理器,还有说明和游戏结束文本。

1
2
3
4
5
6
7
8
9
10
11
void Start () {
GameEventManager.GameStart += GameStart;
GameEventManager.GameOver += GameOver;
gameOverText.enabled = false;
}
 
private void GameOver () {
gameOverText.enabled = true;
instructionsText.enabled = true;
enabled = true;
}

一旦Runner从平台掉落,就触发游戏结束事件。只要给Runner添加Game Over Y字段,值为-6,然后检查每个更新看看是否低于-6。如果这样,就触发游戏结束事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
public float gameOverY;
 
void Update () {
if(touchingPlatform && Input.GetButtonDown("Jump")){
rigidbody.AddForce(jumpVelocity, ForceMode.VelocityChange);
touchingPlatform = false;
}
distanceTraveled = transform.localPosition.x;
 
if(transform.localPosition.y < gameOverY){
GameEventManager.TriggerGameOver();
}
}

游戏结束阈值

使用事件

现在已经能够正确的触发游戏事件了, 现在 Runner 该使用这些事件了。

在第一个游戏开始之前,Runner应该是被禁用的,尽管我们想让它里面的相机保持活跃。禁用Runner意味着要禁用它的渲染器以及其自身的runner组件。还要把它的刚体切换为运动模式,冻结在适当的位置。可以通过Start方法做到这一点,然后在游戏开始事件触发时撤销此更改。记住起始位置,这样每次游戏开始时都可以重置它。还要重新设定distanceTraveled,这样它就能立刻更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private Vector3 startPosition;
 
void Start () {
GameEventManager.GameStart += GameStart;
GameEventManager.GameOver += GameOver;
startPosition = transform.localPosition;
renderer.enabled = false;
rigidbody.isKinematic = true;
enabled = false;
}
 
private void GameStart () {
distanceTraveled = 0f;
transform.localPosition = startPosition;
renderer.enabled = true;
rigidbody.isKinematic = false;
enabled = true;
}
 
private void GameOver () {
renderer.enabled = false;
rigidbody.isKinematic = true;
enabled = false;
}

现在Runner能够正确回应游戏事件,但是一旦第一个平台被回收之后,游戏就会迅速结束,因为Runner会立刻掉落。所以要修改一下平台管理器,让它也回应游戏事件。只有在游戏进程中启用,并且平台要在第一个游戏开始事件被触发后变得可见。

为了达到这一点,可以把PlatformManager初始位置放在相机后方较远的地方,重新定位循环回路为一个新的GameStart方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Start () {
GameEventManager.GameStart += GameStart;
GameEventManager.GameOver += GameOver;
objectQueue = new Queue<Transform>(numberOfObjects);
for (int i = 0; i < numberOfObjects; i++) {
objectQueue.Enqueue((Transform)Instantiate(
prefab, new Vector3(0f, 0f, -100f), Quaternion.identity));
}
enabled = false;
}
 
private void GameStart () {
nextPosition = startPosition;
for(int i = 0; i < numberOfObjects; i++){
Recycle();
}
enabled = true;
}
 
private void GameOver () {
enabled = false;
}

接下来用同样的方法处理SkylineManager, 这样游戏的各个方面就能够良好地回应游戏事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Start () {
GameEventManager.GameStart += GameStart;
GameEventManager.GameOver += GameOver;
objectQueue = new Queue<Transform>(numberOfObjects);
for(int i = 0; i < numberOfObjects; i++){
objectQueue.Enqueue((Transform)Instantiate(
prefab, new Vector3(0f, 0f, -100f), Quaternion.identity));
}
enabled = false;
}
 
private void GameStart () {
nextPosition = startPosition;
for(int i = 0; i < numberOfObjects; i++){
Recycle();
}
enabled = true;
}
 
private void GameOver () {
enabled = false;
}
game startgame over

Game start 和 game over

能量提升

让我们来包含一个能量提升,这样就能实现半空中的助力。做一个旋转的立方体,随机出现在平台上面。任何时候,屏幕中至多有一个能量块,这样有一个实例就够了,可以重复使用它。

创建新的文件夹,命名为Booster。在它里面创建一个新的材料,命名为Booster Mat。给材料使用Specular shader,用绿色(0, 255, 0),以及一个白色高光。

再创建一个新的cube,命名为Booster,把scale设置为0.5,把它变小一点。为了更容易撞击到它,把它的对撞增大到1.5,这样就能形成0.75的面积范围。然后给它指定材质。

把对撞机标记为触发器,通过检查它的Is Trigger字段。我们这样做是因为想让Runner正确的通过它,而不是撞到它。

Booster cube(能量块)

在相应的文件夹中创建一个新的C#脚本,命名Booster,将其指定到Booster对象,给它四个公共变量来配置它。

需要在平台中心偏移位置放置能量块,设置offset为(0, 2.5, 0)

设置一个旋转速度使其旋转,把rotation velocity设置为(45, 90, 1)。

还需要一个旋转偏移,只是作为一个平台,免得Runner错过能量提升。把recycle offset设置为20.

设置重生机会(spawn chance),这样能量块能在不可预知的地方出现,每个平台25%即可。

1
2
3
4
5
6
7
using UnityEngine;
 
public class Booster : MonoBehaviour {
 
public Vector3 offset, rotationVelocity;
public float recycleOffset, spawnChance;
}

Booster 配置

生成工作的另一种实现方法是每当平台回收的时候请求能量块安置。然后就看能量块自身是否安置它自己了。给Booster添加SpawnIfAvailable方法来实现。它需要一个平台位置,这样就能知道在哪里放置能量块。先把它设为空。

1
2
public void SpawnIfAvailable(Vector3 position){
}

然后给PlatformManager添加变量,指定Booster。在Recycle方法里,决定新平台的位置之后可以调用PlaceIfAvailable方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public Booster booster;
 
private void Recycle () {
Vector3 scale = new Vector3(
Random.Range(minSize.x, maxSize.x),
Random.Range(minSize.y, maxSize.y),
Random.Range(minSize.z, maxSize.z));
 
Vector3 position = nextPosition;
position.x += scale.x * 0.5f;
position.y += scale.y * 0.5f;
booster.SpawnIfAvailable(position);
 
Transform o = objectQueue.Dequeue();
o.localScale = scale;
o.localPosition = position;
int materialIndex = Random.Range(0, materials.Length);
o.renderer.material = materials[materialIndex];
o.collider.material = physicMaterials[materialIndex];
objectQueue.Enqueue(o);
 
nextPosition += new Vector3(
Random.Range(minGap.x, maxGap.x) + scale.x,
Random.Range(minGap.y, maxGap.y),
Random.Range(minGap.z, maxGap.z));
 
if(nextPosition.y < minY){
nextPosition.y = minY + maxGap.y;
}
else if(nextPosition.y > maxY){
nextPosition.y = maxY - maxGap.y;
}
}

平台管理器知道能量块

现在所有的东西都连接到了一起,我们需要更新SpawnIfAvailable方法,这样它会激活并放置能量块 ,同时也要考虑到重生的机会。另外,为了实现这一点要先禁用能量块,在游戏最后也要禁用能量块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Start () {
GameEventManager.GameOver += GameOver;
gameObject.SetActive(false);
}
 
public void SpawnIfAvailable (Vector3 position) {
if(gameObject.activeSelf || spawnChance <= Random.Range(0f, 100f)) {
return;
}
transform.localPosition = position + offset;
gameObject.SetActive(true);
}
 
private void GameOver () {
gameObject.SetActive(false);
}

为了让能量块旋转和回收, 我们需要给它添加一个Update方法。回收通过简单地禁用来实现,通过SpawnIfAvailable使它符合重生。旋转通过基于上一阵之后经过的时间来旋转。

1
2
3
4
5
6
7
void Update () {
if(transform.localPosition.x + recycleOffset < Runner.distanceTraveled){
gameObject.SetActive(false);
return;
}
transform.Rotate(rotationVelocity * Time.deltaTime);
}

旋转的能量块

当Runner 通过能量块的时候,什么都没有发生。为了改变这一点,给能量块添加Unity事件方法OnTriggerEnter,一旦有东西触发对撞机就调用。唯一可能撞到能量块的就是Runner,我们可以继续前进,只要有触发就给出一个新的能量块。为了实现这一点,假设Runner有一个静态方法叫做AddBoost并使用它。禁用能量块,因为它已经被消耗了。

1
2
3
4
void OnTriggerEnter () {
Runner.AddBoost();
gameObject.SetActive(false);
}

实现它要给Runner添加一个AddBoost方法。为了让事情变简单,我们就添加一个私有静态变量来记住我们已经积累了多少能量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static int boosts;
 
private void GameStart () {
boosts = 0;
distanceTraveled = 0f;
transform.localPosition = startPosition;
renderer.enabled = true;
rigidbody.isKinematic = false;
enabled = true;
}
 
public static void AddBoost () {
boosts += 1;
}

为了真正实现通过消耗能量在半空中跳跃,我们需要修改检查跳跃可能性的代码。定义独立的提高速度,设置为(10, 10, 0)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Vector3 boostVelocity, jumpVelocity;
 
void Update () {
if(Input.GetButtonDown("Jump")){
if(touchingPlatform){
rigidbody.AddForce(jumpVelocity, ForceMode.VelocityChange);
touchingPlatform = false;
}
else if(boosts > 0){
rigidbody.AddForce(boostVelocity, ForceMode.VelocityChange);
boosts -= 1;
}
}
distanceTraveled = transform.localPosition.x;
 
if(transform.localPosition.y < gameOverY){
GameEventManager.TriggerGameOver();
}
}

建议使用电驴(eMule)下载分享的资源。

说明
:本教程来源互联网或网友分享或出版商宣传分享,仅为学习研究或媒体推广,51zixue.net不保证资料的完整性。
 
上一篇:【Unity C#编程】跑动游戏(6):GUI和粒子特效  下一篇:【Unity C#编程】跑动游戏(4):平台与游戏事件