年初から関わらせていていただいているKidsstarさんでのUnityゲームアプリ2個目と3個目の「JALのおしごとたいけん」と「串カツ田中のくしカツしゅぎょう!」がリリースされました。ひゃっほう。

日本航空が社会体験アプリ「ごっこランド」に 新規パビリオンを出店~JALのおしごとたいけん~ | 株式会社キッズスター|KidsStar Inc.

串カツ田中社会体験アプリ「ごっこランド」に新規パビリオンを10月8日(祝)に出店 ~当アプリ限定の「必ず」もらえる特典も全店でご用意~ | 株式会社キッズスター|KidsStar Inc.

JALの方はアプリ内のゲームが複数あって、開発はフェーズ1・2というように別れていて、最初のフェーズ1にあたる部分を担当しました。その後串カツ田中を担当して、リリースとしては同時期になりました。

UnityとC#は未だにヒーヒー言いながらやっていますが、新しい開発環境と言語は新鮮で勉強になることばかりです。

僕がスケジュールについていってる率でいうと、

1本目の「ECCのえいごのせんせいごっこ」は僕一人で終えることのできるシーンは少なく、一部を除いてほとんどは@monryさんや@fakestarbabyさん、@hanageman69さんにやっていただいたのでスケジュールに間に合ってないどころではない感じでした。

2本目の「JALのおしごとたいけん」は汚いコードながらも一人で作れるようになったのですが、僕の開発の理解も効率も悪く、スケジュール的には全マイルスートンで遅れてしまう感じでした。

3本目の「串カツ田中のくしカツしゅぎょう!」は一部マイルストーンでスケジュールを過ぎてしまうものの、必死に食いついていくことでなんとかスケジュール通りにこなせるようになってきた感じです。

すでに4本目の開発が始まっていますが、個人的に下記を目指してやっていこうとおもいます。

  • Kidsstarで使っているフレームワークのCAFUがv3になってかなり変わったのでZenjectとともに使えるようになる。(今まではv2ベース)
  • ゲーム開発の一部分しか知らないので、個人開発でゲームを作ってみて、全体としてのゲームづくりに習熟する。
  • 人任せになってしまっている、各プラットフォーム用ビルドの方法やリリースなどができるようになる。

今までずっとWebプログラマー(主にrails)で、スマホアプリちょろっとぐらいでしたが、今回初めてUnityでのスマホゲームのお仕事をさせていただきました。

お仕事

ECC が社会体験アプリ「ごっこランド」に新規パビリオンを出店!〜 ECC のえいごのせんせいごっこ〜 | 株式会社キッズスター|KidsStar Inc.

https://gyazo.com/be11132e05c72011837796bd014241a0

謝辞

「Unityを仕事でやりたい!」という意気込みだけの僕を辛抱強く教えてくださった株式会社Kidsstarエンジニアの @monryさん、@fakestarbabyさん、@hanageman69さん、@lycoris102さんありがとうございます。

お仕事で開発するまで

去年の11月末ぐらいに、

komagata「Unityやりたい」

Kidsstarさん「やろう」

ってなって、まずは勉強のお題として「もぐらたたきを作ってみよう」ということになりました。

https://gyazo.com/1509a6fd598d71ae23ec03514fdf9356

(もぐらたたきの要件の図)

その辺りの途中経過はブログにも書いています。

基本的なことを理解してない俺に対して@monryさんが丁寧に辛抱強くおしえてくれて非常に感謝しております。

基本リモートなので、現在の進捗や理解をブログとしてアウトプットするのは良かったなと思います。

ブログにすると自分の中で質問できる程度にまとまります。

フィヨルドブートキャンプで最近Railsを教えているので教える側として思うのですが、初心者のブログを見てると回答や教え方が自然に頭に浮かんじゃいます。それを吐き出すのは比較的ラクなんじゃないでしょうか。

昼間Rails仕事をし、夜中に気力が無くてもなるべく公式サイトのチュートリアル動画をみたりして勉強しました。

2週間ぐらいの感じで…と言われていたのですが結局年内一杯(4週間ぐらい)かかっちゃって後半必死こいてました。

Kidsstarのゲーム開発の流れ

ゲーム開発がはじめてなのでとにかく一回やってみないとリリースまでの開発の流れがわかりません。今回一通り体験できてとっても勉強になりました。

