web-dev-qa-db-fra.com

GameObject.FindObjectOfType <> () vs GetComponent <> ()

J'ai suivi plusieurs séries de didacticiels et j'ai vu ces deux-là utilisés de manière très similaire, et j'espérais que quelqu'un pourrait expliquer comment ils diffèrent et, si possible, des exemples de cas où vous utiliseriez l'un au lieu de l'autre (en supposant qu'ils sont en fait similaires !).

private LevelManager levelManager;

void Start () {
    levelManager = GameObject.FindObjectOfType<LevelManager>();
}

et

private LevelManager levelManager;

void Start () {
    levelManager = GetComponent<LevelManager>();
}
12
JonHerbert

Vous ne voulez pas utiliser

void Start () {
    levelManager = GameObject.FindObjectOfType<LevelManager>();
}

si souvent. Particulièrement sur start

Pour répondre à votre question, ces deux fonctions ne sont en fait pas très similaires. L'un est un appel extérieur, l'autre un intérieur.
Alors quelle est la différence?

  1. Le GameObject.FindObjectOfType Est plus une recherche à l'échelle de la scène et n'est pas le moyen optimal d'obtenir une réponse. En fait, Unity a déclaré publiquement son super lent Référence de l'API Unity3D - FindObjectOfType

  2. La GetComponent<LevelManager>(); est un appel local. Cela signifie que le fichier qui effectue cet appel ne recherchera que le GameObject auquel il est attaché. Ainsi, dans l'inspecteur, le fichier ne recherchera que d'autres choses dans la même fenêtre d'inspecteur. Tels que Mesh Renderer, Mesh Filter, Etc. Ou qui objecte les enfants. Je crois cependant qu'il existe un appel distinct pour cela.
    Vous pouvez également l'utiliser pour accéder aux autres composants de GameObject si vous les référencez d'abord (voir ci-dessous).

Résolution:

Je recommanderais de faire une recherche tag dans la fonction awake.

private LevelManager levelManager;

void Awake () {
    levelManager = GameObject.FindGameObjectWithTag ("manager").GetComponent<LevelManager>();
}

N'oubliez pas de marquer le GameObject avec le script LevelManager dessus en ajoutant une balise. (Cliquez sur le GameObject, regardez en haut de l'inspecteur, puis cliquez sur Tag-> Ajouter un tag

Vous pouvez le faire ou

public LevelManager levelManager;

Et faites glisser le GameObject dans la zone de l'inspecteur.

L'une ou l'autre option est nettement meilleure que de faire un GameObject.FindObjectOfType.

J'espère que cela t'aides

15
iSkore

Il y a deux différences:

1.) GetComponent<T> ne trouve un composant que s'il est attaché au même GameObject. GameObject.FindObjectOfType<T> d'autre part, recherche toute la hiérarchie et retourne le premier objet qui correspond!

2.) GetComponent<T> renvoie uniquement un objet qui hérite de Component, tandis que GameObject.FindObjectOfType<T> ne s'en soucie pas vraiment.

5
walther