【なるべく楽して】ゲームを製作・公開するまでの知見【Unity】

2018の大晦日unityroom にて3D脱出ゲーム「Pictures」を公開しました。

3D脱出ゲーム「Pictures」/ unityroom

簡単なプログラムなら組めるけど、グラフィック関係の知識は皆無。

そんな私が3Dの脱出ゲームをなるべく苦労せずに公開するまでの知見をまとめました。

  • ゲーム製作に興味がある。
  • プログラミングに興味がある。
  • Unityに興味がある。
  • でも苦労はしたくない。

そんな人が読んでみれば良いと思います。

1から100まで全部解説はできないので、足りない部分は調べながら補ってください。

制作に思い至るまで

私のプログラミングスキルは謙遜なしに普通です。

基礎的なところは分かるけど、複雑なアルゴリズムなどは扱えない。 AtCoder で言うと、C問題がちょうどいい難易度といった感じです。

この程度でも、ゲーム製作中にプログラミングで困ることはそれほど無いです。問題はグラフィックです。

過去数十年に渡るゲームの歴史で最も進化した部分はどこでしょうか?

おそらく答えはグラフィックです。

今やリリースされるゲームのほとんどが美麗なグラフィックでぬるぬる動作します。

ゲーム製作をしたい人にとってここが難関では無いでしょうか?

少なくとも私一人では、世の中で遊ばれているゲームほど綺麗なグラのゲームは作れません。 そもそも何がどうなってあんなにリアルになっているのか理解すらしていません。

それでも良いのです。今回はUnityというゲームエンジンを採用しましたが、 Unity は個人製作に非常に易しく、誰でも綺麗なグラのゲームが作れます。

Unity ってなに?

Unity とは無料で使えるゲームエンジンです。 そして、ゲームエンジンとはゲームを作るためのソフトです。そんな理解で良いと思います。

下の動画を見ると雰囲気が掴めるでしょう。

www.youtube.com

サンプルで動いているゲームはとても綺麗ですね。

すみません。さっきは綺麗なグラのゲームが簡単に作れるみたいに言いましたが、 上の動画ほど綺麗なグラフィックのゲームを作るのは簡単ではありません。

公式が公開しているようなゲームはプロがそれなりの人手と金と時間をかけて作っているので、クオリティが高いのは当然なのです。

大変なのは今回の主義に反します。我々はそこそこを目指しましょう。そこそこなら大丈夫です。

Unity でプログラミング

Unity でゲームを作るにはプログラミングが必要です。

ただ、よほどプログラミングに苦手意識がある人以外は大丈夫です。

普通のゲームならそこまで複雑なプログラムは必要ないからです。 実際、今回私が製作したゲームでも基礎的なところしか使いませんでした。

変数リストを理解していれば問題ないですし、構文もif文for文switch文 程度しか使ってないです。

クラス継承やコンストラクタなども使いましたが、調べれば山のように使い方が出てきます。

ここが大事な部分です。あなたが実装したい機能は既に誰かが作っています。 そして、そのやり方は解説されていると思って間違い無いでしょう。

それをパクれば良いのです。パクってるうちに自分でも書けるようになるのです。

最初からスマートにコーディングする必要は無いです。

冗長でも場当たり的でも動けば良い!動くのが大切です。 動かないのはゴミです。 スキルは長い時間をかけて、徐々に洗練していけば良いでしょう。

参考にするほどクオリティは高く無いですが、今回のゲームで作った機能などは当ブログの記事として残してあるので覗いてみてください。

teriyaki398.hatenablog.com

Unity でグラフィック

Unityアセットストアを活用する

Unity に触れたことがある人は知っていると思いますが、Unity にはアセットストアと呼ばれる素材の販売サイトがあります。

サイトに行けば分かりますが、ゲームに有用な素材などが大量に販売されています。
無料で使える素材も多いです。

ここから良い3Dモデルを探しましょう。これが一番早くて楽でクオリティも高いです。

例えばこれを見てください。

www.youtube.com

これは ArchVizPRO Interior Vol.6 という部屋と家具が内包された3Dモデルですが、今回のゲームではこれを使いました。

(通常価格50ドルとありますが、セールで半額になっていました。それでもまあまあ高いですが、 確実にそれ以上の価値があります。アフィリエイトでは無いのでリンクは貼りません。)