Kidsstarさんでのゲーム開発の流れは下記のような形でした。(外部の開発者としての視点オンリーです)

  1. お客さんとの間で仕様が決まる。(esa or Googleスプレッドシートで詳細な仕様書が作られる)
  2. ゲームで使う素材が作られる。(ボイスを録ったり、イラストを作成したり)
  3. オーサリングの得意なデザイナーさん(神)がほとんどの素材をUnityに配置し、アニメーションもTimelineなどで作る。(GameObjectについてる付箋にプログラマーへの指示が書いてある)
  4. コードが必要な部分(ゲーム本体や入力に反応して動くところなど)にプログラマーがコードを入れていく。
  5. お子さん向けテスト(実際に遊んでもらってフィードバックをもらう)
  6. 多端末検証(Androidの部分を外部の会社さんに依頼してテストしてもらう)
  7. ごっこランド本体とつなぎこみをし、リリース。(個別のゲームはそれ単体でBuildできるようになっている)

真っ先に思ったのが、

「圧倒的に大変なのデザイナーさんじゃね?」

ということです。

多分デザイナーさんには3つの役割があって、

  1. 元になるキャラクターなどのイラストを書く。
  2. 上記を元にゲームで実際に使う素材を作る。
  3. 素材をUnityに配置する。アニメーションを作る。

3人ぐらいデザイナーさんが関わってると思います。

また、Kidsstarの開発で驚いた点は、

「仕様書が超書いてある」

点です。

僕は最近、コンセプトのパワポだけを元に全て話しながら作ってく感じのWeb開発の仕事が多かったので、かっちり仕様が決まってるのは1プログラマーとして入るのはとても楽でした。

今回のゲームでできなかったこと

ほとんどの実装方法も聞きながらやったようなものですが、

「あ、この画面は自分で書けるかも?」

という状態にβ版リリース一週間ぐらい前にやっとなりました。1ヶ月前にその状態になっとけよなぁ〜頼むよぉ〜😢

音声の録音やビルド周りなど、難しい部分はほとんど@monryさんや@fakestarbabyさんにやっていただき、ランダムで生徒のキャラクターが生成されるアバター部分も@hanageman69さんにやっていただいて、簡単な部分を僕が書くといった程度だったので、次のアプリからはそういった部分も一人でできるように勉強していく所存です。

AssetBundleとか全然理解できていないですしね。

やる前の自分に教えておきたいこと

オーサリングツールは習うより慣れろ

UnityはC#から呼べるランタイムとオーサリングツールで成り立っています。実際はかなりの時間オーサリングツールを弄り回すことになるので概念理解もいいですが、どこに何があるのか、どこの機能を使えばどうなるのか、とにかく慣れです。

Photoshopの使い方をマスターすることを想像するとわかりやすいと思います。

UnityはあくまでHierarchy本位

プログラマー的には「C#で書けることをGUIからでも書けるだけでしょ?」と思いがちですが、Unityはそんなコード本位な思想ではなく、オーサリングツール上のGameObjectにHierarchyがメインで、C#コードはあくまで、

「GameObjectにつけることができる1コンポーネント」

という位置付け。そういった流儀だと理解しないと色々と分かりづらくなってしまいます。

Rider最高

JetBrains社製のC#のIDEであるRiderはUnityに最適。基本的な作法を指摘してくれるので特に勉強中の人間にとっては最高。すぐ買え。

静的型付けコンパイル言語の流儀に従え

言語入門経験が少ないと陥りがちですが、入門時に別言語のスタイルを無理矢理持ち込むのは理解の妨げになる。新しい言語を学ぶ時は郷に入っては郷に従え。

  • 暗黙的より明示的
  • 型をつけろstringにするな
  • クラスが増えることを恐れるな
  • コーディングはなるべくIDEに任せろ

rubyをvimで書いているときは頭の中で思い浮かべたコードをすばやくタイプしまくる感じですが、C# + Riderのときは自分の書いた原型をIDEにたびたび投げてコントロールを渡しつつすばやく補完し、指摘点の自動修正をしてもらって仕上げていく感じ。

感想

既に次のゲームの開発が始まっているのでゆっくりしてられませんが、Unityに入門してやってみてとっても良かったです。

やはり新しいことを学んでできることが増えるのは楽しいです。僕の場合、webでは新しい言語を覚えたといってもそれほどできることに違いはありませんが、webとゲームだと全く違うので感動もひとしおです。

まだ2Dゲームだけで3Dはさっぱりなのですが、個人的にも3Dのゲームを作ってみたいです。

