如何在unity中制作塔防游戏——继续升级怪兽

我们继续:

升级这些怪兽

切换到MonoDevelop并将以下方法添加到MonsterData:

public MonsterLevel getNextLevel(){
    int currentLevelIndex=levels.IndexOf(currentLevel);
    int maxLevelIndex=levels.Count-1;
    if(currentLevelIndex<maxLevelIndex){
        return levels[currentLevelIndex+1];
    }else{
    return null;
    }
}

在getNextLevel 获取到currentLevel 索引和索引提供的最高等级,如果怪兽没有达到最高等级则返回下一等级。否则返回null。

可以用这个方法来算出时候可以升级怪兽。

public void increaseLevel(){
    int currentLevelIndex=levels.IndexOf(currentLevel);
    if(currentLevelIndex<levels.Count-1){
        CurrentLevel= levels[currentLevelIndex+1];
    }
}

现在获取到了当前等级,然后需要通过检查它是否小于 levels.Count - 1来确认它是不是最高等级。如果是,设置CurrentLevel 进入下一等级。

测试升级能力

保存文件并在MonoDevelop中切换到PlaceMonster.cs ,添加这个新的方法:

private bool canUpgradeMonster(){
    if(monster !=null){
        MonsterData monsterData=monster.GetComponent<MonsterData>();
        MonsterLevel nextLevel=monsterData.getNextLevel();
        if(nextLevel!=null){
            return true;
        }
    }
    return false;
}

首先通过检查monster 变量是否为null 来判断是否有可以升级的怪兽。如果是这种情况,从它的MonsterData获取怪兽的当前等级。

然后检查更高等级是否可用,即当 getNextLevel() 返回不为空时。如果可以升级,返回true,否则返回false。

可以用金币进行升级

为了使升级选项可用,在 OnMouseUp 添加一个else if分枝:

if(canPlaceMonster()){
// Your code here stays the same as before
}else if(canUpgradeMonster()){
    monster.GetComponent<MonsterData>().increaseLevel();
    AudioSource audioSource=gameObject.GetComponent<AudioSource>();
    audioSource.PlayOneShot(audioSource.clip);
// TODO: Deduct gold
}

通过canUpgradeMonster()检查升级是否可用。如果是,用GetComponent() 访问MonsterData组件并呼叫增加怪兽等级的increaseLevel()。最后,触发怪兽的AudioSource。

保存文件并切换回unity。运行游戏,现在想放置并升级多少个怪兽都可以。

所有怪兽升级

花费金币——游戏管理

现在可以马上建立并升级所有怪兽了,不过,升级的挑战在哪里?

让我们深入探讨一下金币的问题。追踪的困难在于需要在不同的游戏对象之间共享信息。

下边这张图展示了所有要参与的对象。

突出的游戏对象都需要知道玩家有多少金币。

这里将使用一个可访问其他对象以便存储数据的被共享对象。在Hierarchy 点击右键并选择Create Empty。将新的游戏对象命名为GameManager。

为GameManager添加一个命名为GameManagerBehavior 的C#脚本,然后在MonoDevelop中打开新脚本。这里将会在标签里显示玩家的总金币数,因此在顶部添加下边这行代码:

using UnityEngine.UI;

这个允许访问类似Text的UI特性的类,项目用来显示标签。现在来为类添加下边的变量:

public Text goldLabel;

这个将存储用来显示玩家拥有金币量的文本组件的引用。

现在GameManager知道了标签,怎样确保金币数量存储到了变量中并且同步显示在了标签上?需要创建一个属性。

为GameManagerBehavior添加下边代码:

private int gold;
public int Gold {
  get {return gold;}
  set {
    gold = value;
goldLabel.GetComponent<Text>().text="GOLD: "+ gold;
}
}

看着熟悉吧?它和在Monster中定义的CurrentLevel 很相似。首先,创建一个私有变量,gold,来存储现有金币总数。然后定义一个Gold属性——有创造性,是吗?——执行getter和setter方法。

getter方法仅仅返回gold 值。setter方法就更有趣了。除了设置变量的值,还要设置goldLabel 的文本字段来显示金币新的数量。

你觉得有多慷慨?为Start()添加下边这行来给玩家1000金币或者更少:

Gold =1000;

为脚本分配标签对象

保存文件并切换到unity。

在Hierarchy中选择GameManager。在Inspector中点击Gold Label右边的圆圈。在Select Text 对话框,选择Scene 标签和GoldLabel。

运行游戏并且标签显示Gold: 1000。

检查玩家的“钱包”

在MonoDevelop中打开 PlaceMonster.cs,添加以下实例变量:

private GameManagerBehavior gameManager;

用gameManager 访问场景中GameManager的GameManagerBehavior 组件。为了分配它,将下边代码添加到Start():

gameManager = GameObject.Find("GameManager").GetComponent<GameManagerBehavior>();

获取到使用GameObject.Find()的名为GameManager的GameObject,即返回的第一个找到的游戏对象的名字。然后,检索它的GameManagerBehavior 组件并且稍后存储它。

注:通过设置unity编辑器的字段已经完成了这些,或者通过为GameManager 添加一个返回可以获取GameManagerBehavior单例实例的静态方法。

然而,在上边这块有一个“黑马”方法:Find,这个在运行时有些慢不过少量使用会很方便并且很好。

获得金币!

现在还不要减掉金币,因此在OnMouseUp()添加两次这行,替换每一个评论// TODO: Deduct gold:

保存文件并切换到unity,升级一些怪兽并观察金币读取更新.现在减掉了金币,不过玩家只要有空间就可以建立怪兽;它们只是会欠债.

无限的信用?太好了!但是不能允许这样.只有当玩家有足够的金币时才可以放置怪兽。

怪兽需要的金币

在MonoDevelop中切换到 PlaceMonster.cs ,用下边代码替换 canPlaceMonster() 里的内容:

int cost =monsterPrefab.GetComponent<MonsterData>().levels[0].cost;
return monster ==null&&gameManager.Gold>= cost;

在它的MonsterData中从levels检索放置怪兽的花费。然后检查monster 不是null并且gameManager.Gold 要大于花费的数量。

挑战:自己在canUpgradeMonster() 中添加玩家是否有足够金币的检测。

替换这行:

Return true;

用下边这个:

return gameManager.Gold>=nextLevel.cost;

这个用来检测玩家是否有多于升级所花费的金币数。保存并在unity中运行场景。继续尝试放置无限的怪兽们!

现在只能建立有限数量的怪兽了


下期预告:敌人来了

转至:游戏蛮牛

标签: unity, unity制作塔防游戏

?>