2013-03-05 2 views
0

Я изучаю, как использовать функцию Unityscript WaitForSeconds, и раньше у нее был успех. Но теперь я пытаюсь использовать его в сценарии, который, как предполагается, когда здоровье объекта достигнет 0, переместите объект (окно в этом случае) за кадром, а затем через определенное количество секунд он снова появится в случайном положении на экране, и установите для здоровья значение по умолчанию. До сих пор я знаю:Проблемы с WaitForSeconds

function Update() 
{ 
    if(health <= 0) 
    { 
     RespawnWaitTime(); 
     var position = Vector3(Random.Range(-6,6),Random.Range(-4.5,4.5),0); //this is the onscreen range 
     transform.position = position; 
     health = 2;     
    } 
} 

function RespawnWaitTime() 
{ 
    var offScreen = Vector3(10,10,0); 
    transform.position = offScreen; 
    yield WaitForSeconds(2); 
} 

Однако, это не дотягивает до 2 секунд. Коробка просто переходит на новое место, как будто функции там не было. Я считаю, что он идет в офшорную позицию, но просто прыгает прямо назад, не дожидаясь. Я проверил, чтобы увидеть, если это применение ждать вообще, изменив некоторые из кода:

function RespawnWaitTime() 
{ 
    var offScreen = Vector3(10,10,0); 
    transform.position = offScreen; 
    print("I'm over here!"); 
    yield WaitForSeconds(2); 
    print("I'm coming back!"); 
} 

Первый бит текста заканчивается печать сразу, то через две секунды, появится второй бит текста а также, как и ожидалось. Так почему же ожидания не относятся к коробке? Спасибо за вашу помощь.

+0

Я не знаю единственного слова, но позвольте мне угадать: 'WaitForSeconds' принимает обратный вызов, который вызывается после указанного таймаута. Вот как ведет себя 'setTimeout' в Javascript. –

ответ

1

Я подозреваю, что WaitForSeconds асинхронно, поэтому, когда обновление вызывает RespawnWaitTime, тогда RespawnWaitTime немедленно возвращается. Не могли бы вы попробовать следующий код, чтобы увидеть, как ведет себя WaitForSeconds?

function Update() { 
     print("1 in update before calling respandwaittime"); 
     RespawnWaitTime(); 
     print("3 in update after calling respandwaittime"); 
} 

function RespawnWaitTime(){ 
    print("2 in in respainwaittime before calling waitforseconds"); 
    yield WaitForSeconds(2); 
    print("4 in in respainwaittime after calling waitforseconds"); 
} 

Поскольку выход был 1,2,3,4 (как и ожидалось) можно перепрограммировать так:

function Update() { 
    if(health <= 0){ 
     recover(); 
     return; 
    } 
} 

function recover(){ 
    var offScreen = Vector3(10,10,0); 
    transform.position = offScreen; 
    yield WaitForSeconds(2); 
    //this is the onscreen range 
    var position = Vector3(Random.Range(-6,6),Random.Range(-4.5,4.5),0); 
    transform.position = position; 
    health = 2;     
} 
+0

Он печатал 1,2,3 сразу после запуска, а затем через пару секунд печатал 4. Я не уверен, что это будет означать для того, как он себя ведет. Я довольно новичок в кодировании. – Toushinu

+0

Обновлен мой ответ с кодом, который мог бы решить вашу проблему. – HMR

+0

Кажется, что я не могу получить во время функции Update. «Update() не может быть сопрограммой« это то, что говорит мне ошибка ». – Toushinu

0

Вы должны использовать "выход RespawnWaitTime();" - в противном случае функция, которая вызвала его, будет продолжать выполняться одновременно с выполнением сопрограммы.

Устранение сопрограммы приостанавливает выполнение кода, который его вызывал, до завершения сопрограммы, после чего исходный код возобновляется с строки, следующей за оператором yield.

ОДНАКО - как вы не можете поставить заявления урожая в Update() - Вы должны были бы назвать промежуточную функцию, что-то вроде следующего:

function Update() 
{ 
    if(health <= 0) 
    { 
     Respawn();    
    } 
} 

function Respawn() 
{ 
    yield RespawnWaitTime(); 
    var position = Vector3(Random.Range(-6,6),Random.Range(-4.5,4.5),0); 
    transform.position = position; 
    health = 2; 
} 

function RespawnWaitTime() : IEnumerator 
{ 
    var offScreen = Vector3(10,10,0); 
    transform.position = offScreen; 
    yield WaitForSeconds(2); 
} 

Примечание Я также добавил «: IEnumerator» в RespawnWaitTime() - если вы этого не сделаете, консоль напечатает ошибку для оператора yield, который его вызывает. Насколько я понимаю, код, вероятно, будет работать, несмотря на то, что отображается ошибка компиляции, но я предпочитаю не рисковать ;-)

Смежные вопросы