もぐらが叩かれたときに★マークをパーティクルで飛ばすようにしました。

パラメーターのちょっとした変更だけでいろんな効果が作れるパーティクルはすごいですね。これはGUIならではの便利さと言った感じ。

そして得点を保存してランキング表示するようにしました。

PlayerPrefsというやつに保存しています。(iOSのNSUserDefaultsみたいなもん?)

PlayerPrefsはListとかは保存できないのでJSONにしてstringで保存。

これでもぐらたたきの課題としては一通り実装という感じかな?次は3Dを使ったものを作ってみたい。

soundflowerを使うことでQuickTime Playerで音声も取り込めるようになったので音入りで動画を取れるようになりました。

ただ、スクショみたいにアクティブなウィンドウを選択するとそのサイズがキャプチャされて欲しいがやり方がわからない。できないのかもしれない。

叩かれた時のモグラアニメーションやハンマーの効果音を追加。叩かれた時に★が散るようなパーティクルを付けたい。

それにしてもAnimatorの機能はすごい。GUIは少し迷ったけど、キャラの状態と各種アニメーションを紐付ける設計はわかりやすい。しかしExitは何なんだろう?別にExitに紐付けなくてもそこで終わるからどういう時に使うのかがわからなかった。

ゲームの点数など、ゲーム全体のデータはどうやって保存すべきか迷う。現在はとりあえず適当なクラスのpublic static変数に点数を保存してます。

次は点数を永続化してランキング表示をやる予定。

課題ゲームとしてはそれができたら一段落かな?

コードで動かしていたもぐらをAnimatorの使い方が分かったのでそちらで動くように変更。動きの試行錯誤はやはりタイムライン上の方がやりやすい。

次に出てくるまでの秒数をランダムにすることでゲームっぽくうごかしているんだけど、無茶な出方する場合があるので、こういう場合はどう制御するのがいいんだろう。

次はもぐらに当たり判定をつけたいです。

unityの勉強でもぐらたたきを作っております。

進捗は下記。

Webとゲームはよく出てくる用語も違いますね。Spriteぐらいは聞いたことあったけど、Maskとか発想がなかったんですが、教えてもらって上下するモグラを隠すMaskを追加することができました。

あと丸いタイマーをつけました。

Prefabというやつがいまいちわかってないです。クラスとインスタンスの関係に似てるようにおもうんだけど、Unity全体に渡って(Prefab自体も)どれがクラスでどれがインスタンスにあたるのかがイマイチわかっておりません。

次はランダムにもぐらが出てくるというのを作りたいです。

Unityのお仕事するかもなので、もぐらたたきゲームを作ってみようという課題をいただいて夜と土日を使って勉強しています。

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

public class MoleGenerator : MonoBehaviour {
    public GameObject molePrefab;
    public float diff = -2.28f;

    GameObject mole1;
    GameObject mole2;
    GameObject mole3;

    Vector3 startPosition1;
    Vector3 startPosition2;
    Vector3 startPosition3;

    void Start () {
        mole1 = Instantiate (molePrefab) as GameObject;
        startPosition1 = new Vector3 (-6.02f, -3.51f, 0);
        mole1.transform.position = startPosition1;

        mole2 = Instantiate (molePrefab) as GameObject;
        startPosition2 = new Vector3 (0.2f, -4.31f, 0);
        mole2.transform.position = startPosition2;

        mole3 = Instantiate (molePrefab) as GameObject;
        startPosition3 = new Vector3 (6.13f, -2.16f, 0);
        mole3.transform.position = startPosition3;
    }

    void Update () {
        Debug.Log (startPosition1.y);
        Debug.Log (mole1.transform.position.y);
        Debug.Log (startPosition1.y - mole1.transform.position.y);

        if (startPosition1.y - mole1.transform.position.y > diff) {
            mole1.transform.Translate (0, 0.08f, 0);
            mole2.transform.Translate (0, 0.08f, 0);
            mole3.transform.Translate (0, 0.08f, 0);
        } else {
            mole1.transform.Translate (0, -0.08f, 0);
            mole2.transform.Translate (0, -0.08f, 0);
            mole3.transform.Translate (0, -0.08f, 0);
        }
    }
}

もぐらが上にスーっっっ。

一定以上上にいったら下がるってやらないと。

同じもぐらが3匹いるからクラスにしたら良さそうですね。

後は、PCの性能に寄らずにスピードを調整したい。

さらに穴から出てくるまで隠しておく的なのはどうやるんだろう。