Остановить метод от выполнения - PullRequest
0 голосов
/ 02 октября 2019

Итак, у меня есть метод смены цвета, который непрерывно меняет цвет моих спрайтов. Моя проблема заключается в том, что я хочу приостановить его, когда я выполняю метод OnMouseDown ().

Я пробовал это с оператором if и return. Я также попробовал это с логическим значением, но это не работает.

       public class colorchange : MonoBehaviour
       {
        public int color;

private SpriteRenderer _mySpriteRenderer;
private float _timeBetweenChanges = 1f;

void Start()
{
    _mySpriteRenderer = GetComponent<SpriteRenderer>();
    InvokeRepeating("ChangeColor", 0F, _timeBetweenChanges);
}

void Update()
{
    // not executed
}

void ChangeColor()
{
        color = Random.Range(1, 5);
        if (color == 2)
        {
            _mySpriteRenderer.color = Color.blue;
        }
        if (color == 3)
        {
            _mySpriteRenderer.color = Color.red;
        }
        if (color == 4)
        {
            _mySpriteRenderer.color = Color.yellow;
        }




}
private void OnMouseDown()
{
  // the Changecolor method should be paused in this one
}
}

Ответы [ 3 ]

2 голосов
/ 02 октября 2019

Другая альтернатива CancelInvoke, как упомянуто в комментариях, заключается в использовании bool.

public class colorchange : MonoBehaviour {

private bool canChangeColor;

//...

private void ChangeColor() {
   if (!canChangeColor) {
       // You can even do something here if you like.
       return;
   }
   // ...
}

private void OnMouseDown(){
   canChangeColor = false;
}
}

Хотя я бы настоятельно рекомендовал вместо этого использовать CancelInvoke, если только вам это не нужносделать что-то, если он не может изменить цвет.

1 голос
/ 02 октября 2019

Как упоминалось ранее, CancelInvoke и boolean flag являются опциями.

Однако я предпочитаю / предлагаю другой подход.

Измените ваш метод на обычную.

public class colorchange : MonoBehaviour
{
    public int color;

    private SpriteRenderer _mySpriteRenderer;
    private float _timeBetweenChanges = 1f;
    private Coroutine _colorRoutine;

    void Start()
    {
        _mySpriteRenderer = GetComponent<SpriteRenderer>();
        _colorRoutine = StartCoroutine(ChangeColor());
    }

    IEnumerator ChangeColor()
    {
        while (true)
        {
            color = Random.Range(1, 5);
            if (color == 2)
            {
                _mySpriteRenderer.color = Color.blue;
            }
            else if (color == 3)
            {
                _mySpriteRenderer.color = Color.red;
            }
            else if (color == 4)
            {
                _mySpriteRenderer.color = Color.yellow;
            }

            yield return new WaitForSeconds(_timeBetweenChanges);
        }
    }

    private void OnMouseDown()
    {
        StopCoroutine(_colorRoutine );
    }
}

Я предпочитаю такой подход, поскольку вы можете сохранить ссылку на процедуру и даже изменить время задержки без остановки / запуска.

Кроме того, вы не зависите от строки, соответствующей имени метода, и можете передавать дополнительные параметры при использовании сопрограммы, а не метода Invoke.

0 голосов
/ 02 октября 2019

Ну, это начинает казаться, что вы на самом деле не хотите использовать OnMouseDown, потому что вы не можете или не хотите прикреплять коллайдер к объекту, по которому щелкаете, или вы хотите, чтобы щелчок мыши обнаруживался в любом месте,В таком случае я рекомендую использовать Input.GetMouseButtonDown(0) для обнаружения щелчка мышью в любом месте. Я также рекомендую использовать сопрограмму, чтобы использовать удобные инструменты, такие как WaitUntil:

public class colorchange : MonoBehaviour
{
    public int color;        
    public float delaySeconds = 1f;
    IEnumerator changeColorCoroutine;

    SpriteRenderer mySprite;

    public bool doChangeColor;

    void Start()
    {
        // cache result of expensive GetComponent call
        mySprite = GetComponent<SpriteRenderer>();

        // initialize flag
        doChangeColor = true;

        // create coroutine
        changeColorCoroutine = ChangeColor();

        // start coroutine
        StartCoroutine(changeColorCoroutine);
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // toggle doChangeColor
            doChangeColor = !doChangeColor;
        }
    }

    IEnumerator ChangeColor()
    {
        WaitUntil waitForFlag = new WaitUntil( () => doChangeColor);

        while (true)
        {
            yield return waitForFlag;

            Debug.Log("Hello");
            color = Random.Range(1, 5);

            // switch for neater code
            switch (color)
            {
            case 2:
                mySprite.color = Color.blue;
                break;

            case 3:
                mySprite.color = Color.red;
                break;

            case 4:
                mySprite.color = Color.yellow;
                break;
            }

            yield return new WaitForSeconds(delaySeconds);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...