Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
We use cookies to ensure that we provide you with the best possible experience on our site.
Votre source incontournable sur Unity et le développement web
Votre source incontournable sur Unity et le développement web
Sur Unity, les développeurs utilisent fréquemment `GetComponent`. Cette fonction permet de récupérer un composant attaché à votre GameObject. Dans ce guide complet, nous explorons divers aspects de `GetComponent` et fournissons en fin d’article quelques astuces.
Table des matières
using UnityEngine;
public class MonoBehaviourComponent : MonoBehaviour
{
private void Action()
{
// Utiliser GetComponent immédiatement, car MonoBehaviour étend Component
// Méthode de base
var boxCollider2d = GetComponent<BoxCollider2D>();
// Avec le type en tant que paramètre
var box2 = GetComponent(typeof(BoxCollider2D)) as BoxCollider2D;
}
}
Un composant dans Unity est un script C# héritant de `UnityEngine.Component`, attaché à un GameObject pour effectuer diverses tâches telles que le rendu, le gameplay ou la gestion des collisions… Tous les composants ont accès aux fonctions de « recherche » de composants fournies par `UnityEngine.Component`.
Inspecteur Unity avec 3 composants
`TryGetComponent` est utilisée dans un scénario où vous n’êtes pas sûr si le composant est attaché à votre GameObject. Cette fonction renvoie `true` si le composant est trouvé.
private void Handle()
{
if (TryGetComponent<BoxCollider2D>(out BoxCollider2D boxCollider2D))
{
boxCollider2D.isTrigger = true;
}
}
Vous pouvez également récupérer des composants qui implémentent une interface à l’aide de `GetComponent`. Par exemple, vous pouvez obtenir un composant qui implémente l’interface `IPointerDownHandler`.
using UnityEngine;
using UnityEngine.EventSystems;
public class MonoBehaviourComponent : MonoBehaviour
{
public GameObject referenceGameObject;
private void Awake()
{
var pointer = referenceGameObject.GetComponent<IPointerDownHandler>();
}
}
La fonction `GetComponents` vous permet de récupérer tous les composants d’un même type sur un GameObject.
private void Action()
{
var boxCollider2Ds = GetComponents<BoxCollider2D>();
foreach (var boxCollider in boxCollider2Ds)
{
boxCollider.isTrigger = true;
}
}
Remarque : Cette fonction renvoie un tableau d’éléments du type spécifié.
Cette fonction peut également être utilisée en passant une liste en tant que paramètre pour éviter de recréer une liste à chaque appel :
private List<BoxCollider2D> _boxColliders = new List<BoxCollider2D>();
private void Update()
{
GetComponents(_boxColliders);
foreach(var boxCollider in _boxColliders)
{
// effectuer des actions
}
}
`GetComponentInChildren` récupère un composant d’un type spécifique du GameObject lui-même ou d’un GameObject enfant.
private void InChildren()
{
// Trouver la premiere Image dans lui-même ou ses enfants si leur gameObject est actif
var image = GetComponentInChildren<Image>();
image.color = Color.red;
// Trouver la premiere Image dans lui-même ou ses enfants si leur gameObject est inactif ou actif
var imageDisabled = GetComponentInChildren<Image>(true);
}
Découvrez comment récupérer tous les composants d’un type spécifique du GameObject lui-même et de ses enfants en utilisant `GetComponentsInChildren`.
private void InChildrens()
{
// Trouver toutes les Images dans lui-même et ses enfants si leur gameObject est actif
var images = GetComponentsInChildren<Image>();
foreach (var image in images)
{
image.sprite = null;
}
// Trouver toutes les Images dans lui-même et ses enfants si leur gameObject est inactif ou actif
var disabledImages = GetComponentsInChildren<Image>(true);
}
Remarque : Cette fonction peut également être utilisée en passant une liste en tant que paramètre pour éviter de recréer une liste à chaque appel.
`GetComponentInParent` récupère un composant d’un type spécifique du GameObject lui-même ou d’un parent.
private void InParent()
{
// Trouver la premiere Image dans lui-même ou ses parents si leur gameObject est actif
var image = GetComponentInParent<Image>();
image.color = Color.red;
// Depuis Unity 2020, trouver la premiere Image dans lui-même ou ses parents si leur gameObject est inactif ou actif
var imageDisabled = GetComponentInParent<Image>(true);
}
Explorez `GetComponentsInParent` pour récupérer tous les composants d’un type spécifique du GameObject lui-même et de ses parents.
private void InParents()
{
// Trouver toutes les Images dans lui-même et ses parents si leur gameObject est actif
var images = GetComponentsInParent<Image>();
foreach (var image in images)
{
image.sprite = null;
}
// Trouver toutes les Images dans lui-même et ses parents si leur gameObject est inactif ou actif
var disabledImages = GetComponentsInParent<Image>(true);
}
Remarque : Pour éviter de recréer une liste à chaque appel, cette fonction peut avoir une liste en tant que paramètre.
Un petit conseil, pour éviter la recherche sur lui-même, vous pouvez appeler la méthode directement sur le parent :
var imagesWithoutSelf = transform.parent.GetComponentsInParent<Image>();
Trouver un composant avec le nom du gameObject n’est pas une bonne approche. La fonction utilisée pour cela est `GameObject.Find`, mais elle n’est pas très efficace. Pour de meilleures performances, vous pouvez utiliser d’autres méthodes telles que les références directes ou le suivi des composants dans un manager.
private void FindByName()
{
// Évitez cet appel...
var boxCollider2d = GameObject.Find("NomDeMonGameObject").GetComponent<BoxCollider2D>();
}
Au lieu d’utiliser `GetComponent`, envisagez de créer une propriété sérialisable pour référencer directement votre composant.
using UnityEngine;
public class MonoBehaviourComponent : MonoBehaviour
{
public BoxCollider2D boxCollider2D;
// ou, si vous préférez un champ privé
[SerializeField]
private BoxCollider2D _boxCollider2D;
}
Utilisez les méthodes `OnEnable` et `OnDisable` pour suivre les composants du même type en les ajoutant et en les supprimant d’une liste statique.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class MonoBehaviourComponent : MonoBehaviour
{
public BoxCollider2D boxCollider2D;
public string code;
public static List<MonoBehaviourComponent> ListComponents { get; private set; } = new List<MonoBehaviourComponent>();
private void OnEnable() => ListComponents.Add(this);
private void OnDisable() => ListComponents.Remove(this);
}
Maintenant, nous utilisons l’identifiant (code) au lieu du nom pour appeler le composant, par exemple en utilisant LINQ :
using System.LINQ;
// Exception non gérée dans ce code
var boxCollider2d = MonoBehaviourComponent.ListComponents.Single(x => x.code == "monCode").boxCollider2D;
Créez un manager pour gérer vos composants MonoBehaviour. Le manager peut instancier et détruire des composants, fournissant une approche centralisée pour gérer vos composants.
J’adore utiliser des managers car ils me permettent de développer mon code très facilement. Vous pouvez partir de cette base et ensuite ajouter un système de pool, des événements (events), etc.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class ComponentManager : MonoBehaviour
{
// c'est un modèle, peut être un prefab
public MonoBehaviourComponent monoBehaviourComponent;
public List<MonoBehaviourComponent> components = new List<MonoBehaviourComponent>();
public static ComponentManager Instance { get; private set; }
private void Awake()
{
Instance = this;
}
public void InvokeComponent(string code)
{
var instance = Instantiate(monoBehaviourComponent);
instance.code = code;
components.Add(instance);
}
public void DestroyComponent(MonoBehaviourComponent component)
{
if (components.Contains(component))
{
components.Remove(component);
}
Destroy(component.gameObject);
}
public MonoBehaviourComponent GetComponentByCode(string code)
{
return components.SingleOrDefault(x => x.code == code);
}
}
En utilisant notre ancien exemple, nous ferions un appel comme ceci :
var boxCollider2d = ComponentManager.Instance.GetComponentByCode("monCode").boxCollider2D;
Il est recommandé dans un Monobehaviour de définir vos appels `GetComponent` dans la méthode `Awake` puis de les utiliser pendant ou après la méthode `Start` pour éviter les `NullReferenceException`. Dans ce schéma `Awake` est utilisé uniquement pour définir des composants ou des Singletons, et `Start` est utilisé pour la configuration.
[SerializeField]
private BoxCollider2D _boxCollider2D;
private void Awake()
{
_boxCollider2D = GetComponent<BoxCollider2D>();
}
private void Start()
{
_boxCollider2D.isTrigger = true;
}
Mettez en cache vos appels `GetComponent` dans un champ ou évitez de les appeler à chaque frame. N’oubliez pas que, par défaut, aucun cache n’est appliqué à ces fonctions. Si vous appelez, par exemple, `GetComponentInParent` dans un `Update`, cela recherchera tous les parents à chaque frame, ce qui peut potentiellement affecter vos performances.
[SerializeField]
private BoxCollider2D _boxCollider2D;
private List<ContactPoint2D> _contactPoints = new List<ContactPoint2D>();
private void Awake()
{
_boxCollider2D = GetComponent<BoxCollider2D>();
}
private void FixedUpdate()
{
if (_boxCollider2D.GetContacts(_contactPoints) > 0)
{
// Effectuer des actions avec le contact
}
}
J’espère que ce tutoriel vous a fourni des informations précieuses sur les composants dans Unity. Que vous soyez débutant ou développeur expérimenté, maîtriser l’utilisation de `GetComponent` et de ces méthodes associées est crucial pour un développement efficace.
Merci de l’avoir lu.