KLabGames Tech Blog

KLabは、多くのスマートフォン向けゲームを開発・提供しています。 スマートフォン向けゲームの開発と運用は、Webソーシャルゲームと比べて格段に複雑で、またコンシューマゲーム開発とも異なったノウハウが求められる領域もあります。 このブログでは、KLabのゲーム開発・運用の中で培われた様々な技術や挑戦とそのノウハウについて、広く紹介していきます。

この記事は、KLab Advent Calendar 2016 の17日目の記事です。はじめまして、morikenです。

昨日はjukey17さんのVRのゲームを作ってみて気をつけたことでした。

2016年はVR元年

さて、2016年は年始から盛んに「今年はVR元年だ」と言われていましたが、確かに一気にVRが普及したように感じます。

家庭用のVR機器がいくつも発売され、またVRを体験できる場所や機会も増えたことにより、VRの魅力を知った方も増えたと思います。

私自身も、VR ZONEでVRを体験してその魅力に取り憑かれ、PlayStation®VRももちろん購入し、日々バーチャル空間でサイリウムを振ったり、家庭教師の仕事をしたりして楽しんでいます。

ところで、面白いゲームをプレイすると、自分でも作ってみたくなるのがゲーム開発者の性です。そこで、VR元年が終わる前に、自分でもVRのゲームを作ってみることにしました。

VRゲームを作る前に

今回は初めてということで、普段から慣れ親しんだUnityで、スマートフォン向けVRゲームを作ることにしました。

ところが、スマホ向けのVRゲームを作る上で、ある問題に直面しました。それは、プレイヤーにどのようにゲームを操作させるか、です。

というのも、スマホVRでは専用のゴーグルにスマホをセットし、それを覗いてコンテンツを楽しみます。そのため、タッチパネルによる操作はほぼ行うことができません。

それゆえ、VRコンテンツの開発者たちは、ゴーグルに磁石を取り付けてスイッチ代わりにしたり、視線でUIを選択できるようにしたり、首を縦横に振る動きを利用したりと、色々工夫をしてきました。しかし、これらの操作方法では、複雑な操作をさせることは難しいです。

そんな時、自宅にむかし購入したBluetoothのキーボードがあることを思い出しました。Bluetoothなので、スマホとも接続できるはずです。キーボードを使うことができれば、プレイヤーに複雑な操作をさせることができます。

そして、キーボードを使ったゲームと言えば、思い浮かぶものは1つしかありません。

そう、タイピングゲームですね。

VRタイピングゲームの作成手順

手順は以下の通りです。

  1. タイピングゲームを作ります。

  2. 1.で作ったものをVRに対応します。

以上の2ステップです。簡単ですね。

タイピングゲームの作成

今回は、フィールドの中心にいるプレイヤーに向かって、周囲から襲いかかってくるモンスターをタイピングによって撃退するという、ベーシック(?)なタイピングゲームを作成しました。

プレイヤーを定点カメラにするのは、VRのデモ作品などによくある形式ですね。この形式は、周囲を 360° 見渡せるためVRと相性が良く、またカメラの移動がないため酔いづらい、というメリットがあります。

リソースにはUnity Technologies製のアセット、Survival Shooterを利用しました。

非VRのタイピングゲーム

VR対応

タイピングゲームがあらかた完成したら、次はVRに対応させます。

VR対応には、Google VR SDK for Unityを使用しました。Googleは以前、Google Cardboard SDKというSDKを配付していましたが、今年の8月に発表されたDaydreamに対応され、リニューアルされたようです。

VR対応はとても簡単で、UnityにインポートしたSDKに含まれるGvrViewerMain.prefabというPrefabをシーンに配置するだけです。これだけで下の画像のように、ゲーム再生時に自動で右目・左目用のカメラを配置し、VRゴーグルを通して見ることで、ゲーム内のオブジェクトが立体的に見えるようになります。

VR対応のデモ

VRでのUIの注意点

さて、VRゲームでは、非VRのゲームとは少しUIを変えなければいけません。

というのも、非VRゲームと同じようにUIを配置しても、UIが適切に表示されないためです。

例えばこのように、ゲーム内テキストと体力ゲージを模したUIを配置します。

オーバーレイのUI

ところが、これを再生すると、下のようにUIが左目、右目の領域にはみ出して表示されてしまいます。

オーバーレイのUI再生時

この問題を解決するため、カメラ画像にオーバーレイさせていたUIを、3D空間上に配置しましょう。

CanvasコンポーネントのRender Modeは、デフォルトではScreen Space - Overlayになっていますが、これをWorld Space に変更します。

Canvasコンポーネントの設定

