Google

2012年9月18日火曜日

Unityでコインゲー開発:ポーズの具体例

開発中に中盤まですっかり忘れていたのがポーズ機能。
別にポーズボタンをつけてお客さんに使わせる訳じゃありません。
Unityでは望まなくても必要になる場合が殆どじゃないかと思います。

必要になるのはこんなタイミング。
  • アイテム一覧等のGUI専用画面遷移時
  • アプリ内課金等の通信で待ってもらう際
  • その他ゲーム内のエフェクト等で止める必要がある場合
2番目は1番目と被るのかも知れませんが一応。

そもそもUnityにはシーンという概念があります。
シーンはインスタンス丸ごと入れ替えなので、GUIが出たり消えたりする毎にごっそり入れ替えればポーズという概念が不要になります。
現在のシーンから別のシーンへの切り替え方法はとっても簡単。
以下のようにシーン名を指定するだけです。

// Unity公式サイトより抜粋。
// この例ではHiscoreという名前で保存されたシーンに遷移します。
Application.LoadLevel("HighScore");

しかしこの処理は負荷が大きく、一瞬アプリが固まったような印象を与えます。
さらにインスタンス管理とセーブロードの処理がきっちり出来ていないと、GUIから行って戻るだけでコイン位置が全リセット、なんて仕様になったりもします。
なのでUnityをよく知ってる人の場合、シーン分割はせいぜいタイトル位でしょう。

そこで今回はシーン切り替えではなく、実際に使ったポーズ処理をご紹介。
まずUpdate()で毎回動きを設定しているのなら、Update()の先頭にポーズフラグ判定を入れれば完了です。
フラグはboolにして、トグルさせるのが普通でしょう。

しかしコインゲーのような物理系の場合RigidBodyで落下処理をしているので、Updateでは止められません。
落下を止められるのはこれです。


通常この値は1.0になっています。
これは時間の進み具合を表現しており、0.0になるとRigidBodyの動きは完全に止まってしまいます。
RidigBodyの動きは重力の動きなので、めでたしめでたし。

、、、とはなりません。
これが0.0になると影響を受ける項目がこちらです。


他にも少々ありますがこれが大きいんじゃないでしょうか。
実はtimeScaleを0.0にしてもUpdate()関数は呼ばれます。
この時、GUIボタンのアニメーション等をdeltaTimeで判断していると、そっちまで全て止まってしまってあらどうしよう、になってしまいます。

しかしそれ以外の処理やイベントなどは全て使用可能ですので、静止タイプの2D処理を書く分には問題は発生しませんのでご安心を。
ちなみにNGUIにはtimeScaleに関するオプションがあり、ポーズの有無に関係ない処理を行うことが可能です。
まとめると、ポーズを実際に使うにはこうなります。

  • ポーズフラグを作る
  • Updateで処理しているものが止まるべきか判断する
  • RididBodyはタイムスケールでトグルさせる

今回は、コインインスタンス管理にポーズボタンだけを付けたものを準備しました。
先日のプロジェクトを改造しただけのシロモノですが。

これが画面。コイン落下自体は何も変わってません。
前回の違いとしては、勝手にコインがどんどん落ちてくるところ。

コインを落とすボタンは変わって、今回は「ポーズ」ボタンです。
左上に文字も出るようになりましたが、各項目はこうです。

  • DeltaTime:Updateで飛んでくる際のdeltaTimeの値
  • ProgressTime:ゲーム開始後の時間経過の値
本筋に関係ないのでソース解説は割愛。
簡単に言うと、Updateの中で毎回今回のdeltaTimeを保存し、FixedUpdateの中で毎回ゲーム開始からの時間を保存しています。
それらをOnGUIで出しているので、タイムスケールの動きがどうなるのかを勉強するにはいい材料ではないかと思います。

このプロジェクトは以下からどうぞ。
弊社サイトの保管庫に上げてあります。


ポーズの話はここまで。

続きます。

0 件のコメント:

コメントを投稿