コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】通常のコルーチンよりも多機能でパフォーマンスにも優れたコルーチン「More Effective Coroutines」紹介($21.60、無料版あり)

概要

2016/8/11 に「More Effective Coroutines」がリリースされました

「More Effective Coroutines」を導入すると、
通常のコルーチンよりも多機能で、
パフォーマンスにも優れたコルーチンが使えるようになります

検証環境

  • Unity 2017.1.1f1
  • More Effective Coroutines 3.00.0

公式マニュアル

http://trinary.tech/category/mec/

比較表(引用)

  Unity MEC Free MEC Pro
yield return を使用
空のコルーチンを
10万回実行するのにかかる時間
110.53ms ~9.62ms ~9.64ms
コルーチンのシングルトンインスタンスの実行
実行中のコルーチンのタイミングの切り替え
CallDelayed、CallPeriodically、CallContinously
ゲームオブジェクトに紐付ける必要がない

更新タイミング(引用)

  Unity MEC Free MEC Pro
Update
Fixed Update
Late Update
Slow Update
Realtime Update
Editor Update
Editor Slow Update
End Of Frame
Manual Timeframe

使い方

using MEC;
using System.Collections.Generic;
using UnityEngine;

public class Example : MonoBehaviour
{
    private void Start()
    {
        // コルーチンを Update のタイミングで実行
        Timing.RunCoroutine( CheckForWin() );

        // コルーチンを FixedUpdate のタイミングで実行
        Timing.RunCoroutine( CheckForWin(), Segment.FixedUpdate );

        // コルーチンを LateUpdate のタイミングで実行
        Timing.RunCoroutine( CheckForWin(), Segment.LateUpdate );

        // コルーチンを SlowUpdate のタイミングで実行
        Timing.RunCoroutine( CheckForWin(), Segment.SlowUpdate );
        
        // 指定されたゲームオブジェクトが死んだ、もしくは非アクティブになったらコルーチンを停止
        Timing.RunCoroutine( CheckForWin().CancelWith( gameObject ) );
    }

    private IEnumerator<float> CheckForWin()
    {
        // 1 フレーム待つ(その1)
        yield return 0;

        // 1 フレーム待つ(その2)
        yield return Timing.WaitForOneFrame;

        // 1 秒待つ
        yield return Timing.WaitForSeconds( 1 );

        // 他のコルーチンの完了を待つ
        yield return Timing.WaitUntilDone( Timing.RunCoroutine( CheckForWin() ) );

        // 他のコルーチンの完了を待つ(MEC Pro 専用)
        yield return Timing.WaitUntilDone( CheckForWin() );

        // WWW の完了を待つ
        yield return Timing.WaitUntilDone( wwwObject );

        // AsyncOperation の完了を待つ
        yield return Timing.WaitUntilDone( asyncOperation );

        // CustomYieldInstruction の完了を待つ
        yield return Timing.WaitUntilDone( customYieldInstruction );
 
        // 指定されたデリゲートが true を返すまで待つ
        yield return Timing.WaitUntilTrue( functionDelegateThatReturnsBool );
        
        // 指定されたデリゲートが false を返すまで待つ
        yield return Timing.WaitUntilFalse( functionDelegateThatReturnsBool );
    }
}

SlowUpdate

MEC のコルーチンには SlowUpdate と呼ばれる更新ループが存在します
SlowUpdate は1秒間に7回実行されます
SlowUpdate は UI の表示の更新などに効果的です
SlowUpdate の実行レートは下記のように変更できます

Timing.Instance.TimeBetweenSlowUpdateCalls = 3f;

タグ

MEC のコルーチンにはタグを紐付けることができます
タグを紐付けたコルーチンは KillCoroutine や KillAllCoroutines で
一括で削除することが可能です

using MEC;
using System.Collections.Generic;
using UnityEngine;

public class Example : MonoBehaviour
{
    private void Start ()
    {
        Timing.RunCoroutine( Message( 1, "ピカチュウ" ), "message1" );
        Timing.RunCoroutine( Message( 2, "カイリュー" ), "message1" );

        Timing.RunCoroutine( Message( 3, "ヤドラン" ), "message2" );
        Timing.RunCoroutine( Message( 4, "ピジョン" ), "message2" );

        Timing.KillCoroutines( "message2" );
    }

    private IEnumerator<float> Message( float time, string text )
    {
        yield return Timing.WaitForSeconds( time );

        Debug.Log( text );
    }
}

CallDelayed と CallContinously

Timing クラスには、CallDelayed と CallContinously という
2つのヘルパー関数が含まれています

// 2 秒後にコルーチンを実行
Timing.CallDelayed( 2, () => Timing.RunCoroutine( Hoge() ) );

// 4 秒ごとに指定されたデリゲートを実行
Timing.CallContinuously( 4, () => Hoge() );

例外

MEC はデフォルトでは例外をコンソールに出力して、
例外を投げたコルーチンは終了しますが、
例外が発生したときの処理はカスタマイズできます

using MEC;
using System;
using UnityEngine;

public class Example : MonoBehaviour
{
    private void Start ()
    {
        Timing.Instance.OnError = OnError;

    }

    private void OnError( Exception exception )
    {
        ...
    }
}

無料版

「More Effective Coroutines」には、いくつかの機能が制限された無料版も存在します

関連記事