Оператор должен работать так: если случайное число будет равно нулю (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);
}
}
Мне кажется надо (можно, во всяком случае) сделать так:
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 в ноль.
Все проще:
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;
}
}
}
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей