Reputation: 1
I'm very new to coding and am trying to make a basic simon says game. Currently I have a cube that is supposed to change the material after a few seconds however I'm really struggling getting any sort of timer to loop so that the cube changes materials, pauses, changes materials again.
this is a part of the code I have currently. At the moment, it crashes a lot and I'm fairly certain it's thanks to my while loop messing it up.
private void Awake()
{
while(i < 3)
{
StartCoroutine(Delay());
i++;
}
}
private IEnumerator Delay()
{
yield return new WaitForSeconds(3);
ChangeColour();
}
void ChangeColour()
{
// we want to change simon's colour
simon.GetComponent<Renderer>().material = callList[i];
}
Upvotes: -1
Views: 48
Reputation: 90813
(Despite as mentioned the fact that your code wouldn't compile as it stands.)
What you are currently doing is starting 3 Coroutines at the same time that will basically all wait the same amount of time and then 3 seconds later all change the material "at the same time".
From your code attempts I would assume you are looking for something like e.g.
[SerializeField] Renderer simon;
[SerializeField] Material[] callList;
[SerializeField] float delay = 3f;
// Yes, you can do this and Unity will run this as a Coroutine implicitly
private IEnumerator Start()
{
var wait = new WaitForSeconds(delay);
// This will iterate ONCE through the array
// and change the material in "delay" seconds interval
foreach(var material in callList)
// alternatively
//for(var i = 0; i < callList.Length; i++);
//{
// var material = callList[i];
{
yield return wait;
simon.material = material;
}
}
Or alternatively if you rather want to infinitely wrap around the materials
[SerializeField] Renderer simon;
[SerializeField] Material[] callList;
[SerializeField] float delay = 3f;
private IEnumerator Start()
{
var wait = new WaitForSeconds(delay);
var i = 0;
// This is fine in an Enumerator as long as you yield somewhere
while(true)
{
yield return wait;
simon.material = callList[i];
// increase by one but wrap around at the end of the array
i = (i + 1) % callList.Length;
}
}
or alternatively to that as said you can also go without a Coroutine and do e.g.
[SerializeField] Renderer simon;
[SerializeField] Material[] callList;
[SerializeField] float delay = 3f;
int currentIndex;
private void Start()
{
InvokeRepeating(nameof(ChangeColor), delay, delay);
}
private void ChangeColor()
{
simon.material = callList[i];
currentIndex = (currentIndex + 1) % callList.Length;
}
Upvotes: 1