Неправильная работа оператора в Unity

302
17 июля 2017, 13:27

Оператор должен работать так: если случайное число будет равно нулю (0), то вложенный оператор увеличивает значение переменной timeRemaining до 40, если нет — то останавливать все на три секунды. И потом повторить снова. Вместо этого срабатывает и if и else и все вперемешку. Подскажите, как исправить?

void Update() {
    int rand = Random.Range(0, 2);
    if (rand == 0) {
        if (timeRemaining < 40) {
            timeRemaining += Time.deltaTime * 5f;
            Debug.Log ("random " + (byte)timeRemaining);
        }
    } else {
        System.Threading.Thread.Sleep(3000);
    }
}
Answer 1

Мне кажется надо (можно, во всяком случае) сделать так:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rangee : MonoBehaviour {
    private float timeRemaining = 0f;
    private int workLimit = 10;
    private bool flagToStopWork = false;
    void Start() {
        StartCoroutine(WaitALittleBit(0));
    }
    IEnumerator WaitALittleBit(int seconds) {     
        Debug.Log("WaitALittleBit start");
        timeRemaining = 0;
        flagToStopWork = true;
        yield return new WaitForSeconds(seconds);
        Debug.Log("WaitALittleBit end");
        flagToStopWork = false;        
    }
    void Update() {            
        if (timeRemaining > workLimit) {
            Debug.Log("reset all");            
            int rand = Random.Range(1, 3);
            StartCoroutine(WaitALittleBit(rand));
        }
        if (flagToStopWork)
            return;
        timeRemaining += Time.deltaTime * 5f;
        Debug.Log("do work " + (byte) timeRemaining);        
    }
}

Тут используются Корутины, корутины и еще раз корутины.

В чем смысл кода:

Мы делаем какую-то работу (в данном случае делаем что-то пока timeRemaining < workLimit). Делаем мы это только в одном случае: если нам позволяет специальный флаг flagToStopWork. Если он true, то мы просто не пускаем логику выполнения дальше, то есть пишем return, ибо нефиг.

Также смотрим, если вдруг timeRemaining превысило лимит, то вот тут-то запускаем корутину, которая выполняется асинхронно и, что важно НЕ останавливает весь главный поток!!! Эта корутина как раз управляет флагом, устанавливая его значение в true, чтобы в методе Update не выполнялась работа, а после нескольких секунд (в данном случае их задает как раз-таки Random.Range) вновь делает флаг false, что запускает опять работу в методе Update. Также, попутно, она (корутина) сбрасывает timeRemaining в ноль.

Answer 2

Все проще:

using UnityEngine;
public class Test : MonoBehaviour
{
    float timeRemaining;
    float timer;
void Update()
{
    float td= Time.deltaTime;
    if (timer <= 0f)//ждем таймер
    {
        if (timeRemaining < 40)
        {
            timeRemaining += td * 5f;
            Debug.Log("timeRemaining=" + (byte)timeRemaining);
        }
        else//создаем новый таймер
        {
            timeRemaining = 0f;
            timer = UnityEngine.Random.Range(1f, 3f);//UnityEngine.Random.Range(1, 3); для целых
            Debug.Log("wait "+ timer + " seconds");
        }
    } else timer -= td;//уменьшаем таймер каждый кадр

 }
}

Ну или если прям хочется корутин:

using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour
{
    float timeRemaining;
    private void Start()
    {
        StartCoroutine(TestCor());
    }
    IEnumerator TestCor()
    {
        while (true)
        {
            timeRemaining = 0f;
            yield return new WaitForSeconds(UnityEngine.Random.Range(1f, 3f));
            while(timeRemaining < 40)
            {
                timeRemaining += Time.deltaTime * 5f;
                Debug.Log("timeRemaining=" + (byte)timeRemaining);
                yield return null;
            }
        }
    }
}
READ ALSO
C# Отличить одну флешку от другой

C# Отличить одну флешку от другой

Стоит задача засечь подключение определенной флешки к устройству и копировании туда данных

357
&ldquo;Открыть с помощью&rdquo; моей программы. Как сделать?

“Открыть с помощью” моей программы. Как сделать?

В Windows при двойном клике на фото открывается программа для просмотра фотографийКак мне сделать это в своей программе? Чтобы при двойном клике...

300
Потоковая передача HTML5 video (.webm) на rtmp сервер (.flv)

Потоковая передача HTML5 video (.webm) на rtmp сервер (.flv)

ЗдравствуйтеВстала задача записывать видео из браузера и передавать на rtmp сервер

412
Может ли Google специально делать свои сервисы (например YouTube) тормознутыми не в их браузере (Chrome)? [требует правки]

Может ли Google специально делать свои сервисы (например YouTube) тормознутыми не в их браузере (Chrome)? [требует правки]

JS у них во всех сервисах обфусцирован, поэтому я даже не пытался разобратьсяТак же могут использоваться и какие либо сложные серверные технологии

306