FreelyApps

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


    アプリ『トランプ・7並べ』を公開しました。
    Android/iOS https://goo.gl/zsFces

    タグ:FPS

      このエントリーをはてなブックマークに追加 Clip to Evernote
    C#でスクリプト上で重い処理を作ったとします。大きなリストの複雑なソートをするとか、大量の計算を行うといったことです。
    そういったときスクリプトのある特定の部分に書いてあることが、どれくらいの時間で処理されるのかということを知りたいことがあるでしょう。 こういったときはC#のStopwatchクラスを使うと簡単に実行時間が測れます。以下にコードを載せておきます。


    ストップウォッチクラスを作り、Startします。処理が終わったタイミングでStopし、ElapsedMillisecondsでかかった時間をミリ秒単位で取得しています。非常に簡単なコードなので、簡単にパフォーマンスを測れます。
    リリース版に計測用のコードが紛れ込むのが嫌なら、定義を使っておくと良いと思います。(#if DEBUGなど)

    ProfilerやFPSの計測よりも細かな範囲でのパフォーマンス計測になります。はじめは大きな計測から始めて、徐々に計測範囲を狭めていくと処理が重い原因を調べやすいと思います。
    このスクリプトのあるメソッドが重いとわかっているなら、今回の計測方法でさらに詳しく原因を探れるはずです。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    FPS を変えるところだけ知りたい方は、横線が引かれた下の部分だけお読みください。

    Unity で作ったゲームはFPS が自動的に設定されます。端末ごとに自動で決まるので意識しないことも多いかと思います。
    FPS は処理の更新頻度と考えることができますが、当然処理が重くなれば高いFPS は出しにくくなっていきます。PC とモバイルの性能差は大きいもので、開発中(PC で作業)のときは問題ないのに実機(モバイル)では動きが滑らかでないということが起きます。 それは描画の処理はハードウェアの仕組みで常に一定のタイミングで変更がなされるためです。(ここでそれについては深く触れないので、Unity で作ったアプリで処理が描画の更新に間に合わなければカクカクした動きになるということだけ認識してください。)
    Unity のFPS は変動するので、可変フレームレートの設計で作らなければいけません。Update 関数の呼び出しのタイミングが一定ではないので、前の呼び出しから何秒経ったかを取得しその時間を考慮して更新を行うということです。例えばキャラクターの移動を(速度)×(Time.deltaTime) の値を足していくことで実現していれば良いのです。このように作られていれば、フレームレート(FPS) を変更してもそのままゲームが動くはずです。 

    Unity でゲームを作れば可変フレームレートの設計になります。更新のタイミングがどうであろうとゲームが動くように作られているなら、FPS の目標値を下げたりする必要があるのかという疑問を思うかもしれません。FPS の目標値が60である場合、FPS は0 ~ 60 までの値を取り得ます。十分に処理に余裕があれば60 の値になり、余裕がないときは10 とかになるでしょう。60 のときは滑らかで10 のときは動きがぎこちない。それを行ったり来たりしてしまうと、非常に見た目が悪くなります。頻繁に低いFPS を取ってしまう場合、処理が重すぎるので目標とするFPS を下げる必要性が出てきます。
    FPS の変動が小さくなればそれほど見た目に差は出ません。目標とするFPS が下がると、当然取りうる範囲が狭くなるので変動する可能性が減ります。また更新頻度が下がることで処理にかける時間を増やすことができます。



    Unity でFPS を動的に変更する方法は以下のようになります。
    Application.targetFrameRate = 30;
    というようにして目標とするFPS を指定できます。60 か30 が無難だと思います。
    もうひとつ変えなければいけないところがあります。QualitySettings のV Sync Count という設定をDon't Sync にしなければいけません。これはハードウェアの画面の更新に更新(Update)をあわせるかという設定なので、あわせてしまうとFPS を設定できません。
    動的に変えられるといってもゲーム起動時に30FPS に設定してあとは何もしないとかでもかまいません。その場合は単にFPS を半分にしているだけなので、QualitySettings のV Sync Count をEvery Second V Blank にするだけでスクリプトで制御しなくても同じことが実現できます。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    FPSの計測を自前で書くことはいろいろなメリットがあります。
    アプリをインストールするだけでFPSを測れることになると、チェックに必要なものが端末だけになるので 便利です。

    UnityにはProfilerというパフォーマンスを計測するための機能があります。実はこれを使うと端末で実行中のゲームのパフォーマンスが測れます。
    Android以外の場合も計測できますが、ここではAndroidだけ説明します。

    ゲームをビルドするときにデバッグできるように設定します。
    Build Settingsを開いたときに以下のようにDevelopment Buildを選択します。
    すぐに計測したい場合はAutoconnect Profilerも選択します。(ゲームのインストールが終わると自動でProfilerを開くようになります)

    bs

    Build And Runを押してビルドと端末へのインストールを行います。
    端末でゲームが起動したら、Unity側でProfilerを開きます。Profilerの上部メニューのActive Profilerを押して計測したい端末を選択します。ここでは3番目に出ているNexus 7を選択します。(私の場合です)

    prof

    選択後計測がリアルタイムで行われていきます。Wi-Fiでつないでいるようなので、Unityから認識されてからはUSBケーブルを外しても大丈夫でした。 

    確実に使うためにはBuild SettingsでDevelopment BuildとAutoconnect Profileを選択し、Build And Runを行うのが良いです。自動で計測開始してくれるのでミスが起こらないと思います。USBケーブルもつけっぱなしにしておいてください。

    公式ページにも情報がありますので参照ください。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unityのエディター上では簡単にFPSを表示できます。
    ゲームビューのStatusボタンを押すと、画面の右中段に表示されます。
    簡易的に調べられるので便利です。
    実機上の確認には使用できないので端末の性能を測ることに使えません。
    つまり、リリースするときの機種次第では目安程度の意味しかありません。
    FPSが急激に変わったりすることを見つけるとかに使いましょう。

    FPSの表示をするにはOnGUIを使うのが簡単です。
    Unity UI(uGUI)を使ってもかまいません。 
    表示方法は何でも良いです。 

    FPSを測るには2通りあります。
    • 定義通り、1秒間に何回更新が行われたかカウントする方法 
    • 更新間隔を測り、その逆数をFPSとする方法
    1秒間を測りその間に何回更新されたかをカウントして、FPSを求めます。
    FPS = (更新回数)
    定義通りの値であり、整数値が返ります。利点は見やすく、ゲームの1秒ごとのパフォーマンスが把握できることです。1秒というのはそれなりに長いので、パフォーマンスが良い悪いという指標に使いやすいです。
    欠点は瞬間的なパフォーマンスの悪化を見逃すことと実装の面倒さです。
    1秒ごとというのを判定し、そのたびに初期化をして繰り返すといったことになります。

    更新間隔を測ることから求める方法は、測った更新間隔でこの後も処理が続くと仮定して1秒間に何回更新されるかを決定しています。
    FPS = 1 / (更新間隔) 
    になります。
    1フレーム前の更新時刻を 記録しておけば毎フレームFPSを求めることができます。この方法の 利点は瞬間的な処理の速さを知ることができることと実装が簡単ということです。欠点は瞬間的なゲームのパフォーマンスしか測れないことです。 

    FreelyAppsでは2番目の方法を使っています。
    そのまま使うと継続的なパフォーマンスがわかりにくいため、平均を用いてある程度の長さでのパフォーマンスを測っています。
    最新の更新間隔だけでなく、いくつか前の更新間隔も記憶しておくということです。



    fFPSとfAveFPSには毎フレーム更新された値が入ります。
    上では30フレーム分の更新間隔を平均し、その更新間隔からfAveFPSを求めました。
    この値をOnGUIかUnity UIで出せばいいわけです。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    FPSというのはFrames Per Secondの略であり、1秒間に何回画面の描画がおこなわれるかという単位です。
    大きいほど頻繁に画面が切り替わるので、動きが滑らかになります。動画の滑らかさを表すのに使われていますが、ゲームの処理がどれくらい速く行われているかを表すのにも使われます。ゲームの処理が行われてから画面を更新しての繰り返しでゲームが進んでいきます。処理が行われることが画面の更新のタイミングを決めるため動画と同じ単位が使われているのでしょう。

    FPSを測ることでゲームの更新頻度がわかり、どれくらい処理がかかるのかを把握できます。つねに表示すれば、どのタイミングで重いのか調べることもできます。

    あまりに低いFPSが出ることがあるなら、その部分には改善すべきことがあるはずです。

    ゲーム全体で目標とするFPSを決めてそれ以下になる部分をなくしていくことが良いです。わかりやすいですし、無駄な作業が減らせます。

    このページのトップヘ