FreelyApps

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


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

    2016年02月

      このエントリーをはてなブックマークに追加 Clip to Evernote
    アプリを作ったら、自然に広まっていくようにするためSNSとの連携ができるようにしたいと思うかもしれません。ゲームであれば、何らかのタイミングで結果が出ます。その瞬間にSNSに投稿できるようにするというのは自然だと思います。

    Unityを使ってSNSと連携するときに最も簡単なのはTwitterのTweet Web Intentを使うことだと思います。 特定のURLにアクセスすることでウェブサーバーがツイートを行うようにしてくれます。Web APIという呼ばれ方をされている利用方法でしょう。ものによっては認証が必要なことがありますが、ツイートすることについてはブラウザでアクセスするだけで可能です。

    https://twitter.com/intent/tweet?text=test

    のようなURLをApplication.OpenURLに渡してやれば良いです。このサイトを見ているブラウザで試してみるとわかりやすくて良いでしょう。私の場合、赤字になっているURLをブラウザでコピペして開いた結果が以下のようになりました。
    tw-wintent

    単なる文字列を投稿するだけならtextパラメータに値を設定すれば良いですが、渡す文字列はURLの書式に対応したものでなければなりません。具体的に言うと、文字列データをWWW.EscapeURLで変換したあとの文字列を渡す必要があります。
    var webintent = "https://twitter.com/intent/tweet?text=" + WWW.EscapeURL("送りたい文字列");
    というようにすれば良いということです。

    クエリパラメータにはいくつか種類が用意されているので、他にもできることがあります。クエリパラメータを使わなくても特殊な文字列(#、@など)を使っても問題なく動きます。

    このTweet Web Intentを使うことの利点はUnityの機能をあまり使っていないということです。単にブラウザにアクセスする機能さえあれば、あとはURLを適切に作成するだけなので、どの端末でも間違いなく動きます。AndroidでもiOSでもWindowsでもMacでも関係がありません。
    欠点はURLに埋め込めるのは文字列だけということとSNSによっては対応していない方法だということです。いくつかのSNSはこういった機能を持っているので、同じようなことができます(どれに投稿するか選ぶ画面を作らなくてはなりませんが)。

    簡単にSNSに連携してみたいという場合は、Tweet Web Intentを使ってみるのが最も良いと思います。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    ゲーム会社に就職してゲームを作りたいと思っている人は、ゲームをしたことがある人なら希望することが多いと思います。そんなわけでゲーム会社に応募する人はそれなりに多いです。会社の規模を考えたら倍率が高いことが多く、新卒なら100倍とかもありえるでしょう。

    ゲームを作りたいという人が多い(少なくともゲームが嫌いだと言う人はゲーム会社にいない)ため、仕事がきつい割に待遇が悪いです。この待遇というのも外からわかりづらいというのも問題です。
    内部にいる人に聞く機会があったら、必ず聞いておいた方が良いことを挙げてみます。
    • 給料
    • 残業時間
    • 休日の労働
    • 有給休暇の使用率
    • 職場環境
    とりあえず上記のことは聞いておくべきです。

    基本的にゲームというものはおもしろくさせるためにあるものなので、どう作れば良いという決まった方法がありません。工業製品でもありながら、芸術作品的な性質も持つものです。作ってみておもしろくなければ、やり直しとなります。それを繰り返しやすいので、働く時間は増えていきます。働く時間が増えると、健康に対する悪影響は加速度的に上がりますが、給料は大した割合では増えません。仮に給料が倍になったとしても、残業が100時間を超えるような労働を続けるのは割に合いません。(人によっては死にます。若いころは体力があるから大丈夫と言っていてもダメージは蓄積しています。視力だったり、腰だったり……)
    給料を聞くといっても「年収はいくらですか?」と聞いても気分を悪くさせるだけなので、「成果に見合った報酬を得られていると感じるか」とかでうまく聞きだしましょう。

    休日に働くというのは何の言葉遊びなのだろうかと思います。おかしくなってしまった人は、何連勤なのかを自嘲気味に自慢し始めます。

    日本は有給休暇の消化率が悪いそうですが、ゲーム会社もそうです。取ると他の人に迷惑だとか、作業が滞るだの言って取らない人が存在しますが、そういった人がどれくらいいるのかというのが大事です。そのような人が大勢いると非常に面倒です。有給休暇は働かないで給料がもらえる日です。使わないというのは実質給料が減っているのと同じです。手元に残るお金が減っているのではないため、なくなってもあまり文句を言う人がいないのかもしれません。

    職場環境は外部からは最もわかりづらいことです。具体的な例を質問するとかである程度は把握できるでしょうが、正確なことはわからないです。雰囲気が暗いとかは、現場に行ってみないとわからないことです。

    ゲームが好きだから、ゲーム会社で働くというのは素晴らしいことだと思います。ただ、ゲームが好きでもその会社が好きになれるかは関係ないです。
    知っておいた方が良いのは、労働条件を悪くしても人が多く集まってくる会社は労働条件を悪くすることがほとんどだということです。会社は営利目的なので、人件費を安くするというのが多くの経営者の考えるところだからです。(ごく稀に従業員の待遇を良くすることで生産性を上げるという経営者もいます。口だけの可能性もあるので、数値で見て待遇を良くしているか判断することが大事です。)

    最後に私の経験を元にした主観が入っているので、絶対に正しいとは言いません。異なる意見もあるでしょうし、それが正しいとも思います。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    できればやらないことにこしたことはないのですが、セーブをバージョンアップしなければならないことがあります。
    古いバージョンのセーブに含まれているパラメータを新しいバージョンのセーブでは以前と別の意味で使いたいといった特別なときのみ対応が必要になります。このような時でも容量を無駄にしても良いなら、新しくパラメータを増やして保存した方が安全です。
    デバッグ用途でなければ、バージョンは増える方向にしかいきません。バージョン1、2があったら、1から2へはいけますが逆はいけません。

    対応方法は色々あると思います。今、私が使っている方法は次のような方法です。
    セーブにはバージョン情報(単なる数字int)を保存できるようにします。またプログラム中にセーブのバージョンを定義します。プログラム中に書いたバージョンが最新バージョンになります。プログラムにあるロード処理は当然最新バージョンのデータに対応したものになっています。
    バージョンが変わるごとに1つバージョンを上げる処理を作り、それを順に通すことにより古いバージョンのセーブから最新のバージョンのセーブを作りだします。

    バージョン3が最新のものとし、セーブされているのがバージョン1とします。
    バージョン2を作ったときに、バージョン1のセーブからバージョン2のセーブを作る処理Convert1To2を作ります。Convert1To2はバージョン1をロードして、2のデータを作り、2として保存します。PlayerPrefsで作ると、バージョン1のキーで必要な情報を変数に保持しておき、バージョン2のキーで作成したデータを保存することになります。
    同じ要領でバージョン2のセーブからバージョン3のセーブを作る処理Convert2To3を作ります。これらの変換関数は現在のセーブバージョンを見て変換を行い、処理の最後でバージョンを上げます。
    1. 保存されているバージョンを調べる 
    2. バージョンが最新でなかったら、バージョンを1つずつ上げていくための処理を行う
    3. 最新バージョンのデータが保存されている状態になったら、ロードを行う
    という手順でバージョンがなんでも対応できます。この方法は古いバージョンのものがあったら、それを逐次新しいバージョンのデータに変換していくというものです。ひとつずつバージョンが上がるためにいくつものバージョンが合っても正しく変換でき、バージョンが上がるときの対応も1つ前のものから最新のバージョンへの変換処理だけ追加すれば良いという利点があります。

    ややこしく感じるのはセーブがファイル上にあるのかメモリ上にあるのかが、文章からだと区別しにくいからです。 説明していて私もちょっと混乱してきました。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Androidのアプリのアップデートについてですが、公開のタイミングを自由に選べるようになったようです。アプリの公開というところに詳細が載っています。

    アップデートをするときにDeveloper Consoleの「更新を送信」ボタンの上に標準公開(デフォルト)となっているところをクリックすれば、時限公開に切り替えることができます。
    このモードにした状態でAPKをアップロードするなりして、アップデートの準備をします。
    これで「更新を送信」すると、通常のように数時間(かかることも)の待ち時間を経て公開できる状態になります。通常では公開も自動で行われるわけですが、時限公開の場合は「公開」ボタンを押すと数分以内で公開されることになります。
    公開タイミングを自由に選べることでイベントとかやってるアプリは楽になるでしょうし、告知をしてすぐに公開できるというのも使いやすいかもしれません。

    次にアップデートする機会があれば、使ってみようと思います。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    a6-permission

    Android6.0ではパーミッションをユーザーが任意に変えられる仕組みが導入されました。アプリによっては動かなくなるような致命的な影響を与える変更なので、一度は公式のドキュメントを見た方が良いです。

    パーミッションには色々ありますが、一部のパーミッションは危険だという分類にされていて、そのパーミッションを使うにはユーザーが許可する必要があります。それも動的(アプリ実行時)に変わるので、パーミッションが必要な処理をするところではその都度許可されているか調べなくてはなりません。

    どのパーミッションが危険かはこの記事のNormal and Dangerous Permissionsを見てください。
    私はSNSで画像を添付するためのファイルの読み書き
    • android.permission.READ_EXTERNAL_STORAGE
    • android.permission.WRITE_EXTERNAL_STORAGE
    の許可が必要になりました。 (実はWRITEの方があれば良いんですが……)

    許可が与えられているかを調べるにはAndroidのContextCompat.checkSelfPermissionを使えば可能です。当然、この呼び出しはJavaになります。プラグインを作ることでも可能ですが、UnityにあるJavaクラスを呼び出すためのクラスAndroidJavaClassを使うとC#のコードだけで実装が可能です。以下にコードを置いておきます。


    Check("android.permission.WRITE_EXTERNAL_STORAGE")のようにするとパーミッションが許可されているか調べられます。

    このコードを利用しても次のエラーが出るでしょう。
    AndroidJavaException: java.lang.ClassNotFoundException: android.support.v4.content.ContextCompat
    これはライブラリがないため、クラスが見つからないということです。 Plugins/Androidフォルダを作り、そこにandroid-support-v4.jarを置いておけば解決できます。
    android-support-v4.jarはAndroid SDKをインストールしたフォルダにあるはずで、
    (AndroidのSDKフォルダ)\extras\android\support\v4にjarがあります。これをUnityのプロジェクトの適切な場所にコピーすれば良いです。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    2/20に『トランプ・ゲスイット』を1.1にアップデートしました。
    今回の対応はユーザーからの不満の対応として、AIの改善を行いました。

    AIは学習によって行動を変えるのですが、負けてくるとその戦略が悪いと判断します。以前、勝っていた戦略が悪いと判断されてしまうと今までやっていなかった行動をし始めます。その行動がユーザーを驚かすようなものになってしまっていて不満が出ているのだと思います。

    どのような行動が良くないかというと、ゲスイットのゲーム性上「いきなり解答する」というのはつまらないものと感じられるようです。何もせずにゲームが終わってしまうということに加え、ノーヒントで解答するという運に賭けるような行動は弱いAIだと思われてしまうのです。
    とりあえずいきなり解答することは避けるように修正してみたので、これで様子を見ることにします。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    『FlashNumbers』のタイトル画面を作ってみました。いつもはあまり時間をかけて作っていないのですが、今回は美しいフォントを使用させてもらっているので、アニメを作ってみました。フォントは「数式フォント」というものです。キユマヤ園様が作成されたフォントです。

    画像真ん中にある"FlashNumbers"というのが数式フォントによる表示です。特徴的なデザインのフォントなので、見出しとかに使うとインパクトがあるかと思います。

    dvt-title

    数字が降っているのが今回作成したアニメです。uGUIを使って作成されています。Textを大量(100個)用意して、それを画面の上から下に向かって動かしています。数字をセットしたり、アルファをフェードアウトさせたりするとこんな感じの見た目になります。
    本当はもっとたくさん降らしていたのですが、処理落ちが激しくなってきたので断念しました。フォントの描画は結構重い処理のようです。

     

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unityではイベント関数と呼ばれる特殊な関数があります。これはゲームオブジェクトにアタッチされたスクリプトの中で特別な名前のメソッドがUnityから呼ばれるという機能です。

    よく使うものを挙げると、 
    • Awake()
    • Start()
    • Update()
    • OnDestroy()
    などです。

    イベント関数を使う上で問題になることが多いのが、名前を間違うことです。名前を間違えただけなので修正は容易なのですが、問題が発覚しにくいことが厄介なところです。
    名前を間違っていても特にコンパイルエラーは発生しません。そのためプログラム的な問題はないと判断されて、後になって実は問題があるということになります。Unityから呼び出されなくても文法的には問題ないため、検出できないバグになるのです。

    OnCollisionEnter(Collision)みたいに特定のクラスを引数に取る場合も注意が必要です。イベント関数の名前が合っていても引数の型が間違っているということがあります。このときどのようになるかを例を挙げて調べてみました。
    void OnCollisionStay(int n)のように定義すると、以下のようにエラーが発生しました。
    event-argerror
    しかしながら、void OnCollisionStay()というように引数を空にしてみるとイベントが発生したタイミングに正しく呼ばれていました。
    つまり、イベント関数が引数を取る場合、引数があっているか空であれば呼ばれるということです。(もちろん名前が合っているとして)

    イベント関数の名前を間違ったり、引数の型を間違っていてもエラーが発生しないことがあります。
    正しくないイベント関数を書かないようにすることは絶対には防げないので、起こりにくくする方法を紹介することにします。


    VSTUを使っている場合は便利機能でイベント関数を自動で実装することができます。これを使うのが最もミスの起こりにくい方法だと思います。あまり詳しくないイベントを使う時などはこの機能を使っておくのが良いです。

    Visual Studioでイベント関数を追加したいソースファイルを開いて、ソース上で右クリックをすると下のメニューが現れます。
    vs-event

    Implement MonoBehavioursとQuick MonoBehavioursとが用意されているので、どちらかをクリックします。

    Implement MonoBehavioursの場合は、次のウィンドウが現れます。
    vs-implement
    チェックしたイベント関数が一度に追加でき、メソッドの説明をコメントできたりするのでお勧めです。ソースに自動的にプログラムが書かれるので間違うことがなく、積極的に使うべき機能だと思います。

    Quick MonoBehavioursの場合は、次の小さなウィンドウが現れます。
    vs-quick
    入力欄にイベント名を一部でも入れると候補が検索して現れます。候補を選べばメソッドが追加されます。
    こちらの機能はイベントの名前を知っている場合、素早く追加することができるという熟練者向けの機能と言えます。一度に追加できるのは1つまでです。

    VSTUを使って自動的に追加されたイベント関数にはpublic void Awake()のようにpublicが付きますが、publicはなくても問題ありません。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    このアプリでは画面は横向きです。縦向きだと数字が縦に並んで見にくかったからです。なぜか見にくいと感じました。生理的なものなのかもしれません。

    画面の向きの設定はPlayerSettingsのOrientationという項目を設定します。モバイルではPortraitがデフォルトですが、これは縦向きの表示です。縦向きの表示ではホームボタン(Androidではナビゲーションバーのこと)は画面の下部に来ます。
    Portraitはホームボタンが端末の下側に来ている状態です。逆にPortrait Upside Downではホームボタンが端末の上側に来ていて、スマホを上下反対にして遊ぶことになります。
    横向きにするにはLandscape RightかLandscape Leftを選びます。端末によって向きが違うかもしれないので試してみることをお勧めします。

     autorotation-screen
    このアプリでは横向きであれば良いので、Landscape RightとLandscape Leftを切り替えられるように設定しました。上のような設定にすると端末を回すと、画面の表示が切り替わります。横向きにする設定だけをチェックしてあるので表示が崩れたりもしません。
    ひとつ問題があるとすれば、全画面表示の広告の向きは一定のようで、逆に表示される人もいるということくらいです。(Unityが制御しているわけではないからです。)


    最後に新しいアプリの名前を決めました。『FlashNumbers』とします。

      このエントリーをはてなブックマークに追加 Clip to Evernote

    徐々に数字の表示速度が短くなっていくようにしてみました。ある程度まで短くなるとそれ以上短くなりませんが、永遠にゲームは続いていきます。失敗するときがこのゲームの終了です。
    1つの枠には0~9の数字が表示されています。これを0~3までにしたり他の文字(アルファベット)とかが出るようにもして試してみたのですが、おもしろさは変わらなく感じたのでやめました。数字が出るという単純な方が良さそうです。

    ここでは見えませんが、実は難易度の設定も作ってみました。 枠の数、つまり一度に表示される数が変わります。当然、多い方が難易度が高いです。一番難しいのは記憶力も必要なので難しすぎるかもしれません。

    短期記憶で調べてみると数字の記憶は7個くらいらしいです。このアプリではその限界の7つまで出すつもりです。難しいですが、記憶のトレーニングにもなりそうです。 

    このページのトップヘ