top of page

コルーチン コールバック

こんにちは.

眠い・・・寝不足ダメ絶対...

寝て起きたら一日悩んだことが解決するときもありますからね!笑




今日はコルーチンについてちょっとだけ.

コルーチンって聞いたことありますか?

まぁ色んな環境で使わないことがないくらい有名であり,

便利なものだとは思いますがUnityでも使えます.


書き方は簡単,

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

IEnumerator Test()
{
    Debug.Log("0");
    yield return null;
    //1フレーム待ってから処理が行われる
    Debug.Log("1");
}

IEnumeratorという呪文で処理の開始を少し待つことができます.



//1フレーム待つ
yield return null;

//1秒待つ
yield return new WaitForSeconds(1.0f); 

//処理をここで終わらせる
yield break;

私がよく使うのはこの3つです.

アニメーションやエフェクトを再生したときにそれぞれに応じて時間を取得して

その分遅らせるであったり,

ゲームでシーン遷移にタイムラグを設けたり(星海の眼でも頻繁に使われています)できるのでとても重宝しています.



ちなみに画面フェードアウトでよくやっている処理は


//真っ黒な画像
Image fadeImage;

IEnumerator FadeOut()
{
    Color base = Color.Black;
    //アルファ値0(最初透明)
    base.a = 0;
    
    while(base.a < 1.0f)
    {
        base.a += .1f;
        fadeImage.color = base;
        
        //1フレームごとに少しずつ不透明にしていく
        yield return null;
    }
    
    //真っ暗!
}

こんな感じです.

フェードトランジションに関してはもっとちゃんとした書き方がありそうですが

使い慣れちゃったうえ,今のところ普通に動いちゃってるのでこれを使ってます.



で,ここで思うわけです.

フェードが終わったタイミングでXXしたい・・・


whileループの後にフラグを切り替えて

Update関数の中でフラグが切り替わるのを待つ?

いやいや・・・それはよくない

じゃあどうしよう?













ここでコールバックという概念が出てくるわけですね.

コールバックは実行が終わったら何か値を返すってものです.

例を見てみましょう.


void Start()
{
    StartCoroutine(Test(()=>{
        //処理が終わった!
        Debug.Log("終了!");
    }));
}

IEnumerator Test(System.Action callback)
{
    //3秒待つ
    yield return new WaitForSeconds(3.0f);
    
    callback();
}


なにやらよくわからないカッコとか矢印みたいなものが出てきました.

わけわからーん!って最初は思うかもしれませんが,意外と簡単です.


//関数はこう書く
void Hoge()
{
    Debug.Log("Hoge");
}

//コールバックではこう書く
StartCoroutine(Test(

//↓ここに処理をかく************
()=>{
    Debug.Log("Hoge");
}
//↑********************

));

()=>{ }とかいて,{}の中に処理を書けばいいんだーと思ってもらえれば大丈夫です.

普通の関数を書くときと同じように中をたとえびっしり書いてもらっても問題なく動きます.




なるほど,じゃあコールバックに引数を渡したい場合はどうするの?

たとえばRPGで攻撃をしたときのダメージ計算結果とか・・・


void Battle()
{
    int atk= 10;
    int def = 5;
    StartCoroutine(DamageCalc(atk, def, (damage)=>{
        
        Debug.Log($"{damage}のダメージを受けた!");
    
    }));
}

IEnumerator DamageCalc(int atk, int def, System.Action<int> callback)
{    
    //ダメージ計算は適当です.
    int damage = atk - def;
    
    yield return null;
    
    
    callback(damage)
}

System.Action<返す引数の型>

と書いて

コルーチンの中にcallback(返したい変数など)

と書けばいいんです.

意外と書く量は少なく済みますねー.


()=>{}に慣れるまでは使うのに抵抗があるかもしれませんが

慣れると超便利ですよ.




・ちなみに,処理を待ってから何かする方法として,

こういう手もあります.

IEnumerator Hoge()
{
    var coroutine = StartCoroutine(Test());
    
    yield return coroutine;
    
    //コルーチン処理を待ってから実行
    Debug.Log("HogeHoge!!");
}

正直に言って専門的なことはちんぷんかんぷんな私にとっては

どっちで書こうが良い気はしますが

なーんか落とし穴がありそうなところはちょっと不安です.

どっちも使うときは自己責任で! 笑





ということで今回はコルーチンについて書いてみました.

ゲームをしていて超高速に処理が進んじゃうと嫌な部分って多々ありますから

ぜひ効果的な使い方,表現方法を考えてみてください!


例によっておかしなところなどあればやさしく教えていただけると助かります(^-^;

それでは,アディオス!

閲覧数:570回0件のコメント

最新記事

すべて表示
bottom of page