サイトで購入するとあなたのUnity で使えるようになります。

f:id:teriyaki398:20190101122025p:plain:w450

さらに、これらの3Dモデルは自由に使うことができます。 これらを好きに配置することで、自分なりの家が作れそうですね。

f:id:teriyaki398:20190101122631p:plain:w450

また、モデル以外にもマテリアル(テクスチャみたいな感じ)も自由に活用できます。

例えばUnity で下のような地面を作ったとします。無機質で真っ白な地面です。 (ゲームの種類によってはこれで良いかもしれませんが)

f:id:teriyaki398:20190101123220p:plain:w450

これに木目のマテリアルをつけると...

f:id:teriyaki398:20190101123349p:plain:w450

簡単にフローリングみたいな地面が作れます。また、石畳のマテリアルをつけると...

f:id:teriyaki398:20190101123500p:plain:w450

それっぽい地面ができました。

このようにUnity アセットストアで買ったものを活用することで、何一つ努力することなく、自分好みのゲームが製作できそうです。

巨人の肩に立つとはこのことです。

家具以外にも様々な種類のアセットがあるので、ぜひ一度アセットストアを見てみましょう。

全てを自分で1から作るのは大変です。カレーをスパイスの調合から作るようなものです。 市販のカレールーを買った方が簡単ですし、大抵の場合はそちらの方が美味しくできます。

Post Processing Stack を使う

Post Processing Stack とはその名前の通りポストプロセッシングを行うためのアセットです。 そしてポストプロセッシングとは、画面の見栄えを後から変える処理のことです。

Twitter やLINE で写真を送るときに後からエフェクトをかけて盛ったりしますよね? あれと全く同じことです。

現状Unity でポストプロセッシングを行うには、Post Processing Stack と呼ばれるアセットを用いるのが定番です。

assetstore.unity.com

これを活用することでグッと見栄えを良くすることができます。

Post Processing Stack には V1 とV2 がありますが、好きな方を使えば良いと思います。 良い感じにエフェクトをかけて見栄えを良くしましょう。

f:id:teriyaki398:20190102165357p:plain:w450
Post Processing Stack なし

f:id:teriyaki398:20190102165413p:plain:w450
Post Processing Stack あり

Post Processing Stack v1 を使おうとすると、MinAttributeがどうとかいうエラーが出ます(ver. 2018.3.0f2)

PostProcessing/Editor/PropertyDrawers/MinDrawer.cs 内のMinAttribute と書いてある箇所を全て UnityEngine.PostProcessing.MinAttribute に変更すると動作するようになります

これだけで、自分で全て製作するよりはずっと見栄えの良いゲームができると思います。

Unity で作ったゲームを公開する

作ったゲームを誰かに遊んでいただけるというのはとても嬉しいことです。

コミュニティの活性化にも繋がるので、クオリティの高い低いに関わらずぜひ公開しましょう

その公開の場としてunityroomがあります。 非常に簡単に投稿できる上に、安定してユーザーが集まっています。

フリーゲーム投稿サイト unityroom

ただし、私が今回投稿したゲームはあまりにも美麗なモデルを使いすぎてめちゃめちゃロードが長くなってしましました。 反省点ですね。

他にはAndroidiOS アプリとして、Playストアなどに公開することもできます。

unityroom よりは若干敷居が高いので、初めての人はunityroom が良いと思います。

(随時更新予定)

3D脱出ゲーム「Pictures」の攻略手順

unityroom で公開中の脱出ゲーム「Pictures」の攻略手順を残しておきます。

https://unityroom.com/games/escaping-game-pictures

詰まった時のための参考にしましょう。

具体的な内容は反転。

  • 白いロッカー(左下)の開け方

f:id:teriyaki398:20181230235304p:plain:w300

まずは写真のオブジェをクッションの下から拾う。

次に、机の上の写真を見ると、ロッカー風のボックスの台座に乗せられている写真が飾られているので、 同じように台座に乗せる。これでロッカーが開くようになる。

  • 白いロッカー(右上)の開け方

f:id:teriyaki398:20181230235513p:plain:w300

各スイッチをボックスに入っているカゴの位置に対応するように合わせる。

  • 大きい黄色いロッカーの開け方

