[Résolu] Enfants indestructibles ???

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
jmhoubre
Messages : 851
Inscription : 05 Oct 2019 22:05

[Résolu] Enfants indestructibles ???

Message par jmhoubre » 04 Avr 2022 11:53

Bonjour,

dans un projet 2D URP 2020.3.32, j'ai une interrogation.
En mode éditeur, je construis des pièces de façon aléatoire (selon les tuto de Sunny Valley décrit dans la section Tuto), cela fonctionne bien.
Afin de m'aider à peupler ces pièces avec des props et des ennemis, j'ai matérialisé le centre de chaque pièce en y instanciant un Sprite Circle.
Évidemment, à chaque nouvelle génération du donjon il me faut effacer les anciens marqueurs, ce que je fais comme ci-dessous, mais 4 enfants résistent à la destruction :
Code initial

Code : Tout sélectionner

// Calcul de la liste des pièces -> roomsList
// ...

// Efface les marqueurs.
foreach (Transform child in parentMarkers.transform)
{
#if UNITY_EDITOR
	DestroyImmediate (child.gameObject);
#else
	Destroy (child.gameObject);
#endif
}

// Calcule le centre de chaque pièce.
List<Vector2Int> roomCenters = new List<Vector2Int> ();
foreach (BoundsInt room in roomsList)
{
	roomCenters.Add ((Vector2Int) Vector3Int.RoundToInt (room.center));
	// Place un sprite cercle au centre.
	Instantiate (prefabMarker, new Vector3 (room.center.x, room.center.y, 0), Quaternion.identity, parentMarkers);
}
J'ai donc modifié comme ceci, et je n'ai plus le problème :
Code final

Code : Tout sélectionner

// Efface les marqueurs.
while (parentMarkers.transform.childCount > 0)
{
	foreach (Transform child in parentMarkers.transform)
	{
#if UNITY_EDITOR
		DestroyImmediate (child.gameObject);
#else
		Destroy (child.gameObject);
#endif
	}
}
Quel est le problème dans le code initial ?
Dernière édition par jmhoubre le 04 Avr 2022 15:45, édité 1 fois.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6185
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: Enfants indestructibles ???

Message par boubouk50 » 04 Avr 2022 12:59

Je pense que c'est le fait de travailler sur les éléments de la liste sur laquelle tu fais ton foreach.
Tu vas supprimer des éléments de parentMarkers.transform pendant que tu boucles dessus. Des pertes peuvent intervenir.
Il est d'ailleurs conseillé de ne pas travailler sur la liste d'éléments qui sert de condition de boucle.
Généralement, pour détruire des enfants, tu récupères la liste de ceux-ci puis tu viens détruire les éléments de cette liste avec un for en commençant par la fin.
Si tu veux détruire tous les enfants d'un gameObject, tu peux éviter ce problème en plaçant les enfants de premier niveau (GetComponentsInChildren(Transform)) sous un nouveau parent et détruire ce parent.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
jmhoubre
Messages : 851
Inscription : 05 Oct 2019 22:05

Re: Enfants indestructibles ???

Message par jmhoubre » 04 Avr 2022 15:33

J'ai transformé la boucle :

Code : Tout sélectionner

Debug.Log ($"{parentMarkers.transform.childCount} enfants à détruire");
for (int i = parentMarkers.transform.childCount - 1; i >= 0; i--)
{
#if UNITY_EDITOR
	DestroyImmediate (parentMarkers.transform.GetChild (i).gameObject);
#else
	Destroy (parentMarkers.transform.GetChild(i).gameObject);
#endif
}
Cela fonctionne. Merci.

Répondre

Revenir vers « Scripting »