すると、Canvas以下のUIコンポーネントが通常の3Dオブジェクトと同じようにワールド空間上に配置されるようになり、左目用・右目用の両方のカメラに描画されるようになりました。

VR対応されたUI

完成

こうして、無事にVRタイピングゲームが完成しました。

VR対応されたゲームのGIF

実際にプレイしてみた

さて、実際にプレイする上で、いくつか必要なものがあります。

まずは、Bluetooth接続できるキーボードです。このゲームはタイピングゲームなので、キーボードは必須です。

キーボード

次に、プレイ中はVRゴーグルを手で支えることができません。そのため、頭に固定できるタイプのものを用意する必要があります。

VRゴーグル

またモンスターは360°さまざまな方向から襲いかかってくるため、素早く周囲を見渡せるよう立ってプレイするのが最適です。その際にキーボードを手元に固定できるように、画板のようなものがあると便利です。

画板のようなもの

全て装備するとこのようになります。(本当は某ゲーム機を背負いたかったのですが、怒られそうなので諦めました。)

装備した様子

プレイしている様子です。遊んでいる本人はVRの世界に没入できてとても楽しいのですが、周りからは不審な目で見られるので、人目がないところでプレイするのが良さそうです。

プレイの様子

終わりに

ゲームのクオリティはさておき、VR対応ゲームはこのように簡単に作ることができます。興味を持たれた方はぜひチャレンジしてみてください。

一緒にこれからのVR業界を盛り上げましょう!

KLab Advent Calendar 16日目の記事です

はじめまして、jukey17です
Advent Calendarを書くのは初めてです
よろしくお願いします!

この記事に書いてあること

この記事では、jukey17がVRゲームを初めて作ってみて、気をつけた内容を簡単にまとめています

これからVRのゲームを作ってみようと思っている方の参考に少しでもなってもらえれば幸いです

VRのゲームを作ろうと思ったキッカケ

VR元年と言われた2016年 、個人でも楽しむことができるVR製品が次々に発表・発売されていき「VR製品買いました」「VR楽しい!」「VR凄い」という声が開発仲間の周りから少しずつ聞こえてくるようになりました

私自身全く興味がなかったわけではなく最初は体験ブースなどを見つけたら軽く遊んでみる程度の興味はありました
が、今一歩踏み込めないままでいました

そうこうしているうちについにはゲーム開発とはゆかりのない仕事をしている友人からもVRの話題が聞こえるようになってきてやっと ちょっとこれは実際に作ってみたほうがいいのでは? と思うようになりました

気がついたら今年も残りわずか、 このまま踏み込まないまま1年が終わってしまうのも勿体無い! と思い、VRゴーグルを購入しゲーム開発をはじめました

作ったゲーム 『World Jab VR』

image

正面から飛んでくるジャブ(パンチ)を左右に避けるゲームです
少し昔、TVで話題になっていた某ボクシング3兄弟の父親が行っていた練習の1つをモチーフにしました

このゲームは Google VR SDK for Unity(※以下SDK)を使ってUnityで作りました

ジャイロセンサーを使用して横の傾きを検出し、プレイヤー自身を左右に動かしてジャブを避けます
何回連続で避けられるかを競うゲームとなっています

初めてのVRゲーム開発だったのですが、実際に開発を進めていく中で気をつけたことの中でやってよかったと思った内容がありました

以下にその内容を紹介します

気をつけて良かったこと

先にUnityEditor上で遊べるようにした

私はまず初めに VRのゲームを作ろう! と勢い良くSDKのサンプルシーンを起動し、実機に転送して遊んで見るところからスタートしました

しかし、プロジェクトをビルドして、端末にバイナリを転送し、起動した状態で端末をVRゴーグルに装着して…
というのを 開発中に何度も繰り返すのはとても大変 だとすぐに気づきました

そこでまずはSDKの導入は一旦せず、UnityEditor上のみで動作が確認できるように開発をはじめました

とはいっても、SDKは簡単にゲームのVR対応ができるように GvrViewerMain.prefab をシーン上に配置するだけでVR対応が済むような構造になっているので、この対応は非常に簡単です

初めはUnity上で開発を進めていき、 ある程度遊べるようになってきたら対象のプレハブをひょいとシーンに置けば良いのです

但し、今回作った World Jab VR はゲームの仕様上プレハブの設置とセットでジャイロセンサーの入力機構も実装しなければなりません

ある程度遊べるようになってからも膨大な微調整の時間がかかるのは容易に想像できます

そこで更にもうひと工夫することにしました

入力操作方法を切り替えられるようにした

今回は3つの入力操作方法を切り替えられるようにしました

  • キーボード操作

PC(UnityEditor)想定
※先程のgifアニメーションがPC操作

  • ジャイロセンサー

