Changing bool with a coroutine timer

Ho can i change a bool from true to false with a coroutine as a timer every few seconds?
Battling with it, here is my code, ignore the last few lines on the coroutine, i was just experimenting.

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

public class SoldierController : MonoBehaviour
{
    public int secondsToWalk;
    public float walkingSpeed;
    private bool facingRight = true;
    private float oldPosition = 0.0f;


    private void Start()
    {
        oldPosition = transform.position.x;
    }
    void Update()
    {
        SoldierWalks();
        FlipSoldier();
       
        StartCoroutine(SetWalkDirection());
    }

    void FlipSoldier()
    {
        Vector3 characterScale = transform.localScale;
        if (transform.position.x < oldPosition)
        {
            characterScale.x = -3f;
            facingRight = false;
        }

        if (transform.position.x > oldPosition)
        {
            characterScale.x = 3f;
            facingRight = true;
        }

        oldPosition = transform.position.x;
        transform.localScale = characterScale;
    }

    void SoldierWalks()
    {
        if (facingRight)
        {
            transform.Translate(Vector2.right * Time.deltaTime * walkingSpeed);
        }

        if (!facingRight)
        {
            transform.Translate(Vector2.right * Time.deltaTime * -walkingSpeed);
        }
    }

    private IEnumerator SetWalkDirection()
    {
        yield return new WaitForSeconds(secondsToWalk);
        facingRight = false;
        if (facingRight == false)
        {
            facingRight = !facingRight;
        }
    }
}
while(gameObject.activeInHierarchy == true)
{
   yield return new WaitForSeconds(delay);

   facingRight = !facingright;
}

Uhm, this code:

facingRight = false;
if (facingRight == false)
{
    facingRight = !facingRight;
}

is a very complicated way of doing

facingRight = true;

You said you wanted to set it to false? what’s the point of the if statement and the toggling then?

Apart from that you start a new coroutine every frame. That means at a framerate of say 60 frames per second (assuming yoursecondToWalk value is non-zero) you would have at least 60 coroutines running in parallel, each just setting your facingRight variable to true once its finished. Since you just want to flip the boolean every couple of seconds, all you have to do is start your coroutine once in Start. And change the coroutine to:

private IEnumerator SetWalkDirection()
{
    while (true)
    {
        yield return new WaitForSeconds(secondsToWalk);
        facingRight = !facingRight;
    }
}

So this single coroutine instanec which you start only once inside Start would simply keep running forever. All it does is waiting for the specified time and then flip the boolean.

Note your secondsToWalk variable currently is an integer. You really should define this variable as a float. WaitForSeconds expects a float anyways. With a float you can actually specify something like 0.5 or 1.25 seconds, not just whole numbers.

Though you have another issue. You have a strange circular dependency in your “FlipSoldier” method and your “SoldierWalks” method. SoldierWalks moves either left or right depending on the boolean. However FlipSoldier will change the boolean based on how the object moved. This doesn’t make much sense at all and could cause weird behaviour which completely depends on the execution order of that code. What’s the point of this? If you just want to move the character in one direction and have it turn around after some time and walk the other way, you should simply set the scale also based on the boolean variable and not on the relative movement of the last frame.

So your FlipSoldier method may should look like this

void FlipSoldier()
{
    Vector3 characterScale = transform.localScale;
    if (facingRight)
        characterScale.x = 3f;
    else
        characterScale.x = -3f;     transform.localScale = characterScale;
}

Thanks bunny thats working great. So if you start a coroutine it keeps running? I thought it would only run once, thats why i put it in update. Thanks for all your help guys. Appreciated!

A coroutine only runs once. This one however never finishes since it has a while loop in it ^^. Though coroutines run independent from your “normal” code. When you call StartCoroutine you create a new coroutine that is handled inside Unity.

If you want to learn more about coroutines, how they work and what they actually represent, I’ve written a quite detailed explanation over here.

Thanks bunny, appreciate it