0
\$\begingroup\$

So I have been trying making this game, which changes color of sprites in it. It should only happen when OnMouseDown(). but it is executing every frame and cannot go out of the couroutine. I want the color change to be slower. Please mark the colors should still change.

Please Help,

public class control : MonoBehaviour
{
    public bool startstop = false;
    SpriteRenderer m_SpriteRenderer;
    private void Update()
    {
        StartCoroutine("Changecolor", 3f);
    }
    IEnumerator Changecolor()
    {
        yield return new WaitForSeconds(3);
        if(startstop == true)
        {
            int random = Random.Range(1, 4);
            if (random == 1)
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.blue;
            }
            else if(random == 2)
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.red;
            }
            else if(random == 3)
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.green;
            }
            else
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.yellow;
            }
        }
    }
    private void OnMouseDown()
    {
        startstop = !startstop;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Right now you are creating new Coroutines every frame, which wait for 3 seconds, and then check if the startstop variable is true. This means if you press the mouse button once, startstop will be true and will keep changing the colours every frame. What would be the ideal result ? I'm not sure what you are trying to accomplish. Would you like sprites to change colour once every mouse click? Or just less often? \$\endgroup\$ Commented Oct 7, 2019 at 11:12

2 Answers 2

1
\$\begingroup\$

All you need to do here is move your if statement into the Update function. In your case you would be calling the co routine every frame, and there would be a lot off calls waiting for those 3 seconds to pass and then once the startstop is true, a lot of them would be called. So here, you basically only call it once the startstop is true, and then you immediately change its value to false so no more than 1 call is executed.

public class control : MonoBehaviour
{
    public bool startstop = false;
    SpriteRenderer m_SpriteRenderer;
    private void Update()
    {
        if(startstop){
            StartCoroutine("Changecolor", 3f);
            startstop = false;
        }
    }
    IEnumerator Changecolor()
    {
        yield return new WaitForSeconds(3);
            int random = Random.Range(1, 4);
            if (random == 1)
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.blue;
            }
            else if(random == 2)
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.red;
            }
            else if(random == 3)
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.green;
            }
            else
            {
                m_SpriteRenderer = GetComponent<SpriteRenderer>();
                m_SpriteRenderer.color = Color.yellow;
            }
    }
    private void OnMouseDown()
    {
        startstop = !startstop;
    }
\$\endgroup\$
6
  • 1
    \$\begingroup\$ I like this answer, but perhaps on the startstop = !startstop inside the update function, I think it would be better if it was startstop = false instead. It doesn't really make a difference functionality-wise, because that code can only be reached if startstop is true, but it makes it more readable. \$\endgroup\$ Commented Oct 7, 2019 at 11:13
  • \$\begingroup\$ You're right. I try to change as little as possible from peoples code as not to introduce something they don't quite get, as a lot of code that people post is copied from somewhere else :D \$\endgroup\$ Commented Oct 7, 2019 at 11:16
  • \$\begingroup\$ but I was trying to loop the colors the whole time and not just once. \$\endgroup\$
    – Laurenz
    Commented Oct 7, 2019 at 13:54
  • \$\begingroup\$ In your code the change color method only gets executed once \$\endgroup\$
    – Laurenz
    Commented Oct 7, 2019 at 13:55
  • \$\begingroup\$ I want the color of the sprite to change until I click on it again and not to fast \$\endgroup\$
    – Laurenz
    Commented Oct 7, 2019 at 13:55
0
\$\begingroup\$

The other way would be looping the coroutine instead of calling it multiple times, and stopping it when needed.

public class Control : MonoBehaviour
{
    public bool startstop = false;
    SpriteRenderer m_SpriteRenderer;

    IEnumerator Changecolor() {
        yield return new WaitForSeconds(3);
        int random = Random.Range(1, 4);
        if (random == 1) {
            this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
            this.m_SpriteRenderer.color = Color.blue;
        } else if (random == 2) {
            this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
            this.m_SpriteRenderer.color = Color.red;
        } else if (random == 3) {
            this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
            this.m_SpriteRenderer.color = Color.green;
        } else {
            this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
            this.m_SpriteRenderer.color = Color.yellow;
        }

        this.StartCoroutine("Changecolor", 3f);
    }

    private void OnMouseDown() {
        if (this.startstop) {
            this.StartCoroutine("Changecolor", 3f);
            this.startstop = !this.startstop;
        } else {
            this.StopCoroutine("Changecolor");
            this.startstop = !this.startstop;
        }
    }
}

If this doesn't work you could fix it easily, as I'm at work and cant test it right now ^^

\$\endgroup\$
5
  • \$\begingroup\$ were is the coroutine change color being called \$\endgroup\$
    – Laurenz
    Commented Oct 7, 2019 at 14:22
  • \$\begingroup\$ it still doesn't work sorry \$\endgroup\$
    – Laurenz
    Commented Oct 7, 2019 at 14:23
  • \$\begingroup\$ It's being called from OnMouseDown(), and it will be called again from itself. Then on another OnMouseDown we will call StopCoroutine so it stops calling itself \$\endgroup\$ Commented Oct 7, 2019 at 14:26
  • \$\begingroup\$ how can it be called from Onmousedown() if the startstop is false nothing is being called !!! \$\endgroup\$
    – Laurenz
    Commented Oct 7, 2019 at 14:36
  • \$\begingroup\$ Hahahah well set it to true :D \$\endgroup\$ Commented Oct 7, 2019 at 14:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .