Hi!
I have this script for activationg my collectables again in the scene. There is a parent name “Collectabes” and it has 15 children in it. Is there a way to shorten the script, so I do not have to write 15 different IEnumerators (one for every child object)?
public class ActivateStrawberriesAgain : MonoBehaviour
{
public float sec = 14f;
void Update()
{
if (transform.GetChild(0).gameObject.activeInHierarchy == false)
{
StartCoroutine(LateCall());
}
if (transform.GetChild(1).gameObject.activeInHierarchy == false)
{
StartCoroutine(LateCall1());
}
}
IEnumerator LateCall()
{
yield return new WaitForSeconds(sec);
transform.GetChild(0).gameObject.SetActive(true);
}
IEnumerator LateCall1()
{
yield return new WaitForSeconds(sec);
transform.GetChild(1).gameObject.SetActive(true);
}
}
Starting a coroutine every frame, for every child (while the child is disabled) is a terrible idea.
Here is my suggestion using a simple list and the Update method:
private List<float> timers = new List<float>();
private void Update()
{
for(int i = 0 ; i < transform.childCount ; ++i)
ProcessChild(i);
}
private void ProcessChild(int childIndex)
{
GameObject child = transform.GetChild(childIndex).gameObject;
if(childIndex >= timers.Count)
timers.Add(sec);
if(child.activeInHierarchy == false)
timers[childIndex] -= Time.deltaTime;
if(timers[childIndex] < 0)
{
child.SetActive(true);
timers[childIndex] = sec;
}
}
The code won’t support changes in the order of children or removal of child. If you can have this scenario, you can go for a Dictionary<GameObject, float>
instead of a List<float>
Something like this should work
Update(){
foreach(Transform t in transform){
if((t!=transform) && !t.gameObject.activeInHierarchy){
StartCoroutine(LateCall(t));
}
}
}
IEnumerator LateCall(Transform t){
yield return new WaitForSeconds(sec);
t.gameObject.SetActive(true);
}
Just use the transform iterator to get each child, then pass it as a parameter to your coroutine to enable it for you.