unity5でAndroidのセンサーを用いたゲーム作成

UnityでAndroidのセンサ情報の取得」で、オブジェクト「Cube」に対して、加速度センサー、地磁気センサー、ジャイロの各データを反映させましたが、今回は、unity5を使用し、Asset Store からaircraft「 Stealth Bomber」とskybox「sky5X」を取得して(いずれもFREE)、ゲームに組み込みます。また、Android端末の地磁気センサーとジャイロのセンサー情報をMain Cameraを子として持つオブジェクトに設定し、Android端末の傾きを、aircraft「 Stealth Bomber」に反映させます。

aircraft「 Stealth Bomber」を選択した場合のUnity画面を次に示します。
unity5ゲーム開発画面-Stealth Bomberの選択

MainCameraを選択した場合のUnity画面を次に示します。

unity5ゲーム開発画面-MainCameraの選択Stealth01

使用している各アプリ/ドライバのバージョンを次に示します。

  • Unity 5.6.3f1
  • AQUOS PAD SH-08E android 4.2
  • Android SDK(ADT 25) tools_r25.2.5-windows
  • Windows 7 Professional 32ビット版

Asset Store からaircraft「 Stealth Bomber」とskybox「sky5X」の取得

Unity には 3D モデルやテクスチャ、デモパッケージなどのさまざまな素材を簡単に購入してプロジェクトに取り込める「Asset Store (アセットストア)」が用意されています。今回は無料のaircraft「 Stealth Bomber」とskybox「sky5X」を取得します。Unity の 「Window」 – 「Asset Store」を選ぶとアセットストアのウィンドウが開きます。

aircraft「 Stealth Bomber」の取得

開いた画面の右上の検索ボックスに「aircraft」「free」を設定して検索ボタンを押し、表示された「Stealth Bomber」のアイコンを押すと次の画面が表示されます。

aircraft「 Stealth Bomber」の取得

インポートボタンを押すと、必要なファイルがダウンロードされ、表示された画面のimportボタンを押すとAssets領域にaircraft「 Stealth Bomber」がダウンロードされます。

skybox「sky5X」の取得

開いた画面の右上の検索ボックスに「skybox」「free」を設定して検索ボタンを押し、ソート「評価」を選択して表示された「sky5X One」のアイコンを押すと次の画面が表示されます。

skybox「sky5X」の取得

インポートボタンを押すと、必要なファイルがダウンロードされ、表示された画面のimportボタンを押すとAssets領域にskybox「sky5X」がダウンロードされます。

aircraft「 Stealth Bomber」の配置

Assets領域にダウンロードされたaircraft「 Stealth Bomber」の「Stealth_Bomber」をScene領域にドラッグ&ドロップすると、Scene領域にダウンロードされたaircraft「 Stealth Bomber」が表示されます。

skybox「sky5X」の配置

Assets領域にダウンロードされたaircraft「 Stealth Bomber」の「sky5X_skyboxes」の「sky5X2」をScene領域に表示されている「Main Camera」にドラッグ&ドロップします。「Main Camera」を選択すると、最初に図で示したようにInspector領域のSkyboxコンポーネントに「sky5X2」と設定され、Game領域に空の画像が表示されます。

Stealth Bomberの周囲でMain Cameraの回転

Main Cameraをその場で回転させてしまうとStealth Bomberが視界から外れてしまいます。Main Cameraの親となるオブジェクトを作り、そのオブジェクトごとに回転させると、任意の位置を基点にMain Cameraが回転する状態を作れます。

  1. 親子関係を作ります。まず、メニューから「GameObject」→「Create Empty」を選択します。
  2. 作成したGameObjectに名前「Camera Set」を付けます。
  3. Camera Setの位置を3Dモデルと同じ位置に移動させます。
  4. Main CameraをCamera Setにドラッグ&ドロップします。
  5. Camera Setを回転させると、モデルを基点に、次のようにカメラがその周りを回るように動きます。

    Main Cameraの回転

子として配置したオブジェクト「Camera Set」を選択してInspector領域の座標を確認すると、親から見た相対位置になります。

磁気センサーとジャイロのセンサー入力スクリプトの作成および設定

