[Need Help] Coroutine Issues

I have attempted to get this to work properly but no matter how I place the Coroutine into the code it keeps breaking the game mechanic. This is the closest I gotten to operation but it is still broken because every 2 loops it ignores the wait time. Can someone help me understand why this is please?

public class PowerUp : MonoBehaviour
{
    [SerializeField] float boundry = 1.0f;
    [SerializeField] float minSpeed = 3.0f;
    [SerializeField] float maxSpeed = 5.0f;
    [SerializeField] float minTime = 3.0f;
    [SerializeField] float maxTime = 5.0f;
    [SerializeField] float yPos = 7.0f;

    float xMin;
    float xMax;
    [SerializeField] float startPosX;
    [SerializeField] float moveSpeed;
    [SerializeField] float respawnTimer = 15.0f;

    void Start()
    {
        ViewPortCamera();
        respawnTimer = Random.Range(minTime, maxTime);
        Invoke("BoostPos", respawnTimer);
    }
    void Update()
    {
        if (transform.position.y > -yPos)
        {
            MoveBoost();
        }
        else
        {
            StartCoroutine(Respawn());
        }
    }
    IEnumerator Respawn()
    {
        yield return new WaitForSeconds(respawnTimer);
        while (transform.position.y <= -yPos)
        {
            respawnTimer = Random.Range(minTime, maxTime);
            BoostPos();
        }
    }
    private void MoveBoost()
    {
        transform.Translate(Vector2.down * moveSpeed * Time.deltaTime);
    }
    private void BoostPos()
    {
        moveSpeed = Random.Range(minSpeed, maxSpeed);
        startPosX = Random.Range(xMin + boundry, xMax - boundry);
        Vector2 boostPos = new Vector2(startPosX, yPos);
        transform.position = boostPos;
    }
    private void ViewPortCamera()
    {
        Camera camera = Camera.main;
        xMin = camera.ViewportToWorldPoint(new Vector3(0, 0, 0)).x;
        xMax = camera.ViewportToWorldPoint(new Vector3(1, 0, 0)).x;
    }
}

So someone on another site had told me it was absurd to place a coruotine in this code. So I went back to my original code block but have no Idea how to make it spawn at random intervals everything I try is still broken. Tried both Invoke and Time.time in the Update() but with undesirable results.

public class PowerUp : MonoBehaviour
{
    [SerializeField] float boundry = 1.0f;
    [SerializeField] float minSpeed = 3.0f;
    [SerializeField] float maxSpeed = 5.0f;
    [SerializeField] float minTime = 2.0f;
    [SerializeField] float maxTime = 10.0f;
    [SerializeField] float yPos = 7.0f;

    float xMin;
    float xMax;

    [SerializeField] float startPosX;
    [SerializeField] float moveSpeed;
    [SerializeField] float respawnTime;

    private void Awake()
    {
        ViewPortCamera();
    }
    void Start()
    {
        respawnTime = Random.Range(minTime, maxTime);
        Invoke("BoostPos", respawnTime);
    }
    void Update()
    {
        if (transform.position.y > -yPos)
        {
            MoveBoost();
        }
        else
        {
            BoostPos();
        }
    }

    private void MoveBoost()
    {
        transform.Translate(Vector2.down * moveSpeed * Time.deltaTime);
    }
    private void BoostPos()
    {
        moveSpeed = Random.Range(minSpeed, maxSpeed);
        startPosX = Random.Range(xMin + boundry, xMax - boundry);
        Vector2 boostPos = new Vector2(startPosX, yPos);
        transform.position = boostPos;
    }
    private void ViewPortCamera()
    {
        Camera camera = Camera.main;
        xMin = camera.ViewportToWorldPoint(new Vector3(0, 0, 0)).x;
        xMax = camera.ViewportToWorldPoint(new Vector3(1, 0, 0)).x;
    }
}

First lump of code:

I don’t know why you are calling WaitForSeconds before boosting, surely when

transform.position.y > -yPos

you want to break out of the loop?

Also I can’t understand why you serialize the respawnTimer field, but then overwrite it over and over again with randoms?

But the biggest problem with the first block of code is that you are creating a whole not Respawn() coroutine hundreds of times in a row, which is definately not what you want. Think about what you’re doing: you have respawnTime set to, lets say, 2 seconds. So when you first call StartCoroutine(Respawn()); you make a new coroutine and the first thing it does is nothing, it waits for 2 seconds. During those two seconds, you might have 100 frames in the game, so Update() will make 100 new Respawn() couroutiness. Then each of them eventually all complete to edit respawnTimer, and all call `BoostPos()’, which in turn comlete to edit other variables and all edit you transform.position.

Now, I’ll look at the second block of code:

Again, you are Serializing a field for no good reason. That shouldn’t matter but it’s bad practice because it makes your code purposely confusing!

But I can’t work out what you’re trying to do. Can you comment on your source code (// comments) to help me see what each method is meant to be doing to what object.

Although again, you are calling BoostPos() over and over again in Update() and this means you are directly creating and overwriting many variables, and making the engine behind transform work way too hard

Privacy & Terms