2016-08-14 13 views
2

私はプログラミングに非常に新しいです。私はここでは非常にばかげた間違いがあると感じています。しかし、誰も私を説明することができます、なぜなら、2秒間の遅延を伴う4つのメッセージの代わりに、私は瞬間的に最後のメッセージを表示するだけです。私の「利回り」が働いていないのはなぜですか?

using UnityEngine; 
using System.Collections.Generic; 
using System.Collections; 
using System.Linq; 
using UnityEngine.UI; 

public class Wait : MonoBehaviour { 

    private int i = 0; 
    public string[] message; 

    [SerializeField] 
    private Text toText; 

    public IEnumerator Message(float waitTime) 
    { 
     toText.text = message[i]; 
     i++; 
     yield return new WaitForSeconds(waitTime = 2f); 
    } 

    void Start() 
    { 
     StartCoroutine(Message(i)); 
     StartCoroutine(Message(i)); 
     StartCoroutine(Message(i)); 
     StartCoroutine(Message(i)); 
    } 
} 
+1

キーワードを指定すると、メソッドが遅延実行されます。したがって、 'Enumerator.MoveNext()'を呼び出すときにのみ実行されます。これは決して呼び出されません(例えばforループを使用するため)。 – HimBromBeere

+0

@HimBromBeereは 'StartCoroutine'の仕事ではありませんか? –

答えて

0
void Start() 
{ 
    StartCoroutine(Message(i)); 
    StartCoroutine(Message(i)); 
    StartCoroutine(Message(i)); 
    StartCoroutine(Message(i)); 
} 
:あなたはまた、私は降伏リターンがどのように動作するかに慣れてくるために、次のテストを実行することをお勧め yield return Wait https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html

後の行動を見ることができるドキュメントの例では

私はそれがあなたが考えるべきことをしているとは思わない。これは各StartCoroutineが終了するのを待つことはなく、次にStartCoroutineを呼び出すでしょう。

最初StartCoroutine(Message(i));呼び出しがMessage機能を開始します:

これは何が起こるかです。 コードがyield return new WaitForSeconds(waitTime = 2f);のコード行に一致すると、Start()関数にジャンプします。

次のStartCoroutine(Message(i));が呼び出され、同じことが再び起こります。限り、あなたはyield return new WaitForSecondsyield return null;、またはyield returnを持っているように何史上YieldInstruction実装され、実行はStartCoroutine関数が呼び出された中に、その非コルーチン関数に戻ります

非コルーチン関数からコルーチン関数を呼び出し、他のコードを実行し続けます。

コルーチンが別のコルーチンを終了するのを待たせるには、別のコルーチン関数からStartCoroutine(Message(i));関数呼び出しを行います。これにより、各コルーチン関数の呼び出しをyieldにすることができます。これは連鎖コルーチンと呼ばれます。

yieldコルーチン関数呼び出しを呼び出すには、yield returnStartCoroutine関数の前に置きます。今yield return StartCoroutine(Message(i));

public class Wait : MonoBehaviour { 
    private int i = 0; 
    public string[] message; 

    [SerializeField] 
    private Text toText; 

    public IEnumerator Message(float waitTime) 
    { 
     // toText.text = message[i]; 
     i++; 
     yield return new WaitForSeconds(waitTime = 2f); 
    } 

    void Start() 
    { 
     StartCoroutine(startMessage()); 
    } 

    IEnumerator startMessage() 
    { 
     yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns 
     yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns 
     yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns 
     yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns 
    } 
} 

、各StartCoroutine(Message(i));コールは、最初の1が終了するまで待機します。これを行うには、常にboolean変数を使用できますが、yieldStartCoroutineコールよりはるかに良いです。

0

StartCoroutineMessageから列挙子を実行しますので、テキストが瞬時に設定されている理由があります。

最初に起こるのは、テキストの設定とインクリメントiです。それが行われた後にのみ、WaitForSecondsが返されます。その時点でStartCoroutineMessageの実行を一時停止します。

yield returnの後ろに行がある場合は、2秒後にその効果が見られるはずです。

IEnumerator MessageOuter() { 
    Console.WriteLine("outer 1"); 
    var inner = MessageInner(); 
    Console.WriteLine("outer 2"); 
    return inner; 
} 
IEnumerator MessageInner() { 
    Console.WriteLine("inner 1"); 
    yield return new WaitForSeconds(1); 
    Console.WriteLine("inner 2"); 
    yield return new WaitForSeconds(1); 
    Console.WriteLine("inner 3"); 
} 
void Start() { 
    Console.WriteLine("start 1"); 
    var outer = MessageOuter(); 
    Console.WriteLine("start 2"); 
    StartCoroutine(outer); 
    Console.WriteLine("start 3"); 
} 
関連する問題