読者です 読者をやめる 読者になる 読者になる

非同期処理中にUnityAPIを使えるSpicyPixel Concurrency Kitのご紹介

AdventCalendar UnityAssets

これは、Unity2 Advent Calendar 2015の4日目の記事です。

3日目は、geekdrumsさんの「Unityで音楽同期したアニメーションを作る」でした。

本日は非同期処理向けのアセットを紹介します。


Unityはシングルスレッドで動作します。

非同期っぽい処理を作るには、コルーチンと呼ばれる方法を使います。

これはUnityがフレーム毎に処理を行うときに、そこに混ぜることで擬似的にマルチスレッドのような概念を実現しています。

しかし、別スレッドで実行する処理が重いと、メインの処理速度にも影響が出てしまいます。

(実際、WWWクラスを使って待ち時間のかかる処理をさせたら、コルーチンを使っていても画面が固まったことがありました)


以上がUnityのスレッドに対する私の理解ですが、間違っていたらご指摘くださいm(_ _)m



このような問題を解決してくれるのが、Spicy Pixel Concurrency Kitというアセットです。



詳しい原理については理解できてませんが、この仕組みを使うと、マルチスレッドのような非同期処理が実現できます。


では、使い方です。


使い方


まずはAssetStoreより入手し、Importします。

f:id:Takyu:20151202180111p:plain


代表的な処理例をc#で書いてみます。ここではdelegateを使って非同期処理を実現しています。

using SpicyPixel.Threading;
using SpicyPixel.Threading.Tasks;

public class TestClass : ConcurrentBehaviour {   /*(1)*/

delegate void ThreadFunction();/*(2)*/
static ThreadFunction threadFunction;/*(2)*/

public void asyncFunction(){
	threadFunction = new ThreadFunction(testFunction); /*(2)*/
	threadFunction.BeginInvoke(new AsyncCallback(functionOnAsync),DateTime.Now); /*(3)*/
}

private void functionOnAsync(){
/*非同期で実行したい処理を書く*/

/*Debug.Logなど、UnityAPIを含んだ関数を呼び出す*/
taskFactory.StartNew(functionWithUnityAPI()); /*(4)*/

}

private void CallbackAndShowContents(IAsyncResult ar){  /*(5)*/
/*コールバックを受けて実行したい処理を書く*/
}


(1) ConcurrentBehaviourクラスを継承

多くの場合は、MonoBehaviourですが、このアセットを使うとき、非同期処理したいクラスは、これをくっつけて宣言します。


(2) delegete宣言

SpicyPixel Concurrency Kitにとって必須ではありませんが、非同期処理実行のために使いました。
Threadクラスを呼ぶ方法でも大丈夫です。


(3) 非同期処理の開始

delegateを使うと、BeginInvokeメソッドの引数で宣言した関数が非同期で実行されます。


(4) 非同期処理中のUnityAPIの実行

本稿のメインはこれですね。非同期処理の中でUnityAPIを含んだ関数を呼ぶとき、taskFactory.Startnewメソッドの引数とします。


(5) コールバック関数

非同期処理が終わった時に呼ばれる関数です。この中に処理を書いておけば非同期処理の終了をきっかけに処理を続けることができます。


ここで紹介したのは使い方の一例です。
他にも色々ありますので、ご興味ある方は本家サイトのLearnをご参照ください。


明日はYOSHIOKA-Koさんによる、「uGUIのAnchorを使ったアニメーションの演出」です。