Android
C#
iOS
Unity
uGUI

3時間で作れる割り算電卓アプリ by Unity

14日目担当のf-murakamiです。

簡単にスマホアプリを作る方法について書いてみたいと思います。

スマホアプリを作るにはAndroidならjavaやkotlin、iOSならobjective-cやswiftなどが主流ですが、あえてUnityを使ってみたいと思います。

Unityは、スーパーマリオランや白猫プロジェクトなどの有名なゲームにも使われている、本来3Dや2Dのゲームを作るためのエンジンですが、実はUI機能もかなり充実しており、ツール的なアプリも簡単に作ることができます。

そして、Android、iOS、WebGLなどいろいろなプラットフォームに対応しており、1つ作ればいろいろな環境で動かすことができます。

さらに、プログラム言語にC#が使えるので、C#er(シーシャーパー)の私としては、もってこいなんです。

作るもの

題材は簡単で実用的なものが良いので、電卓アプリにしてみます。

ただ、単純な電卓アプリなら世に掃いて捨てるほどありますので、割り算の商と余りを求めるのに特化した電卓(名付けるとしたら「あまり電卓」かな)を考えてみます。

意外にも、こんな電卓アプリはありそうでほとんどありません。
使い道は少ないかもしれませんが、子供が小学校で習う割り算の答えあわせに使えたりしますよ。

準備(Unityのインストール)

まずは、Unityをインストールしてください。
インストール方法はいろいろなサイトにありますので、ググってみてください。

2017年12月14日現在、最新バージョンは2017.2.1です。

あと、AndoridアプリならAndroidStudio、iOSアプリならXCodeが必要です。
こちらもインストールしておいてください。

アプリの作り方

アプリを以下の流れで作っていきます。

  • どんなアプリにするか設計する
  • Unityプロジェクトを作る
  • プラットフォームを選択する
  • 画面を作る
  • イベント毎のロジックを作り、画面と紐つける
  • PCで動作確認する
  • 画面のオブジェクトに相対的な位置を設定する
  • スマホに転送して動作確認する
  • 完成

それでは順にいきましょう。

どんなアプリにするか設計する

すぐ実装に入りたいところですが、その前に設計しましょう。
割り算の機能しかないので、以下のようなイメージです。

image.png

手書きで恐縮ですが、趣味で作る分には凝った設計図は不要です。
まず、どういったアプリを作りたいかイメージを膨らませて図解してみてください。

設計図ができたらいよいよ実装に入ります。

プロジェクトを作る

Unityで実装するにあたり、まずプロジェクトというものを作ります。

UnityのSDKを開くと、プロジェクトメニューが表示されますので、右上のNewを押します。

image.png

プロジェクト名をいれて、2Dにチェックします

image.png

すると以下の画面が表示されます。

image.png

プラットフォームを選択する

最初にどのプラットフォームで動かすかを選択します。
(あとで選択してもいいですが、先に選択した方が、画面サイズなどシミュレーションしやすいです。)

プラットフォームを選択するにはFileメニューからBuild Settingsを選択します。

image.png

今回はAndroidのアプリとして作ってみます。
その場合、Androidを選択して、Switch Platformを押下します。

image.png

これでプラットフォームの準備ができました。

画面を作る

次に画面を作っていきます。

Unityでは画面1つ1つをシーン(Scene)といいます。
複数画面を遷移するようなアプリは複数のシーンが必要です。

最初はシーンが1つだけ用意されていますが、まだ保存されておらずUntitledとなっています。
今回作るアプリは、画面が1つだけなので、このシーンをMainとリネームして保存します。

画面にラベルやボタンなどを配置するには、まずCanvasというオブジェクトを作る必要があります。
このCanvas上に、ラベルやボタンなどを配置していきます。
Canvas自体に座標をもっており、通常の2Dや3Dのオブジェクトを配置する座標とは別モノです。

Canvasを作るにはシーンの右クリックメニューからCanvasを選択します。

image.png

今見えている図面は2Dや3Dのオブジェクトを配置する図面で、この右上に向かって広がっているのがCanvasの図面です。

image.png

Canvasを作ったら、Canvasの図面に合わせて表示領域を広げます。

image.png

Canvasの図面が表示領域におさまればOKです。

image.png

次にラベルやボタンなどのオブジェクトをおいていきます。

必要なオブジェクトは以下です。

  • 計算式入力欄
  • 結果表示欄
  • 入力ボタン

計算式入力欄

入力欄なので入力フィールド(InputField)が良さそうですが、手入力はさせずボタンによる入力に限定するため、パネル(Panel)をおいてその上に文字を表示するようにします。
そのため、パネルの子オブジェクトとして、文字を表示できるテキスト(Text)をつかいます

入力欄としてパネルを配置します。

image.png

パネルが画面全体に広がっているので縮小し、この子オブジェクトとしてテキストを配置します。

image.png

こんな感じです。

image.png

結果表示欄

計算式入力欄と同じようにパネルで作ります。子にテキストをセットします。

文字も入れてみました。フォントなどはInspectorウインドウで設定します。

image.png

入力ボタン

以下の4種類のボタンを配置します。

  • 各数字ボタン(0~9)
  • 割る(÷)ボタン
  • イコール(=)ボタン
  • クリア(C)ボタン

まずは1個数字ボタンを作ってみましょう。
サイズやフォントをいい感じに設定したら、他のボタンはコピーして作りましょう。
(あとで配置とか調整しますのでおおざっぱで良いです。)

こんな感じになります。

image.png

これで画面の配置は一通り完了です。

イベント毎のロジックを作り、画面と紐つける

手順は以下の流れ。

  • スクリプトファイルを新規作成し、画面のオブジェクトにアタッチする
  • スクリプトに、イベント毎に対応するメソッドを定義する
  • 画面のオブジェクトをスクリプトに受け渡す
  • ボタン毎のクリックイベントに、スクリプトのメソッドを紐つける
  • イベント毎の処理ロジックを作る

スクリプトファイルを新規作成し、画面のオブジェクトにアタッチする

ProjectウインドウのAssetsから右クリックメニューでCreateC# Scriptを選択

image.png

以下のコードが書かれたスクリプトファイルができます。
Main.csと命名してます)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

このスクリプトを画面のオブジェクトにアタッチします。
今回の場合は、どのオブジェクトでも良いのですが、Canvasオブジェクトにしてみましょう。
以下手順です。

CanvasのInspectorウインドウから、Add Componentを押下

image.png

Scriptsを選択

image.png

先ほど作成したスクリプトMainを選択

image.png

これでアタッチ完了です。

スクリプトに、イベント毎に対応するメソッドを定義する

どんなイベントがあるかは、最初設計図に書きましたね。
各イベントと対応するメソッドを定義してみます。

  • 初期ロード → Start(デフォルトで用意されてます)
  • 各数字ボタン押下 → InputNumber
  • ÷(割る)ボタン押下 → InputDivide
  • =(計算)ボタン押下 → InputEqual
  • C(クリア)ボタン押下 → InputClear

(Updateメソッドは常に動かす処理を書きます。このアプリでは使いません)

また、画面のオブジェクトをスクリプトに受け渡すため、クラス変数に定義します。
あと、UnityのUIクラスを使うので、ネームスペースにusing UnityEngine.UIを定義しときます。

変数とメソッドを一通り定義すると、以下のコードになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour {

    // 式入力テキスト
    public Text Formula;
    // 結果表示テキスト
    public Text Answer;
    // 各数字ボタン
    public Button[] bNumber;
    // 割るボタン
    public Button bDivide;
    // 計算ボタン
    public Button bEqual;
    // クリアボタン
    public Button bClear;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }

    // 各数字ボタン押下
    public void InputNumber(Text number){
    }

    // 割るボタン押下
    public void InputDivide(Text divideButton){
    }

    // 計算ボタン押下
    public void InputEqual(Text equal){      
    }

    // クリアボタン押下
    public void InputClear(Text equal){
    }
}

画面のオブジェクトをスクリプトに受け渡す

先ほどCanvasオブジェクトにアタッチしたスクリプトをみると、パラメータを渡せるようになってます。
そこに受け渡す画面オブジェクトを指定します。
(数字ボタンは配列で受け渡しています。)

image.png

ボタン毎のクリックイベントに、スクリプトのメソッドを紐つける

各ボタンオブジェクトにはクリックイベントが設定できるようになってます。
スクリプトをアタッチしたオブジェクトと、イベントで実行するメソッドを指定します。
これを各ボタンに設定していきます。

以下の図は、数字1のボタンの設定例です。

image.png

イベント毎の処理ロジックを作る

