FreelyApps

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


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

    カテゴリ: 開発

      このエントリーをはてなブックマークに追加 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
    DDMS(Dalvik Debug Monitor Server) を使うとログが見れます。
    端末での実行時に起こったことが見れるので、特にエラーが出ていないかを調べるときに重宝します。

    Android SDK をインストールしてSDK Manager からいくつかのツールが落とせますが、その中の一つです。たぶんAndroid SDK Tools を入れておけばDDMS が使えたと思います。

    Android SDK をインストールしたフォルダにtools というフォルダがあるはずです。その中のddms.bat をダブルクリックで実行するとDDMS が起動します。端末をUSBケーブルでつながないと情報は見れませんので、それだけ注意してください。

    実行画面は次のような見た目です。

    ddms-window
     

      このエントリーをはてなブックマークに追加 Clip to Evernote
    GI(Global Illumination) はUnity 5 から使えるようになったライティングの機能です。
    光源からの光が物体に当たり、物体が反射する光がさらに周りの物体を照らす様子を再現するという機能です。
    具体的に言うと、青い立方体に白い光を当てた時周りにある物体は白い光と青い立方体が反射した青い光が当たりうっすらと青くなるということが起きます。どれくらいの影響があるかは反射光の相対的な強さ次第なので、調整が必要です。
    GI を使えば万能かというと違います。なぜならGI は現実の法則に則っていないからです。物理的な法則を計算するには計算しなければならないことが多すぎて現実的な時間では解けないのです。そのため、それらしい絵を作ることができるのがGI ということになります。

    GI の説明をしたところでなんですが、今回はGI を無効化する話になります。Unity 5 ではデフォルトでGI が有効になります。シーンごとにこれは設定できるものです。GI 自体もそれなりに重い処理なので、あらかじめテクスチャに計算結果を書き込んでおきそれを実行時に使うということをして高速化を図っています。
    そのテクスチャはシーン内の情報を書き込んだものなので、かなり大きなテクスチャになりがちです。シーンを多用したモバイル向けのアプリではこれを見過ごすことができないくらいの容量になっていくと思います。(私の場合だとシーンごとで1MB くらいとっていました)

    アプリの大きさが大きくなるのは提出できなくなる恐れもあるので困ります。Google Play に提出するなら50MB が限度です。描画の質を下げたとしてもGIを切ることで容量制限を回避できるので、GIを切ろうということになります。以下がその手順です。



    Menu からWindow->Lighting を選びます。

    lighting-window

    Lighting Window が開くので、ここのPrecomputed Realtime GI とBaked GI のチェックを外します。

    invalid-gi

    これによりGIを実行しなくなり、ビルドした後のファイルにGI用のテクスチャが作られなくなります。GIは当然機能しなくなりますが、出来上がったファイルの容量は小さくなります。

    AndroidやiOSではGIを切った方が容量的な問題を回避できるため、切っておいた方が良いと思います。GI用のファイルが作られる条件というのは、Lightmap Static なゲームオブジェクトがいる場合などになりますが、良くわからなければLighting Window から設定した方が簡単です。 【GI(Global Illumination) を無効化する】の続きを読む

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity AdsのSDKはアセットストアからダウンロードします。

    Unity AdsのSDKはC#で書かれているので、C#で実装するのが一番簡単です。基本的な実装の流れはドキュメントのサンプルに書いてある通りです。 このサンプルをシーンに存在するGameObjectにつけて、GameIDと呼ばれるゲームごとに固有なIDを設定するだけで動きます。GameIDはUnity Adsの管理サイトの登録済みゲームの一覧が見れる画面で見ることができます。(日本語の場合、ゲームIDと書いてあります)

    サンプルコードの重要な所だけ説明しておきます。

     Advertisement.isSupported がtrueでない場合は、iOS/Androidではないプラットフォームを選んでいるのでUnity Adsは動きません。これはtrueだったら処理を続けるというだけのことです。

    Advertisement.Initialize  が初期化を行います。呼び出し方はゲームIDを引数に渡して呼ぶだけです。ゲームIDを間違ってしまうと、得られた報酬が実は違うゲームのものだったということになりかねません。これは十分に注意して書く必要があります。

    サンプルのOnGUIでは、Advertisement.Show を呼び出しています。特に準備できたか関係なしに実行されていることがわかります。Advertisement.isReady() はボタンの表示を変えているだけです。
    Advertisement.Show を呼び出すと広告の表示をします。必ず成功するわけではありません。このメソッドの引数にラムダ式を渡していますが、それにAdvertisement.Show の実行結果を渡します。(渡されるタイミングはわかりませんがいずれ渡されるのは確実のようです。)失敗、広告がスキップされた、広告が最後まで見られたの3通りの結果があります。サンプルでは結果をログに出しているだけですが、この引数によって処理を変えれば広告を見たときだけリワードを渡すといったことができます。

    大雑把に言うと、Advertisement.Initialize を行った後にAdvertisement.Show を呼べば広告が表示されます。広告が表示できないこともありますが、Advertisement.Show を呼んだときに処理がうまくいっていれば広告が出ます。その2つだけで実装は可能です。

    サンプルの説明は以上です。
    一応使えるものですが、実用には向かないと思います。なぜなら通信が遅いときや通信が失敗したときのことを考えられていないように思うからです。
    サンプルのままだと広告再生をしても失敗するということが多く起こると思われます。これについては今度説明したいと思います。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity Adsをゲームに組み込むには2段階あると思います。
    一つは管理サイト上で行う情報の登録でもう一つは実際にプログラミングをしてSDKを組み込むことです。
    今回は管理サイト上でUnity Adsを利用したいゲームの登録の手順をまとめておこうと思います。プログラミングをすることについては次回説明する予定です。

    管理用のサイトでゲームごとに情報を登録する必要があります。 とりあえず登録だけ済ませれば実装して確認できますので、それだけ行います。

    1. Unity Adsにログイン後、画面左のメニューからゲームを選びます。 既に登録されているゲームの情報が見れるのと新しくゲームを登録することができます。
    2. 画面の上部に「+新しいゲームを追加」というボタンがあるので、それを押します。
    3. 「ステップ1 - OSを選択してください。」と表示されるので、iOSかAndroidを選びます。
    4. 「ステップ2 - ANDROIDゲームを追加。」と表示されるので、Google Playに公開しているならそのURLを入力します。公開していないアプリの場合は、下の方に表示されているこちらからゲームを登録となっているところを押して名前の入力だけします。
    5. 「ステップ3 - ゲーム情報の確認」と表示されるので、質問に答えます。
    最後の質問がわかりづらいので補足しておきます。
    下のような画面の質問なのですが、全世界、全年齢向けのゲームとかなら、「このゲームは13才未満の児童を対象にしています。」を選べば良いでしょう。アメリカの法律に関係するようでフォーラムにも載っています。

    uad-gamereg-q
     
    以上の手順で「登録済みゲーム」の 一覧に新しく設定したゲームが追加されています。設定をいじることもできますが、既に2種類の広告を表示できるように設定されています。デフォルトになっているスキップできるタイプの広告と 報酬をあげるスキップできないタイプの広告です。
    あとで設定できるので、実装してからでも十分間に合います。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity AdsとはUnityの提供する広告システムのことです。
    広告の掲載場所の提供で収益を得ることができます。また広告掲載を依頼することでユーザーを獲得し、費用を払うということもできます。Unity Ads はゲームに特化した動画広告を配信するものなので、他の広告と違いゲームに組み込むのに適しています。

    Unity Ads の使い方を一度に解説するには長すぎるので、手順を何回かに分けて説明することにしようと思います。まずはUnity Adsを使うために登録をしなければなりません。今回はその手順について説明します。

    Unity Adsのサイトに行き、画面右上のログインもしくはサインインで登録ができます。画面右上はこんな感じです。

    uad-topright
     
    サインアップでも登録できると思いますが、Unity Accountを使いたいので、ログインの方から登録をしました。
    Unity Adsではメールアドレスと登録情報が重要みたいなので、Unity Accountを使う必要はありません。Unityで作ったもの以外でも使えるため、そのようになっているのだと思われます。
    比べてないのでわかりませんが、Unity Accountを使っての登録のメリットはログインがUnity Accountだけで楽というだけな気がします。 どちらでも機能は同じでしょうから、お好みの方法でどうぞ。

    Unity Accountを使った登録について説明していきます。
    ログインを押すと、次の画面が出てきます。
    UDNというのがUnity Accountのことであり、ログイン画面で登録とログインを兼ねています。サインアップではないので注意してください。

    uad-login
     
    ボタンを押すと、Unity アカウントのログイン画面になりますのでログインをしてください。
    ログイン後にUnity Adsの登録画面が開きます。下のような画面ですので、全ての欄を埋めてください。
    個人開発者であれば、会社名は自分の名前か開発者名(本名でない)を登録すれば良いです。

    以上が終われば、管理画面に入れます。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Androidの端末の画面をキャプチャーする方法がいくつかあります。Android 4.4以上では端末をPCにつないでコマンドを実行すると、Androidの画面をmp4形式の動画で保存することができます。

    Android 4.4以上の端末をPCにUSBケーブルで接続します。USBデバッグを有効にしておく必要があります。
    Android開発用のSDKを入れていれば、ADBがインストール済みなはずです。

    コマンドプロンプトを開き、
    adb shell
    を実行します。これで端末の操作が可能になります。(イメージで言うと端末に入っていろいろいじれる感じでしょうか。実際は入ってませんが)
     
    screenrecord ファイル名
    を実行すると端末の画面のキャプチャーが開始されます。 録画開始後にCtrl + Cを押すか180秒過ぎれば終了になるようです。

    screenrecord
     上の画面はscreenrecord --helpを実行した画面です。コマンドの内容について説明されています。
    詳しい説明はここに載っているので、一度は目を通した方が良いと思います。

    screenrecordの出力先フォルダにファイルの書き込み権限がないとコマンドの実行に失敗します。
    /sdcardの下であれば、問題なくファイルが作れるかと思います。
    例としては、
    adb shell
    screenrecord /sdcard/test.mp4
    と実行すると、/sdcardにtest.mp4というファイルができているはずです。lsコマンドを使えば/sdcardにtest.mp4が追加されているのが見て取れます。ファイルが必要なくなったらrmコマンドで消しておきましょう。

    これで動画の撮影は完了しました。できたファイルをPCに転送してやれば、動画ファイルとして色々扱えます。
    adb shellを終了させ、adb pullコマンドを使ってファイルを転送します。
    先ほどの保存場所だと、
    adb pull /sdcard/test.mp4
    とすれば、カレントディレクトリにファイルのコピーが作られます。 移動ではなくコピーなので、端末にはファイルが残っています。容量が十分にない場合は端末からファイルを消しておく方が良いです。

    ファイルマネージャーアプリでファイルの読み取りができるなら、mp4を作った後それでファイルをPCに持って行った方が簡単です。Android 4.4ではできなかったと思うので、私はadbを利用しています。 


    Android端末の画面を回転させてしまうとキャプチャーはうまくいきません。
    横x縦と決まった大きさの画面を録画しているため、回転すると画面が見切れてしまいます。 

      このエントリーをはてなブックマークに追加 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を決めてそれ以下になる部分をなくしていくことが良いです。わかりやすいですし、無駄な作業が減らせます。

    このページのトップヘ