Unityでつくったアプリ、Aladdin Runnerリリースしました

UnityでAladdin Runnerというランアクションゲームをつくってリリースしました! 着手開始からリリースまでは約1ヶ月半でほぼ一人でつくりました。 週末の空いた時間をつかって作業していたので、実際に作業に費やした時間はもっと少ないです。

iOS

https://itunes.apple.com/jp/app/aladdin-runner/id846489490?l=ja&ls=1&mt=8

Android

https://play.google.com/store/apps/details?id=com.hakuta.arunner

f:id:hiro_akuta:20140503161752j:plain

f:id:hiro_akuta:20140503161728p:plain

つくった理由

Objective-Cとかcocos2dxを使ってアプリをつくってみたことはあるもののリリースまでやりきったことがなかったので、 一度リリースまでやってみたかったというのが理由になります。(いつも途中で飽きたり、挫折したりで続かなかった)

複雑なゲームをつくろうとすると時間がかかってまた途中で諦めちゃいそうだったので、題材は簡単に遊べるカジュアルゲーム にしました。

やったこと

  • 背景、地面、敵、コインなどの自動生成

「ゲームの作り方 Unityで覚える遊びのアルゴリズム」にかかれていたロジックを参考にしました。

  • ランキング機能実装(GameCenterとGoogle Playのリーダーボードを使用)

実機でしかデバッグできなかったので、Unityやビルドやプラットフォーム変更に時間がかかり大分苦労しました。。 後から知ったのですがこちら(http://jemast.com/unity/fast-platform-switch)のfast platform switchというAssetを使うとプラットフォーム切り替えがはやくなるらしいです。

また、いろいろ修正しつつ作業していたらさっきまで動いていたものが動かなくなったりしてしまったので、 gitでちゃんとこまめにcommitしつつ作業しないとダメだなと思いました。

  • 広告の導入(admobを使用)

こちらのplugin(https://github.com/mikito/unity-admob-plugin)を最初使っていたのですが、 Admob SDKGoogle Mobile Ads SDKになったので、あとからPlay Games Plugin for Unityを導入した際に競合が発生して動かなくなってしまいました。 下記のページを参考にjavaファイルを修正して解決しました。 https://developers.google.com/mobile-ads-sdk/docs/admob/play-migration?hl=ja

つかったツール

  • 無料版Unity4.3

http://japan.unity3d.com/unity/download/

  • NGUI (2.7だと無料!)

http://www.tasharen.com/?page_id=140

UnityのGUIより簡単にボタンをつくったり、ラベルをつくったり、アトラスつくったりすることができます。

  • Play Games Plugin for Unity

https://github.com/playgameservices/play-games-plugin-for-unity

Android向けにGoogle Playのランキングを使用したかったので使いました。 最初ClassNotFoundExceptions.というエラーが出ていて2日くらい困っていたのですが、運良く修正commitが適用されたので無事解決しました。

参考にした本

Unity4入門   最新開発環境による簡単3Dゲーム製作

Unity4入門 最新開発環境による簡単3Dゲーム製作

Unityを全く触ったことがなかったのでサンプルを見つつ、Unityでどんなことができるのか把握することができました。 コーディングするところがほとんどなかったのでプログラミングやったことない人でも十分に理解できると思います。

ゲームの作り方  Unityで覚える遊びのアルゴリズム

ゲームの作り方 Unityで覚える遊びのアルゴリズム

Unityのことというより、ゲームをつくるときの考え方やプログラミングの仕方が丁寧に書いてあって非常に参考になりました。 Aladdin Runnerでも背景や地形の生成のプログラミングをするときに役立ちました。

まとめ

ゲームロジック部分は最初の2週間くらいでできたのですが、iOSAndroid両方のランキングを実装したり、広告を入れたり、デバッグしたり、リリースのやり方を調べたりというところにすごい時間がかかってしまいました。 ランキングやら広告やらは一度やってしまえば同じものを流用できそうなので、次からはもっと早く完成までもっていけそう。

実際にリリースしてみて、一番感動したのは自分のつくったゲームでいろんな国の人が遊んでくれてるというところです。 なにかモノをつくるのは大変だけど、モノつくりっていいなと思いました。

また別ななにかをつくろうと思います!

初めてのUnityエディタ拡張(ラベル表示)

UnityのInspectorであるクラスにpublicで定義したintとかfloatとかはInspectorに表示されるけど、 独自に定義したクラスの中のパラメタがみれない。。。

やりたかったことはUserCardクラスに定義したCardMasterクラスのインスタンスが保持しているatk, def, hpとかが見たかったので、初めてUnityエディタ拡張してみることにした。

f:id:hiro_akuta:20140424152148p:plain

using UnityEngine;
using System.Collections;

public class UserCard : MonoBehaviour {
    public CardMaster cardMaster;

    void Start () {
        cardMaster = CardMaster.CreateRandomCard();
    }
}
using System;

public class CardMaster {
    public int hp;
    public int atk;
    public int def;

    public static CardMaster CreateRandomCard() {
        System.Random r = new System.Random();
        CardMaster cardMaster = new CardMaster();
        cardMaster.hp  = r.Next(10);
        cardMaster.atk = r.Next(10);
        cardMaster.def = r.Next(10);
        return cardMaster;
    }
}

Assetsフォルダ以下にEditorフォルダをつくり、その中にUserCardEditor.csファイルをつくる。

f:id:hiro_akuta:20140424152828p:plain

targetという変数名に対象のインスタンスが入ってくるらしいので、それをUserCard型に変換。 あとはEditorGUILayout.LabelFieldでラベルを追加。

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(UserCard))]
public class UserCardEditor : Editor
{
    public override void OnInspectorGUI ()
    {
        DrawDefaultInspector ();
        UserCard userCard = target as UserCard;
        EditorGUILayout.LabelField("atk", 
      userCard.cardMaster.atk.ToString());
        EditorGUILayout.LabelField("def", 
      userCard.cardMaster.def.ToString());
        EditorGUILayout.LabelField("hp", 
       userCard.cardMaster.hp.ToString());
    }
}

これでUserCardのInspectorを見てみると、atk, def, hpが表示された!

f:id:hiro_akuta:20140424152202p:plain

簡単!

NGUIのUIButtonの画像をscriptで変える

UnityのNGUIのUIButtonを使ってボタンをつくり、Prefab化して、 実際に使うときにはPrefabをInstantiateして、画像だけが違うボタンをたくさん作りたかったので、

UISprite uiSprite = GetComponent<UISprite>();
uiSprite.spriteName = "newSpriteName";

としていたのですが、

NGUIを3.4.8から3.5.4にバージョンアップしたら、UIButtonがHover状態からNormal状態に戻ったときに画像がPrefab化したときの画像に戻ってしまった。 Assets/NGUI/Scripts/Interaction/UIButton.csを見てみると、今の状態に応じてSetSpriteしているみたい。

    protected override void SetState (State state, bool immediate)
    {   
        base.SetState(state, immediate);

        switch (state)
        {   
            case State.Normal: SetSprite(mNormalSprite); break;
            case State.Hover: SetSprite(hoverSprite); break;
            case State.Pressed: SetSprite(pressedSprite); break;
            case State.Disabled: SetSprite(disabledSprite); break;
        }   
    } 

mNormalSpriteがPrefab化したときのスプライト名になっていたのが原因ぽかったので

UIButton uiButton = GetComponent<UIButton>();
uiButton.normalSprite = "newSpriteName";

としてNormal状態のスプライト名を指定したらうまくいった!よかった!