FreelyApps

個人によるアプリ開発の日記です。アプリの収入だけで生活できるようになるのが目標です。UnityでAndroid向けのゲームアプリを作成しています。


    アプリ『トランプ・ジン・ラミー』を公開しました。
    Android/iOS https://goo.gl/PYKFYG

    タグ:コルーチン

      このエントリーをはてなブックマークに追加 Clip to Evernote
    以前、同じ内容で記事を書いたのですが、より良い方法がUnity5.3では行えるようです。

    rn-custom_coroutine
    Unity5.3で新しく使えるようになったカスタムコルーチンというものを使います。 公式の説明を見るとCustomYieldInstructionクラスを継承して、keepWaitingプロパティのgetをオーバーライドすれば新しいyieldオペレーションが作れます。
    yieldオペレーションとは、yield return ~とするときの~の処理のことを言っているのだと思います。(この記事ではそうだと思って書くことにします。)
    keepWaitingがtrueであればyieldオペレーションが処理を返さず継続し、falseになると処理を抜けます。このプロパティにDebug.Logを仕込んだところ毎フレーム呼ばれていたので、コルーチンで無限ループ内にyield return 0;というような書き方で行うのと同じと考えて良いでしょう。

    以前の方法のあまり良くない点は、処理をクラス内に書いていなければいけなかったため、あるクラスのstaticメソッドにするかクラス内での利用しかできないようになっていたことです。色々なところから自由に呼び出すということを考えると、その処理は独立した1つのクラスになっている方が見通しが良いのでそうすべきだと思っていました。
    メソッドに処理がある場合は、呼び出し方がStartCoroutineを介するというのもいまいちだと思います。StartCoroutineを使うと、渡すパラメータの個数の制約があること、わずかにコードが増えること、文字列での呼び出しだとエディター上で編集しにくいことが良くないです。
    新たな方法では導入が手間ですが、その後の作業を減らしてくれるため良い方法だと思います。WaitUntilやWaitWhileを使っても同じことができますが、よくある同じ処理をいちいち書くのは無意味なので、以下のようにカスタムコルーチンを作りました。

    上のソースは、ある時間処理を待たせるがスキップも可能であるというyieldオペレーションになります。使い方は
    yield return new SkippableWaitForSeconds(10, () => Input.GetMouseButtonUp(0));
    のようにします。この例だと10秒待つ処理であり、もしその間にマウスの左ボタンが上げられたらスキップするということになります。
    スキップするかの判定を外から渡せるため、色々と使えるようになっています。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    アニメを作る方法はいくつかありますが、ここではコルーチンを使った方法を想定しています。コルーチンは逐次的に進んでいく処理を作ることが簡単なので、アニメーションを実装するには便利な方法です。無限ループを持つことで毎フレーム処理することも可能です。

    アニメを作った後でスキップしたいということがあると思います。特に頑張って作ったアニメは時間がかかりがちなので、ゲームのテンポを悪くしてしまいます。画面をタップしたり、タッチしている間はアニメをスキップするといったことを望まれることでしょう。
    スキップ処理はかなり面倒なことが多いです。本来処理すべき内容を行わないのですから当然です。
    処理を先に行い、表示だけを変化させるアニメを作る設計がふつうかと思います。アニメする状態とアニメが終わったときの状態を作り、最後にはアニメが終わったときの状態を通るように設計すれば、スキップの実装はそれほど難しくはありません。アニメ状態中に強制的にアニメが終わった状態に遷移させれば、スキップになります。
    単純なアニメはそれで可能ですが、色々絡み合ってしまうと非常に難しくなります。

    最も単純なアニメーションは待つことです。表示して、少し待つということを繰り返すだけでも躍動感は出ます。結果表示とかでよくあるものです。
    これを簡単に作るにはWaitForSecondsを使います。
    anime


    上のコードでは、WaitForSecondsを呼び出し1.0秒待機しています。表示するというコメントのところに何らかの処理を書けば良いわけです。
    WaitForSecondsを呼び出すと処理が止められてしまうので、これではスキップができません。スキップを行うには入力の受付が必要なので、毎回処理するところが必要なのです。

    スキップを行えるよう入力を受け付けるコルーチンを書いてみました。 
    コルーチンの中で新たなコルーチンを呼び出すということをしています。yield returnにStartCoroutineを渡すと、渡したコルーチンが終わるまで処理が遅延されます。SkippableWaitがスキップが行える「待ち」の処理です。WaitForSecondsと同じように使えるので、使いやすいと思います。

    このページのトップヘ