Почему метод FindObjectsOfType возвращает только 1 объект? - PullRequest
0 голосов
/ 29 сентября 2019

Я пытаюсь создать игру с 2 уровнями. Счет, набранный игроком на уровне 1, должен сохраняться до уровня 2. Но игра зависает на уровне два. В начале уровня 2 должно быть 2 объекта уровня, но во время отладки я обнаружил, что метод FindObjectsOfType<Level>() возвращает 1.

public class Level : MonoBehaviour
{
    [SerializeField] TextMeshPro text ;
    [Range(0,10)][SerializeField] float speed;
    public int blocksAvailable, points;
    // Start is called before the first frame update
    void Start() {
        blocksAvailable = countBlocks();
        points = 0;

    }
    private void Awake() {
        int levelObjectCount = FindObjectsOfType<Level>().Length;
        if (levelObjectCount > 1)  {
            Destroy(gameObject);
        }
        else {
            DontDestroyOnLoad(gameObject);
        }
    }
    // Update is called once per frame
    void Update() {
        text.text = points.ToString();
        if (blocksAvailable == points) {
            SceneManager.LoadScene(2);
        }
        Time.timeScale = speed;
    }

    public int countBlocks() {
        int blocks = GameObject.FindGameObjectsWithTag("Block").Length;
        return blocks;
    }

    public void addPoints() {
        points++;
    }
}

1 Ответ

0 голосов
/ 30 сентября 2019

FindObjectsOfType может найти только компоненты, которые включены и активны в иерархии сцены. Если по какой-либо причине это не так в момент, когда вы вызываете его, вы не найдете этот компонент.

Он не вернет никаких активов (сетки, текстуры, префабы, ...) или неактивныхобъекты.

Также обратите внимание

Обратите внимание, что эта функция очень медленная. [...]. В большинстве случаев вы можете использовать шаблон синглтона вместо этого.

Так что в вашем случае я бы предпочел использовать шаблон синглтона:

// This stays set and shared between all Level classes
// also between scenes for the entire session
private static Level instance;

private void Awake()
{
    // other instance already exists?
    if(instance)
    {
        Debug.Log("Another instance of Level already exists. Click here to highlight it in the hierarchy", instance);
        Destroy(gameObject);
        return;
    }

    instance = this;
    DontDestroyOnLoad(gameObject);
}
...