Atteindre le .renderer de tous les objets enfants

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
freakdoctor
Messages : 12
Inscription : 16 Déc 2012 17:13

Atteindre le .renderer de tous les objets enfants

Message par freakdoctor » 16 Déc 2012 17:47

J'essaye de créer une scène où je peux modifier la couleur d'une voiture à l'aide d'un script en C# que j'ai trouvé sur le net:

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class SceneGUI : MonoBehaviour {
	public Material[] mats;
	public GameObject ga;
	private int index = 0;
	
	
	void Start () {
		ga.renderer.material = mats[index];
		
		
	}
	
	
	public void OnGUI() {
		GUILayout.BeginArea(new Rect(Screen.width / 2 - 100, Screen.height - 60, 200, 50));
			GUI.Box(new Rect(10, 10, 190, 40),"");
			
			GUI.Label(new Rect(62, 20, 100, 20), "Car Texture " + (index + 1));
			
			if(GUI.Button(new Rect(15, 15, 30, 30), "<<")){
				index--;
				if(index < 0) {
					index = mats.Length - 1;
				}
				ga.renderer.material = mats[index];
			}
			
			if(GUI.Button(new Rect(165, 15, 30, 30), ">>")){
				index++;
				if(index >mats.Length - 1) {
					index = 0;
				}
				ga.renderer.material = mats[index];
			}
		GUILayout.EndArea ();
	}
}
Mais avec ce script je ne peux atteindre qu'un seul élément de ma carrosserie. Ma voiture se compose comme tel:

>Golf3
.. >Chassis
.. >Capot
..>Pare-choc
..etc...

Lorsque je choisis l'objet Golf3 j'ai un message d'erreur m'indiquant que golf 3 n'a pas de "renderer" et qu'un script essaye de l'atteindre. Comment signifier à mon script qu'il doit aller chercher le renderer des enfants attachés à Golf3?

Image

Merci de votre aide ;)

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: Atteindre le .renderer de tous les objets enfants

Message par Max » 16 Déc 2012 18:10

freakdoctor a écrit :Lorsque je choisis l'objet Golf3 j'ai un message d'erreur m'indiquant que golf 3 n'a pas de "renderer"
C'est normal. En fait Golf3 ne possède probablement pas de mesh à proprement parlé. Il n'est (en quelque sorte) que le container principal des enfants qui compose ta voiture.

Donc seul les enfants (ou du moins une partie, comme Châssis ou Capot j'imagine) possèdent probablement des mesh dont tu peux modifier les éléments du
renderer, dans ton cas la couleur. Il faut donc récupérer les enfants de ta Golf3 qui sont susceptible de d'avoir un mesh de définit et dont tu souhaites changer
la couleur.... (cherches dans la doc Transform, tu devrais y trouver les fonctions qui t'aideront)
;)
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
freakdoctor
Messages : 12
Inscription : 16 Déc 2012 17:13

Re: Atteindre le .renderer de tous les objets enfants

Message par freakdoctor » 16 Déc 2012 18:18

Effectivement, Golf3 est un objet vide contenant les différents éléments de la voiture. Je vais aller jette un oeil sur cette doc. Merci ;)

Avatar de l’utilisateur
freakdoctor
Messages : 12
Inscription : 16 Déc 2012 17:13

Re: Atteindre le .renderer de tous les objets enfants

Message par freakdoctor » 16 Déc 2012 20:32

J'ai trouvé cette fonction:

Code : Tout sélectionner

var children = GetComponentsInChildren (Transform);
Il faut que je lui dise que ga = children. Donc ga n'est plus un GameObject mais une variable children dans laquelle est contenue les transform des objets enfants du game object Golf3.
Je ne sais pas si je m'exprime correctement et si j'ai bien compris?

Si je suis dans le vrai, comment ça se passe au niveau du script?

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: Atteindre le .renderer de tous les objets enfants

Message par Max » 16 Déc 2012 21:15

Dans ton cas, si tu veux changer la couleur de tous les éléments comportant un mesh (plus précisement un meshfilter),
il faut plutôt écrire un truc comme ça:

Code : Tout sélectionner

		MeshFilter[] mfs = gameObject.GetComponentsInChildren<MeshFilter>();
        foreach (MeshFilter mf in mfs) {
            mf.renderer.material.color = Color.red; // couleur rouge par exemple
        }