f:id:teriyaki398:20181231000114p:plain:w300

部屋の中に各アイコンが描かれた絵があるので、それを探す。

絵の中に描かれている数が答えの数字に対応する。

ただし、ちょうちょのアイコンは斜めになっているので、同じ角度のちょうちょを数える必要がある。

  • 青いロッカーの開け方

f:id:teriyaki398:20181231000454p:plain:w300

上の画像の左に描かれている記号を用いる。

三角形、四角形、丸に数字を当てはめ、計算した結果が答えの数字になっている。 三角の数字は9 だが、最後の三角は反対向きになっているので、9 -> 6 に読み替える。

93 x 196 = 18228

三角の数字 : ソファーの左側 四角の数字 : 上の画像の右の絵をドライバーで外した壁 丸の数字 : 白いロッカーを開けた中のコイン

  • 黄色いロッカー(小さい方)の開け方

青いロッカーから手に入った謎の数独みたいな盤と、

カゴなどが入っているロッカーの裏側に落ちている盤を棒を使って取り出す。

これらの盤は組み合わせると数字の描かれた迷路になる。

迷路のスタートからゴールまで辿った数字が答えの数字に対応している。

  • 部屋からの脱出

青いロッカーから手に入れた鍵を使うと、部屋の扉が開けられる。

中にはパラグライダーの装備一式があり、手に入れられる。

これを用いて窓から脱出できる。

今回の製作にあたり知見などをまとめたので、こちらも参照していただければ幸いです。

teriyaki398.hatenablog.com

Twitterで自分が誰にどれくらい 「いいね」 されたのかを調べる方法

成果物

自分のツイートが過去にどのアカウントから何件の「いいね」を貰ったかをグラフにしてみた。

f:id:teriyaki398:20181117094456p:plain:w500

作成したコードはGitHubに公開してます。

github.com

環境

今回の目的

2018年11月、次の衝撃的なニュースが話題に。

www.itmedia.co.jp

なんと、ツイッターの「いいね」機能が無くなるかもしれないそうです。

多くの人がこの機能で承認欲求を満たしていることでしょう。私もそうです。

それなら今のうちに、自分のツイートがどれくらいファボをもらっているのか、
そして、どのアカウントから何件もらっているのかを調べておきたい!

実はこれ、簡単な事ではないです

Twitter公式が公開しているAPI を使えば、

  • 自分のツイート一覧
  • フォローしているアカウント一覧

などの様々な情報が取得できますが、肝心の特定のツイートにいいねしたアカウント一覧という情報は取得できないのです。

API についての詳しい説明は割愛します。取得できる情報はページ下部に載せておきます。)