スマホ(VR)想定

vr_play

  • タッチ操作

スマホ(非VR)想定

touch_play

最後のタッチ操作はキーボードとジャイロセンサーの出し分けを作ったときに「幾らでも新しいパターンが追加できるな」と思い、サクッと作ってみてしまった副産物です

この3つの入力操作方法は実行前に設定を切り替えられるようにしました

これのおかげで下記のような対応がとてもしやすくなりました

  • VRで遊んでいる間に問題が発覚!
    1. UnityEditorで動作を確認と問題を修正の繰り返し
    2. 修正が完了したらVRで再度遊ぶ
  • 新しい機能を追加したい!
    1. UnityEditorで機能の実装と微調整の繰り返し
    2. 実装が終わったらVRで最終チェック

一度VR対応したせいで細かい動作確認が億劫になり、開発スピードが落ちていく…なんてことは防げるはず!
(モチベーション維持は大事です)

今後の展望

UI上からのパラメータ調整・設定切り替え

いわゆるデバッグ機能です
現在はUnityEditor上のインスペクタから設定できるようにしています

しかしこれだと実機で動作確認したときに微調整をするために一旦UnityEditorに戻らなければなりません
大きな問題の修正や新機能の追加などプログラムを書き換えなければならない内容では仕方ないことですが、パラメータの調整やオプションの切り替えだけで済む内容なのであればなるべくUnityEditorに戻りたくありません

VRゴーグルを装着しているときは 視点ポインターで選択 できるようにしないといけないため歯応えがありそうな内容です

追加したい機能のアイデアももう思い浮かんでおりドンドンと実装をしたいところ...
もあるのですが、こういった 何度も繰り返し時間の掛かる部分は積み重なっていくとかなりの時間を消費していて開発スピードを下げる原因になる ため、足回りの部分の整備も怠らずに進めていきたいところです

ジャブを繰り出す側もプレイヤーにしてしまう

現状はAIが繰り出すジャブをひたすら避けるゲームになっていますが、通信機能を使って2人で遊べるように したら見栄えも含めてもっと面白くなりそうです

避ける側はVRゴーグルを装着、ジャブをする側はスマホにフリック操作してジャブを繰り出す

フェイント機能 などがあると駆け引きが増えて盛り上がりそうです

(※操作方法は暫定)

最後に

初めてのVRのゲームを作ってみましたが、どんな内容のゲームをつくるかを考える際に『どんな場所で遊ぶのか』『遊んでいる人は外から見てどのように見えているのか』など、 ゲームの内容の外側のことも気にしたりしながら作ったので予想以上に難しく・そして楽しかったです

今回は開発を始めていく中での気をつけておくと良いことを紹介しましたが、今後はそういった空間を含めたゲームデザインや新デバイスならではの技術に触れるような内容にもチャレンジしたいと思いました

以上です

この記事は KLab Advent Calendar 2016 の14日目の記事で @kakkun61 が担当します。

compile SDK version や build-tools version を Unity アプリで指定するにはどうすればいいの?という話をします。

この記事の内容は OS X 10.11.6 で確認しています。

Android アプリケーションのビルド時に指定するバージョンについて

Android アプリケーションのビルド時に指定するバージョンについては「基本をおさえる!Androidアプリで指定するバージョンについて(compileSdk,buildToolsVersion,....) - Qiita」にまとまっています。簡単に引用・要約します。

Android アプリケーションのビルド時に指定するバージョンは下記7つあります。

  • SDK バージョン
    • コンパイル SDK バージョン
    • 最小 SDK バージョン
    • 最大 SDK バージョン
    • ターゲット SDK バージョン
  • build-tools バージョン
  • Gradle の Android プラグインのバージョン
  • Gradle のバージョン
SDK バージョン
コンパイル SDK バージョン
コンパイル時に使用される Android.jar のバージョンでここにない API はコンパイルできません。build.gradle に記載します。値としては API レベルです。次の3つも同様です。
最小 SDK バージョン
インストールできる OS の下限で、条件付きコンパイル等しない限りこれより古い API は利用できません。build.gradle に記載します。
最大 SDK バージョン
インストールできる OS の上限です。build.gradle に記載します。
ターゲット SDK バージョン
OS がこの値を見て処理をし分けます。例えば UI テーマの変更や実質メニューキーの表示非表示があります。引用元記事にスクリーンショットがあります。build.gradle に記載します。
build-tools バージョン
その名の通り build-tools のバージョンで aaptaidldxjack.jarjill.jar などが含まれます。build.gradle に記載します。
Gradle の Android プラグインのバージョン
プロジェクトの build.gradle に記載します。
Gradle のバージョン
gradle/wrapper/gradle-wrapper.properties にダウンロード元 URL として記載します。