スクリプトを書いてSH-08Eの磁気センサーとジャイロのセンサーの角度をCamera Setの角度として適用します。

  1. Project領域で右クリック→「Create」→「C# Script」を選択し、ファイルに名前「Stealth」を付けます。
  2. Project領域に作成された「Stealth」をダブルクリックすると、エディタが起動するので、そこで次のスクリプトを編集します。
    using UnityEngine;
    using System.Collections;
    
    public class Stealth : MonoBehaviour
    {
        double lastCompassUpdateTime = 0;
        Quaternion correction = Quaternion.identity;
        Quaternion targetCorrection = Quaternion.identity;
    
        // Androidの場合はScreen.orientationに応じてrawVectorの軸を変換
        static Vector3 compassRawVector
        {
            get
            {
                Vector3 ret = Input.compass.rawVector;
                
                if(Application.platform == RuntimePlatform.Android)
                {
                    switch(Screen.orientation)
                    {
                        case ScreenOrientation.LandscapeLeft:
                            ret = new Vector3(-ret.y, ret.x, ret.z);
                            break;
                        case ScreenOrientation.LandscapeRight:
                            ret = new Vector3(ret.y, -ret.x, ret.z);
                            break;
                        case ScreenOrientation.PortraitUpsideDown:
                            ret = new Vector3(-ret.x, -ret.y, ret.z);
                            break;
                    }
                }
                
                return ret;
            }
        }
        
        // Quaternionの各要素がNaNもしくはInfinityかどうかチェック
        static bool isNaN(Quaternion q)
        {
            bool ret = 
                float.IsNaN(q.x) || float.IsNaN(q.y) || 
                float.IsNaN(q.z) || float.IsNaN(q.w) || 
                float.IsInfinity(q.x) || float.IsInfinity(q.y) || 
                float.IsInfinity(q.z) || float.IsInfinity(q.w);
            
            return ret;
        }
        
        static Quaternion changeAxis(Quaternion q)
        {
            return new Quaternion(-q.x, -q.y, q.z, q.w);
        }
    
        void Start () 
        {
            Input.gyro.enabled = true;
            Input.compass.enabled = true;
        }
        
        void Update () 
        {
                Quaternion gorientation = changeAxis(Input.gyro.attitude);
    
                if (Input.compass.timestamp > lastCompassUpdateTime)
                {
                    lastCompassUpdateTime = Input.compass.timestamp;
    
                    Vector3 gravity = Input.gyro.gravity.normalized;
                    Vector3 rawvector = compassRawVector;
                    Vector3 flatnorth = rawvector - 
                        Vector3.Dot(gravity, rawvector) * gravity;
     
                    Quaternion corientation = changeAxis(
                        Quaternion.Inverse(
                            Quaternion.LookRotation(flatnorth, -gravity)));
     
                    // +zを北にするためQuaternion.Euler(0,0,180)を入れる。
                    Quaternion tcorrection = corientation * 
                        Quaternion.Inverse(gorientation) * 
                        Quaternion.Euler(0, 0, 180);
    
                    // 計算結果が異常値になったらエラー
                    // そうでない場合のみtargetCorrectionを更新する。
                    if(!isNaN(tcorrection))
                        targetCorrection = tcorrection;
                }
     
                if (Quaternion.Angle(correction, targetCorrection) < 45)
                {
                    correction = Quaternion.Slerp(
                        correction, targetCorrection, 0.02f);
                }
                else 
                    correction = targetCorrection;
    
                transform.localRotation = correction * gorientation;        
        }
    }
    
  3. その後、「Stealth」を「Camera Set」にドラッグ&ドロップすると、Camera SetのInspector領域に次のようにコンポーネント「Stealth(Script) 」が適用されます。

    nspector領域のコンポーネント「Stealth(Script) 」

Android端末「SH-08E」へのダウンロードと実行

Unity で Bundle Identifier の設定とアンドAndroid端末での実行」に従って、アンドロイド端末用にゲームソフトをビルドし、Android端末「SH-08E」にダウンロードします。ゲームソフトが実行され、次のように、SH-08Eを回転するとStealth Bomberも同様に回転し、SH-08Eを傾けるとStealth Bomberも同様に傾きます。