すなわち、公式API では「いいね の合計数」は調べられますが、「いいね の内訳」は調べられないのです(詳しくはこちら

また、合計数を調べたいだけならわざわざAPI を使わなくとも、
自分のアカウントのアナリティクス からCSV形式のデータをエクスポートしてなんやかんやすればいけそうです。

Twitter Analytics

解決策1

という事でAPIを用いずに取得する方法で頑張るしかないです。

色々調べた結果、 stackoverflow で同じような質問があったので、そちらを参考にします。

記事内の関数はツイートidを入れるといいね元アカウントidリスト を返します。

stackoverflow.com

各ツイートにツイートid と呼ばれる識別番号が付与されており、それを与えると対象ツイートにいいねしたアカウントのリストが得られるという訳です。

つまり、基本的な方針としては

  • Twitter API を用いて自分のツイートid 一覧を取得する
  • 各ツイートid ごとに、いいねしたアカウントidのリストを取得する
  • アカウントid を集計する
  • matplotlib を用いてグラフを描画する

という感じでしょう。

note

アカウントid とは@xxxxx のようなやつとは別物です。各ユーザに振り分けられた数列で、普段目にすることはありません。@xxxxx のようなid はscreen name と呼ばれ、API を叩いてアカウントid からscreen name に変換することができます。

ただし、この方法では誰でも閲覧できるアカウントしか対象になりません。
すなわち、鍵垢(非公開のアカウント)からのいいねは統計に入らないのです。

解決策2

鍵垢からのいいねも含めて調べたい場合。

  • Twitter API で相互フォローしてるアカウントリストを取得する
  • 各アカウントが「いいね」したツイート一覧を取得する
  • その中で自分のツイートの数を集計する

みたいにする必要があります。

パッと見で気づくかもしれませんが、これはかなり素直(あほ)な実装で、かなり時間がかかります(笑)

回しっぱなしで気長に待てる場合や、
定期的に回してデータベースを更新していく。みたいな運用を想定している人向けでしょうね。

(試しに期間を今年分に絞って回してみたが、それでも2、3時間ぐらいかかった)

コードの詳細な説明は省きます。

note

当然のことですが、鍵垢を含めた検索は自分のアカウントでしか行えません。他のアカウントに来ているいいねの統計は公開アカウントからのもののみです。

役立ちそうな情報メモ

Twitter Developer アカウントの取得について

Twitter API を使うためには開発者用のアカウントを取得する必要があります。

Developer — Twitter Developers

いつの間にか仕様が変わっていて、取得がかなり面倒になっていました。

ただ、面倒と言っても適当に入力したらすぐに取得できました。

masatoshihanai.com

アカウントid リストの取得方法

元記事のプログラムは Python 2系 で書かれていたので、Python 3系 に少しだけ書き換えました。

def getUserIDList(self,post_id):
    """
    指定されたIDのツイートにいいねした人のIDリストを返す

    post_id : string
        調べるツイートID
    """
    # 一秒まつ
    sleep(1)
    
    try:
        json_data = urllib.request.urlopen(url='https://twitter.com/i/activity/favorited_popup?id=' + str(post_id)).read().decode("utf-8")
        found_ids = re.findall(r'data-user-id=\\"+\d+', json_data)
        unique_ids = list(set([re.findall(r'\d+', match)[0] for match in found_ids]))
        return unique_ids
    except urllib.request.HTTPError:
        return False

クラスのメソッドにしたのでselfが付いてます。

matplotlib でいい感じの円グラフ

いい感じの円グラフの作成には以下を参考にしました。

qiita.com

普通にやると色が足りなくなってしまうので、

temp = cm.Pastel1(np.arange(9))
col = []
for i in range(len(data)):
    col.append(temp[i % 9])

このようにして 9色 をデータの数だけループするような色リストを作成しました。それだけです。

注意点

こちらにも書いてあるが、リクエストの間隔は少なくとも 1秒 空ける必要がある。

そのため、結局全てのツイートを調べるには、少なくとも Tweet数 x 1 [sec]だけの時間がかかってしまう。

2000件くらいツイートしていれば 最低でも 2000秒はかかる。

また、ユーザーid : screen_name の解決も 1ユーザずつ行なっており、こちらも1秒ずつ間隔を空ける必要がある。よって、「ツイート数はそれほどでもないが、大量のアカウントからいいねされている」みたいな感じのアカウントもかなり時間がかかってしまう。

API で取得できる情報

APIでツイートを取得したとき、以下の情報が付随してくる。

キー 内容
created_at ツイートされた日時
id ツイートに一意に割り当てられるid
id_str id の 文字列
text ツイートの本文
truncated ツイート本文が長すぎて途中で切られたかどうか
entities ハッシュタグや画像・動画などに関する情報
extended_entities 複数の画像を取得したいとき
source どの端末からの送信か
in_reply_to_status_id (リプの場合)どのツイートへのリプライか
in_reply_to_status_id_str どのツイートへのリプライかの文字列
in_reply_to_user_id リプするアカウントのid
in_reply_to_user_id_str リプするアカウントのid の文字列
in_reply_to_screen_name リプするアカウントのscreen_name
user ツイート送信者の情報(JSON)
geo ツイートを送信したときの位置情報(非推奨らしい)
coordinates こちらも送信時の位置情報
place ツイートに関連付けられている場所情報(必ずしもこの場所からの送信とは限らない)
contributors アカウントを複数人で運営している時の話
is_quote_status 引用ツイートかどうか
retweet_count リツイートされた数
favorite_count いいねされた数
favorited 認証済みユーザーにいいねされたかどうか
retweeted 認証済みユーザーにリツイートされたかどうか
possibly_sensitive ツイートにリンクがあり、そのコンテンツが危険な可能性がある
lang 言語