c# - Using coroutines and loops to have a repeatable delay in Unity? - Stack Overflow

I'm very new to coding and am trying to make a basic simon says game. Currently I have a cube that

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];
       

   }

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];
       

   }
Share Improve this question edited Nov 17, 2024 at 19:01 derHugo 91.4k9 gold badges91 silver badges135 bronze badges asked Nov 17, 2024 at 6:42 Jelita PurchesJelita Purches 11 silver badge 4
  • 3 first, you need to show the actual errors. "Crashes a lot" is not good enough. Second, i in callList[i] is undefined – Felix Commented Nov 17, 2024 at 6:46
  • so, why are you starting the delay a number of times? it doesnt pass "i" into it, they will also run at roughly the same time because all 3 start at say 0 seconds and 3 seconds later all 3 will run. You almost certainly wanted a for i is 0 to < callList.Length do wait 3 seconds, set material loop. in your coroutine.. and delay would then be a bad name for it. – BugFinder Commented Nov 17, 2024 at 12:00
  • I guess the loop should rather go into your coroutine instead .. or rather directly go with InvokeRepeating instead – derHugo Commented Nov 17, 2024 at 18:51
  • It looks like you're pretty new to StackOverflow. Welcome! This question is probably close to being answerable but needs some help. Please read stackoverflow/help/how-to-ask and edit your question to make it so people can help you better. – Adam B Commented Nov 18, 2024 at 4:33
Add a comment  | 

1 Answer 1

Reset to default 1

(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;
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745636753a4637441.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信