[RESOLU] [DB-AL] Déposer des scripts automatiquement aux derniers enfants

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Zoker
Messages : 4
Inscription : 18 Juin 2018 16:30

[RESOLU] [DB-AL] Déposer des scripts automatiquement aux derniers enfants

Message par Zoker » 26 Juin 2018 12:27

Bonjour !

Je me retourne une nouvelle fois vers la communauté Unity Fr pour pouvoir m'aider à comprendre un problème.

L'objectif du programme que je vais vous présentez ci-dessous est pour ajouter des scripts automatiquement aux derniers enfants de le hierarchy.

Je ne veux pas cibler les enfants car les gameObjects vont tout le temps changer étant donné que je viendrai charger des nouvelles maquettes Revit (logiciel de conception 3D, BIM) au format FBX.
Ainsi donc, de nouveaux GameObject seront créés.

Le principe est de placer manuellement le script "AddComponent1" sur les premiers parents et par la suite, le code va déposer un autre script sur ses enfants et ainsi de suite jusqu'à délivrer le script nécessaire au bon déroulement du jeu "MouseOnGameObject3".

Ce n'est peut être pas la solution la plus optimisé mais avec mon niveau et avec les recherches que j'ai effectué, je n'ai trouvé que cette possibilité.

Code : Tout sélectionner

public class AddComponent1 : MonoBehaviour {

    public GameObject[] FirstChild;

    void Start()
    {
        foreach (Transform child in transform)
            child.transform.gameObject.tag = "FirstChild";
        FirstChild = GameObject.FindGameObjectsWithTag("FirstChild");
        foreach (GameObject one in FirstChild)
            one.AddComponent<AddComponent2>();
    }
}

Code : Tout sélectionner

public class AddComponent2: MonoBehaviour {

    public GameObject[] SecondChild;

    void Start ()
    {
        foreach (Transform child in transform)
            child.transform.gameObject.tag = "SecondChild";
        SecondChild = GameObject.FindGameObjectsWithTag("SecondChild");
        foreach (GameObject second in SecondChild)
            second.AddComponent<MouseOnGameObject3>();
    }
}
Comme vous pouvez le voir j'ai utilisé les Tags pour pouvoir rajouter la fonction AddComponent<>() étant donné que je ne peux pas le faire directement à la suite de foreach(Transform child in transform).

Je vous montrer quelques screens pour énoncer mes propos.

Image

Image

De plus, et c'est là le vrai problème que je souhaite vous exposez.

Lorsque je lance le mode play et que tout se place bien comme il faut... et bien ça se place un peu trop.
En effet, mes scripts que je souhaite donner aux derniers enfants sont multipliés.

Image

Plein de script sont donc placés... il doit forcement lire plusieurs fois la même fonction... :0

Merci pour votre aide et vos futurs réponses et j'espère avoir été claire !
Dernière édition par Zoker le 26 Juin 2018 18:23, édité 1 fois.

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

Re: [DB-AL] Déposer des scripts automatiquement aux derniers enfants

Message par boubouk50 » 26 Juin 2018 13:45

Salut,
Alors, dans tout ça. Il va falloir expliquer plutôt que corriger, je pense.

Code : Tout sélectionner

foreach (Transform child in transform)
            child.transform.gameObject.tag = "FirstChild";
Ici, tu va taguer tous les enfants au premier degré (donc pas les petits enfants et encore plus bas)

Code : Tout sélectionner

FirstChild = GameObject.FindGameObjectsWithTag("FirstChild");
Ensuite tu vas récupérer TOUS les objets tagués FirstChild. Donc pas forcément dans les enfants mais dans la scène entière! Donc potentiellement ceux déjà tagués par une autre instance du script. Qui plus est, dans la première partie, tu tagues, puis tu récupères (pas les bons) pour ensuite ajouter un Component. Pourquoi ne pas ajouter directement le Component?

Code : Tout sélectionner

foreach (Transform child in transform) {
        child.transform.gameObject.tag = "FirstChild";
        one.AddComponent<AddComponent2>();
}
Ensuite, tu fais la même chose pour les petits enfants. Mais cela te limite à une hiérarchie de trois et à écrire en dur. Une méthode efficace serait d'utiliser la récursivité.

Enfin, le AddComponent ne peut se faire que sur un gameObject, pas sur un transform. Il faut donc utiliser l'accès au gameObject depuis le transform, grâce à .gameObject

Code : Tout sélectionner

child.gameObject.AddComponent <AddComponent2> ();
La question: As-tu besoin des scripts AddComponent1 et AddComponent2? Si tu ne veux qu'affecter les derniers enfants, alors tu peux utiliser la récursivité pour les atteindre et n'affecter qu'eux.

Code : Tout sélectionner

void Start () {
	//Lancer la fonction depuis le parent de tous. Tu peux définir un parent global à toutes les hiérarchies à mettre affecter pour n'avoir qu'une occurrence de ce script.
	FindLastChildren (this.transform);
}

private void FindLastChildren (Transform _parent) {
	//tester s'il possède un enfant pour savoir si c'est le dernier et donc arrêter la récursivité
	if (_parent.childCount == 0) {
		//Ici affecter ce gameObject car dernier enfant
		_parent.gameObject.AddComponent <MouseOnGameObject3> ();
	}
	else { //Sinon recommencer avec chacun des enfants
		foreach (Transform child in _parent) {
		//Tu peux également ajouter d'autres affectation ici (tag par ex)
			FindLastChildren (child);
		}
	}
}
"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

Zoker
Messages : 4
Inscription : 18 Juin 2018 16:30

Re: [DB-AL] Déposer des scripts automatiquement aux derniers enfants

Message par Zoker » 26 Juin 2018 18:23

Merci énormément !

La récursivité était exactement ce qu'il me fallait !
Du coup, je n'ai plus besoin d'avoir de trop nombreux script et des tags qui se place un peu partout.

Encore merci ;)

Répondre

Revenir vers « (C#) CSharp »