イベント毎の処理ロジックを書いていきます。
特に難しいロジックはないと思います。

できあがったスクリプトは以下になります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour {

    // 式入力テキスト
    public Text Formula;
    // 結果表示テキスト
    public Text Answer;
    // 各数字ボタン
    public Button[] bNumber;
    // 割るボタン
    public Button bDivide;
    // 計算ボタン
    public Button bEqual;
    // クリアボタン
    public Button bClear;

    // Use this for initialization
    void Start () {
        //初期化
        Formula.text = "";
        Answer.text = "";
    }

    // Update is called once per frame
    void Update () {

    }

    // 数字ボタン押下
    public void InputNumber(Text number){
        // 押下したボタンの数字を式欄に追記する
        Formula.text += number.text; 
    }

    // 割るボタン押下
    public void InputDivide(Text divideButton){
        // 数字が未入力か、すでに÷があればスルー
        if(Formula.text == "" || Formula.text.Contains("÷")){
            return;
        }

        // ÷を式欄に追記する
        Formula.text += divideButton.text;
    }

    // 計算ボタン押下
    public void InputEqual(Text equal){

        // ÷がないか、文字列の最後が÷ならスルー★
        if(!Formula.text.Contains("÷")){
            return;
        }

        // 入力した式を割る数と割られる数に分ける
        string[] inputString = Formula.text.Split('÷');
        int leftNumber = int.Parse(inputString[0]);
        int rightNumber = int.Parse(inputString[1]);

        // 割られる数がゼロならスルー
        if(rightNumber == 0){
            return;
        }

        // 商
        int quotient = leftNumber / rightNumber;
        // 余り
        int remainder = leftNumber % rightNumber;

        // 計算結果を表示
        Answer.text = quotient.ToString() + "…" + remainder.ToString();

    }

    // クリアボタン押下
    public void InputClear(Text equal){
        //初期化
        Formula.text = "";
        Answer.text = "";        
    }
}

PCで動作確認する

一通り作ったら、PC上で動かしてみましょう。
Gameビューから再生するとアプリが立ち上がります。

image.png

いろいろ動かしてみて、うまく動かなければデバッグして修正。
これを繰り返します。

画面のオブジェクトに相対的な位置を設定する

PCで一通り動いたら、スマホで動かしたいところですが、その前にやるべきことが!

スマホは機種によって画面のサイズや解像度が違います。
先ほど、一通り配置したのは、絶対座標で設定されており、画面サイズや解像度が異なると、同じ座標でも位置が変わってしまいます。

どのような画面でも対応できるようにするには、画面の最小最大の座標を統一し、相対的な位置を設定する必要があります。

これには、アンカー(Anchors)というレイアウトの概念を用います。

アンカーを用いると、画面のX軸Y軸それぞれ最小を0、最大を1に統一し、画面の相対的な位置を定義できます。

以下のようなイメージです。

image.png

例1)入力テキスト欄の場合
(アンカーの基準を(0,0)にするため、Left,Right,Top,Bottomは全てゼロにしてください)

image.png

例2)数字1ボタンの場合

image.png

スマホに転送して動作確認する

アンカーの設定を行ったら、いよいよスマホで動かしてみます。

FileメニューからBuild Settingsを開きます。

image.png

まずは、Player SettingsからPackageNameをいれてください。

image.png

設定したら、PCとスマホをつないで、Build And Runを押して転送します。
あらかじめスマホのロックははずしておいてください。

転送が完了したら自動的に立ち上がります

image.png

計算してみます。

image.png

ちゃんと動きますね!

おわりに

Unityを使ってスマホアプリを作る方法を、プロジェクトの作り方から、実機で動くところまで書いてみました。
予想以上に記事量が増えてしまい、ところどころ端折ってます。
もし、ここってどうすればいいの?など不明な点がありましたらコメントしてください。

また、今回はとりあえず動くところまででしたが、もちろんここから画面をもっときれいにしたり、操作しやすいレイアウトにしたり、機能を増やしてみたり、どんどんブラッシュアップできます。
さらに、プラットフォームを切り替えればiOS用にも作れます。

本稿を読んでみて、アプリを作ってみたい!って思った方、これなら私でもできる!って思った方、ぜひともアプリを作ってみましょう。
そして、いいのが作れたら、パブリックにも公開してみましょう。
(公開の仕方は、いろいろなサイトに載ってますので調べてみてください。)

それでは!