How to effect and apply a common material to children individually...

Hi Guys,

I’m having trouble changing the material on children inside a prefab via a raycast hit…

To set the scene I have a city that I want to be able to click on blocks and bring up a list of some sort, all in AR.

I’ve got everything working for the prototype aside from the “highlight”/change material.

I want to be able to highlight/change material of the block I click on/raycast hit, as well as bring up the UI details about the block/plot/gameobject.

Eventually I want to be able to bring in those details via a CSV file and update via the cloud but need the prototype up and running first.

I’ve got the material changing but it effects the first material slot of everything…

Eventually I want to be able to do more things with the children but will settle for understanding my problem a bit better…

As always I appreciate your time and any and all help is much appreciated.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

public class IsClicked : MonoBehaviour {

	public CanvasGroup ItemCanvas;
	public Renderer rend;
	public Material StartColour;
	public Material childColour;
	public List<Transform> objects;
	public List<Transform> childObjects;
	public Material Glow;

	List <Material> childColours;
	List<Renderer> childRenderers;
	Renderer childRenderer;

	void Start () 
	{
		rend = GetComponent<Renderer>();
		childColours = new List<Material>();
		childRenderers = new List<Renderer>();
		childRenderer = GetComponent<Renderer> ();
		StartColour = childRenderer.material;
		for (int i = 0; i < transform.childCount; ++i) {
			childRenderers.Add (transform.GetChild (i).GetComponent<Renderer> ());
			childColours.Add (childRenderers *.material);*
  •  }*
    
  • }*

  • void Update () {*

  •  if (Input.GetMouseButtonDown (0)) {*
    
  •  	Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);*
    
  •  	RaycastHit hit;*
    
  •  	if (Physics.Raycast (ray, out hit, 1000)) {*
    
  •  		ItemCanvas.interactable = true;*
    
  •  		ItemCanvas.blocksRaycasts = true;*
    
  •  		ItemCanvas.alpha = 1;*
    
  •  		childRenderer.material = Glow;*
    
  •  		for (int i = 0; i < childRenderers.Count; ++i)*
    

_ childRenderers .material = Glow;_

* if (hit.collider.tag == “plot_01”) {
Debug.Log (“plot_01”);
_
}_
if (hit.collider.tag == “plot_02”) {
Debug.Log (“plot_02”);
_
}_
if (hit.collider.tag == “plot_03”) {
Debug.Log (“plot_03”);
_
}_
_
}*_

* else{*
* Debug.Log (“you clicked on nothing”);*
* ItemCanvas.interactable = false;*
* ItemCanvas.blocksRaycasts = false;*
* ItemCanvas.alpha = 0;*

* childRenderer.material = StartColour;*
* for(int i = 0; i < childRenderers.Count; ++i)*
childRenderers_.material = childColours*;
}*_

* }*
* }*
}

you are changing the material of each child of your list: don’t you want to change it only on the one that was hit by a raycast?

Hey Guys,

Well that was quite fun!

I ended up doing it like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

public class IsClicked : MonoBehaviour {

	public CanvasGroup ItemCanvas;
	public Renderer rend;
	public Material Glow;
    public Material[] StartColour;
	public Component[] allChildren;
	private GameObject Plot_01;
	private GameObject Plot_02;
	private GameObject Plot_03;
	private GameObject Plot_04;

    List<Material> childColours;
    List<Renderer> childRenderers;
    Renderer parentRenderer;

    void Start () 
	{
        childColours = new List<Material>();
        childRenderers = new List<Renderer>();
        parentRenderer = GetComponent<Renderer>();
        StartColour = parentRenderer.materials;
        for (int i = 0; i < transform.childCount; ++i)
        {
            childRenderers.Add(transform.GetChild(i).GetComponent<Renderer>());
            childColours.Add(childRenderers*.material);*

}
Plot_01 = GameObject.Find (“Plot_01”);

  •  Plot_02 = GameObject.Find ("Plot_02");*
    
  •  Plot_03 = GameObject.Find ("Plot_03");*
    
  •  Plot_04 = GameObject.Find ("Plot_04");*
    
  • }*

  • void Update ()*

  • {*

  •  if (Input.GetMouseButtonDown (0)) {*
    
  •  	Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);*
    
  •  	RaycastHit hit;*
    

if (Physics.Raycast(ray, out hit, 1000)) {
ItemCanvas.interactable = true;
ItemCanvas.blocksRaycasts = true;
ItemCanvas.alpha = 1;

if (hit.collider.tag == “plot_01”) {
Plot_01.GetComponent().material = Glow;
Debug.Log(“plot_01”);
}
if (hit.collider.tag == “plot_02”) {
Plot_02.GetComponent().material = Glow;
Debug.Log(“plot_02”);
}
if (hit.collider.tag == “plot_03”) {
Plot_03.GetComponent().material = Glow;
Debug.Log(“plot_03”);
}

if (hit.collider.tag == “plot_04”) {
Plot_04.GetComponent().material = Glow;
Debug.Log(“plot_04”);
}
}

else
{
Debug.Log(“you clicked on nothing”);
ItemCanvas.interactable = false;
ItemCanvas.blocksRaycasts = false;
ItemCanvas.alpha = 0;
parentRenderer.materials = StartColour;
for (int i = 0; i < childRenderers.Count; ++i) childRenderers_.material = childColours*;
}*_

}
}
* }*
If you can see a better way of doing it please let me know, alternatively if you know how I can apply a quick edit to change all the materials in every slot that would be great! otherwise I’ll keep hacking away.
Thanks again!