Cela permet de balayer tous les enfants, mais aussi les sous-enfants (enfants d'enfant).
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
freakdoctor
Messages : 12
Inscription : 16 Déc 2012 17:13

Re: Atteindre le .renderer de tous les objets enfants

Message par freakdoctor » 16 Déc 2012 22:49

J'ai essayé ça:

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class SceneGUI : MonoBehaviour {
	public GameObject mf;
	public Material[] mats;
	private int index = 0;
   
   void Start () {
	MeshFilter[] mfs = gameObject.GetComponentsInChildren<MeshFilter>();
        foreach (MeshFilter mf in mfs) {
            mf.renderer.material = mats[index];
	}
}
   
   public void OnGUI() {
      GUILayout.BeginArea(new Rect(Screen.width / 2 - 100, Screen.height - 60, 200, 50));
         GUI.Box(new Rect(10, 10, 190, 40),"");
         
         GUI.Label(new Rect(62, 20, 100, 20), "Car Texture " + (index + 1));
         
         if(GUI.Button(new Rect(15, 15, 30, 30), "<<")){
            index--;
            if(index < 0) {
               index = mats.Length - 1;
            }
		mf.renderer.material = mats[index];
         }
         
         if(GUI.Button(new Rect(165, 15, 30, 30), ">>")){
            index++;
            if(index >mats.Length - 1) {
               index = 0;
            }
		mf.renderer.material = mats[index];
         }
      GUILayout.EndArea ();
   }
}
Mais j'ai toujours la même erreur.
Je me trompe où?

Avatar de l’utilisateur
freakdoctor
Messages : 12
Inscription : 16 Déc 2012 17:13

Re: Atteindre le .renderer de tous les objets enfants

Message par freakdoctor » 17 Déc 2012 01:02

J'ai trouvé mon erreur :mrgreen:

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class SceneGUI : MonoBehaviour {
	public GameObject ga;
	public Material[] mats;
	private int index = 0;
   
	void Start () {
		MeshFilter[] mfs = ga.GetComponentsInChildren<MeshFilter>();
			foreach (MeshFilter mf in mfs) {
				mf.renderer.material = mats[index];
		}
	}
	
	public void OnGUI() {
      GUILayout.BeginArea(new Rect(Screen.width / 2 - 100, Screen.height - 60, 200, 50));
         GUI.Box(new Rect(10, 10, 190, 40),"");
         
         GUI.Label(new Rect(62, 20, 100, 20), "Car Texture " + (index + 1));
         
         if(GUI.Button(new Rect(15, 15, 30, 30), "<<")){
            index--;
            if(index < 0) {
               index = mats.Length - 1;
            }
			MeshFilter[] mfs = ga.GetComponentsInChildren<MeshFilter>();
			foreach (MeshFilter mf in mfs) {
				mf.renderer.material = mats[index];
		}
	}
	
         
         if(GUI.Button(new Rect(165, 15, 30, 30), ">>")){
            index++;
            if(index >mats.Length - 1) {
               index = 0;
            }
			MeshFilter[] mfs = ga.GetComponentsInChildren<MeshFilter>();
			foreach (MeshFilter mf in mfs) {
				mf.renderer.material = mats[index];
		}
	}
	
		GUILayout.EndArea ();
   }
}
Là ça fonctionne impec'. Merci mille fois ;)

Avatar de l’utilisateur
yoyoyaya
Messages : 1656
Inscription : 30 Mai 2011 13:14
Localisation : PAAAAARTOUUUU
Contact :

Re: Atteindre le .renderer de tous les objets enfants

Message par yoyoyaya » 17 Déc 2012 01:11

Je n'ai pas les techniques des pros du code mais ne serais-ce pas plus simple dans le cas présent (si le code est attaché au gameObjet principal de la voiture) d'affecter directement les enfants au script à la main ? Histoire de ne pas avoir à chercher au départ ces derniers ^^
ImageImage

Avatar de l’utilisateur
freakdoctor
Messages : 12
Inscription : 16 Déc 2012 17:13

Re: Atteindre le .renderer de tous les objets enfants

Message par freakdoctor » 17 Déc 2012 02:53

Le code est attaché à la caméra et en faisant ça ça me permet d'appliquer la texture voulue à tous les mesh enfants de mon game object parent sans avoir à modifier le code en cas de modification de la voiture.

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: Atteindre le .renderer de tous les objets enfants

Message par Max » 17 Déc 2012 09:54

Si on voulais pinailler un peu, tu pourrais placer la partie changement de couleur dans une petite fonction
et juste faire les appels dans Start ou le reste du code avec un truc du genre SetMaterialByIndex(ga, index)
et le code de la fonction:

Code : Tout sélectionner

void SetMaterialByIndex(GameObject gameob, int index) {
	MeshFilter[] mfs = gameob.GetComponentsInChildren<MeshFilter>();
	foreach (MeshFilter mf in mfs) {
		mf.renderer.material = mats[index];
}
;)
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Répondre

Revenir vers « Scripting »