Unity 3D から生成した Android プロジェクトを Gradle でビルドする

Unity 3D を使って直接 APK を生成する場合、コンパイル SDK バージョンと build-tools バージョンを指定することができず、ビルドするコンピューターにインストールされている最新版が使用されます。これでは、ビルドサーバーを複数案件で共用している場合、案件ごとでこれらバージョンを固定してビルドすることができなくなります。なので、Unity 3D から Android プロジェクトを生成し、Gradle でビルドすることを考えます。

ただ、これではまだ問題があります。Unity 3D の生成する Android プロジェクトの形式が ADT 形式なのです。Google による ADT のサポートは終了しています。

これを Gradle でビルドするために Gradle ビルドスクリプトに少し工夫を加えます。

処理の流れ

  1. Unity エディターから Android プロジェクト(ADT 形式)を出力
  2. Gradle でビルドできるよう Gradle 関連ファイルのリンクを作成
  3. Gradle でビルドして APK 生成

ディレクトリー構成

下記のようなディレクトリー構成とします。サンプルリポジトリーはこちら

  • Assets/
    • Editor/
      • BatchBuild.cs
  • ProjectSettings/
  • gradle/
    • gradle/wrapper
    • build.gradle
    • gradlew
  • make-gradle-buildable.bash

BatchBuild.cs

バッチビルドでは Build() 関数を呼び出せば build-adt ディレクトリーに Android プロジェクトが生成されます(処理の流れ 1)。BuildOptions.AcceptExternalModificationsToPlayer を指定することで Android プロジェクトの生成を指定しています。その他のパラメーターは適宜変更してください。

using UnityEngine;
using UnityEditor;
using System.Linq;

public static class BatchBuild
{
    public static void Build()
    {
        EditorApplication.Exit(DoBuild());
    }

    static int DoBuild()
    {
        Debug.Log("Build Start");
        var options = BuildOptions.SymlinkLibraries
                      | BuildOptions.Development
                      | BuildOptions.AllowDebugging
                      | BuildOptions.AcceptExternalModificationsToPlayer; // このオプションでプラットフォームのプロジェクトが生成される

        var scenes = EditorBuildSettings.scenes.Where(s => s.enabled).ToArray();

        PlayerSettings.bundleIdentifier = "com.example.gradletest";
        PlayerSettings.bundleVersion = "1";
        PlayerSettings.productName = "Gradle Test";
        PlayerSettings.Android.bundleVersionCode = 1;
        PlayerSettings.Android.minSdkVersion = AndroidSdkVersions.AndroidApiLevel22;

        var errorMessage = BuildPipeline.BuildPlayer(scenes, "build-adt", BuildTarget.Android, options);
        if (string.IsNullOrEmpty(errorMessage))
        {
            Debug.Log("Build Success");
            return 0;
        }
        Debug.LogError("Build Failure");
        Debug.LogError(errorMessage);
        return 1;
    }

    [MenuItem("File/Export Android Project #%a")]
    public static void MenuBuild()
    {
        DoBuild();
    }
}

make-gradle-buildable.bash

処理の流れ 1 で、build-adt ディレクトリーに Android プロジェクトが生成されるので、Gradle でのビルドができるようにそこにファイルのリンクを置きます(処理の流れ 2)。prod_nameBatchBuild.csPlayerSettings.productName に指定されたものです。

#!/usr/bin/env bash -ex

prod_name=$(ls -1 build-adt)
ln -sFv "$(pwd)/gradle/"* "build-adt/$prod_name"

gradle/build.gradle

処理の流れ 3 のADT 形式のプロジェクトを Gradle でビルドするためのビルドスクリプトです。sourceSets の部分がキモで、各ソースファイルの位置を ADT 形式に合うように指定しています。他の部分は一般的な Android のビルドスクリプト同様に適宜変更してください。

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.example.gradletest"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    // Lint エラーが出てもビルドを継続するように指示
    // Unity の生成物が Lint にひっかかるので必須
    lintOptions {
        abortOnError false
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-unity.txt'), 'proguard-rules.pro'
        }
    }

    // ADT 形式のディレクトリー構成に対応するための記述
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.4.0'
}

ビルド手順

以上の準備をすると、下記コマンドでビルドができるようになります。生成された APK は build-adt/$prod_name/build/outputs/apk 以下にあります。./make-gradle-buildable.bash./gradlew build の実行は、Unity の post process build にしてしまうのもありだと思います。

/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -quit -executeMethod BatchBuild.Build
./make-gradle-buildable.bash
pushd "build-adt/$(ls -1 build-adt)"
  ./gradlew build
popd

↑このページのトップヘ