Menu
CoddyTech

一个脚本运行整个游戏

本课属于 Coddy Unity 学习旅程的“打造真正的游戏”单元。第 12 课,共 60 课。

把分数放在玩家的脚本中,把生命值放在生命值脚本中,再把游戏结束检查放在第三个脚本中。这样,每个脚本都需要其他脚本中的数字,因此每添加一条新规则,都要修改多个文件。Unity 游戏通常会把这些数字交给一个脚本,即 GameManager,并将它放在一个专属的空 GameObject 上。它负责管理分数、生命值以及结束游戏的规则。其他脚本只需通过调用它的公共方法来报告发生的事情。在这场点球大战中,球网会报告每个进球:

public class GameManager : MonoBehaviour
{
    private int goals;
    private int shotsLeft = 5;

    public void ShotTaken(bool scored)
    {
        if (shotsLeft == 0) return;
        shotsLeft--;
        if (scored) goals++;
        Debug.Log("Goals: " + goals + ", shots left: " + shotsLeft);
        if (shotsLeft == 0) Debug.Log("Full time: " + goals + " goals");
    }
}
// Net.cs,挂在球门的触发器上
public GameManager game;

void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Ball")) game.ShotTaken(true);
}

球网不知道还剩多少次射门,也不知道游戏何时结束。它只报告进球,由管理器决定这意味着什么;守门员的脚本会通过 game.ShotTaken(false) 报告扑救。要把点球大战改为 3 次射门,只需在一个脚本中修改一个数字。ShotTaken 开头的检查可以防止全场结束后滚进球门的球被计入。

在 Inspector 中,你可以把 GameManager 对象拖到 game 字段中,Unity 会找到该对象上的 GameManager 脚本。管理器也适合负责 HUD:当它持有分数文本和游戏结束面板时,数字和屏幕会在同一个方法中更新,其他脚本无需操作 UI。

challenge icon

挑战

简单

让 GameManager 负责记录分数和生命值。

  1. AddScore(int points):如果 gameOver 未设置,就增加 score,并在 scoreText 中显示 Score: 6。
  2. LoseLife():将 lives 减少 1,并显示 Lives: 2;当它变为 0 时,设置 gameOver,显示 gameOverPanel,并设置 player.enabled = false。
  3. 在 Gem 和 Bomb 中,当 other.CompareTag("Player") 时,调用 game.AddScore(points) 或 game.LoseLife(),然后调用 Destroy(gameObject)。

按下“开始”并撞上三个炸弹。然后点击“检查”。

亲手试试

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    public TMP_Text scoreText;
    public TMP_Text livesText;
    public GameObject gameOverPanel;
    public Player player;
    private int score;
    private int lives = 3;
    private bool gameOver;

    public void AddScore(int points)
    {
        // 加上这些分数并显示新分数,除非游戏已经结束
    }

    public void LoseLife()
    {
        // 扣除一条生命并显示剩余生命数;生命数为 0 时,游戏结束
    }
}

打造真正的游戏中的所有课

自己练习: Unity 在线编辑器