coroutine , foreach help needed please

void OnTriggerEnter(Collider other) { coroutine starts ,

in the coroutine - i call 2 functions…before and after yield return new WaitForSeconds(15.0f);

// the function called before yield return new WaitForSeconds(15.0f); changes the material of the objects which are tagged as “obstacle”…

It works perfectly fine but for only those who were spawned at that time, but i want to do it for all those will spawn till 15.0f secs.

Here is my script, see line no. 28 …please help.

using UnityEngine;
using System.Collections;

public class powerup2 : MonoBehaviour {
	
	
	public static bool powerup2ON;
	public int powerup2_status;
	
	
    public Shader shader1 = Shader.Find("MADFINGER/Diffuse/Simple");
	public Shader shader2 = Shader.Find("MADFINGER/Transparent/Blinking GodRays");

	
	// Use this for initialization
	void Start () {
	transform.Rotate(90, 180, 0);
	powerups.Load_powerup_2_status();
		//renderer.material.shader = shader2;
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	
	void NoObstacles(){
		GameObject[] obstacleGameObject = GameObject.FindGameObjectsWithTag("obstacle");
		// not for foreach , do it for all new spawns till 15 sec
		foreach(GameObject go in obstacleGameObject){
			
			go.collider.enabled = false;

			go.renderer.material.shader = shader2;
            go.renderer.material.SetFloat("_FadeOutDistNear", 25);
		}
	}
	
	void YesObstacles(){
		GameObject[] obstacleGameObject = GameObject.FindGameObjectsWithTag("obstacle");
		foreach(GameObject go in obstacleGameObject){
			go.collider.enabled = true;
			 go.renderer.material.shader = shader1;
			//go.collider.isTrigger = true;
		}
	}
	
	
			IEnumerator Tcounter5sec_p2(){
		
		NoObstacles();
		Debug.Log("inside powerup2");
yield return new WaitForSeconds(15.0f);
Debug.Log("15 secs p2 trial");
		Destroy(gameObject);
		YesObstacles();
powerup2ON=false;		
}
	
	IEnumerator Tcounter10sec_p2 (){
		Debug.Log("inside 10sec ");
yield return new WaitForSeconds(10.0f);
Debug.Log("10 secs");
		Destroy(gameObject);
powerup2ON=false;		
}
	
	void OnTriggerEnter(Collider other) {
		if(other.gameObject.tag == "Player"){
			powerup2ON=true;
			Debug.Log("I am Power up 2");
			powerup2_status = powerups.p2stat;
			Debug.Log(powerup2_status);
			if(powerup2_status==0){ 
				Debug.Log("I am Power up 2-inside if");
				StartCoroutine (Tcounter5sec_p2());
			}
			
			else if(powerup2_status==1  powerup2ON==true){
				StartCoroutine(Tcounter10sec_p2());
			}
			//Destroy(gameObject);
    }}
	
	 void OnBecameInvisible() {
		//StartCoroutine(Tcounter5sec());
		
		
		//Debug.Log("Invisible Obstacle");
        //Destroy(gameObject);
    }
	
}

Why don’t you use a bool for this?

Just create a “bool changeMats = false” and use it in an update() function that iterates with for (for example) through a list of objects. For now, nothing happens as we have if(changeMats) {} the changeMats bool is not true so we won’t change materials…

Now each time you create/instantiate a new object add it to our list that you also need to generate (e.g. List myObjs) now simply change only “changeMats” to true before the 15 seconds wait time and then return it back to false. Meanwhile it’s true all materials will be changed, also from newly created objects as they will be stored in our list that we iterate through. After the time runs out we set it to false and the for-loop won’t be triggered now, you could use an else function to reset materials. If you want you could even add some more if-stuff to check if the material already was changed, then you don’t need to change it again.

Should give you some idea to start over :wink: