Menu
CoddyTech

Одиночка

Часть раздела Создание настоящих игр путешествия по Unity на Coddy. Урок 13 из 60.

Ссылку Inspector нужно перетащить на какой-либо объект. Враги, которых спавнер создаёт во время игры, появляются из префаба, а префаб может ссылаться только на ресурсы и собственные части, но никогда — на объект в сцене, поэтому его поле GameManager пустое. Обычно эту проблему решают с помощью синглтона: GameManager хранит себя в поле, к которому любой скрипт может обратиться по имени класса.

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    private int kills;

    void Awake()
    {
        Instance = this;
    }

    public void EnemyDown()
    {
        kills++;
        Debug.Log("Kills: " + kills);
    }
}
// Enemy.cs, на префабе врага
public void Die()
{
    GameManager.Instance.EnemyDown();
    Destroy(gameObject);
}

static означает, что поле принадлежит классу, а не объекту. У каждого объекта GameManager было бы собственное значение kills, но во всей игре есть только один Instance, и обратиться к нему можно по имени класса: GameManager.Instance. Любой скрипт может прочитать это значение, в том числе враг, созданный минуту назад, — ему не нужно заполнять собственное поле.

Менеджер задаёт Instance = this; в Awake, где this — сам скрипт. Unity запускает все Awake в сцене до любого Start, поэтому другие скрипты могут использовать GameManager.Instance уже в своём Start. Второй GameManager в сцене перезаписал бы Instance своим значением; в главе «Сцены и уровни» показано, как этому помешать.

challenge icon

Задание

Легко

Позвольте метеорам обращаться к GameManager через одиночку.

  1. В GameManager.cs добавьте public static GameManager Instance; и Awake() с Instance = this;.
  2. В Meteor.cs удалите поле game и вместо этого вызывайте GameManager.Instance.MeteorLanded() и GameManager.Instance.MeteorCaught().

Нажмите «Играть» и поймайте метеор: появится Caught: 1, а в Console не будет ошибок. Затем нажмите «Проверить».

Попробуйте сами

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    public TMP_Text caughtText;
    public TMP_Text shieldText;
    private int caught;
    private int shield = 3;

    public void MeteorCaught()
    {
        caught++;
        caughtText.text = "Caught: " + caught;
    }

    public void MeteorLanded()
    {
        shield--;
        shieldText.text = "Shield: " + shield;
    }
}

Все уроки раздела Создание настоящих игр

Потренируйтесь самостоятельно: Песочница Unity