Nuitrack 1.5.0
3D スケルトン トラッキング ミドルウェア
 すべて クラス 名前空間 関数 変数 Typedefs 列挙型 列挙子 プロパティ イベント グループ ページ
VR ボクシング ゲームの作成(aeroTAPではご利用になれません)

スケルトン トラッキングを使用した VR ゲームの作成を決めたが、何から始めたら良いかわからないということがあるかもしれません。その様な場合こそ、このチュートリアルで Nuitrack を使用した VRゲームの作成方法を学ぶことができます。VR ゲームでアバターのスケルトンに生気を与える方法を理解するには、「スケルトンを使用してアバターに生気を」のチュートリアルをご覧ください。

このチュートリアルでは、簡単な VR ゲームとして、ボクサーのアバターを使用し、ダミーをできるだけ強くパンチするゲームを作成します。パンチの最高速度が計測され、画面上部に表示されます。このゲームを作成するには、Nuitrack SDK、センサー (Nuitrack website のサポートしているセンサーの一覧にあるもの)、VR ヘッドセット (モバイル VR ヘッドセットまたは Gear VR ヘッドセット) が必要です。推奨される Unity のバージョン:2017.4 以上

完成済みプロジェクトは、 Nuitrack SDK: [Unity 3D] > [NuitrackSDK.unitypackage] > [チュートリアル] > [Box]

Ubox_9.gif

VR 環境とアバターの作成

  1. 新規 Unity プロジェクトを作成します。
  2. NuitrackSDK.unitypackageNuitrack SDK からインポートします。[Assets] > [Import package] > [Custom Package…]を選択します。作業に必要な以下のフォルダーにチェックを入れます。

    • Nuitrack (すべての Nuitrack モジュールを含み、スケルトン検出、トラッキング等を行います。このフォルダーには、VR ゲームに使用される Head プレハブと Nuitrack 自動キャリブレーションの設定ファイルも含まれています)
    • Platform Changer (指定されたプラットフォームに応じて、Unity 設定 (PlayerSettings) を変更します)
    • Plugins (アプリケーションの許可や他の設定の指定を行う Android Manifest ファイルが含まれています)
    • Resources (Platform Changer 設定を保存します)
    • [チュートリアル]の[Box] (このフォルダーがプロジェクトに必要なのは、Dummy プレハブを含んでいるからです。さらに、参照用の完成された VR ボクシング ゲームが含まれています)
    • [チュートリアル]の[Avatar Animation] (ボクサーを表示するために使用する Unitychan プレハブが含まれています)
    • VicoVRCalibrationRGB (T のポーズでのキャリブレーションに必要な要素がすべて含まれています。キャリブレーションは、すべての VR ゲームに必須です)
    注意
    Nuitrack は、Android と Gear VR に対して、改善された自動キャリブレーションを提供します。どんなジャイロスコープ(姿勢制御装置)にもみられる現象ですが、ゲーム時に頭を動かすと、位置がわずかにゆがみ、元の位置に戻らないために、ゲーム環境への影響が出てしまうことがあります。なんと、Nuitrack 自動キャリブレーション はこの厄介な現象を取り除いてくれます。デフォルト設定により、自動キャリブレーションは有効になっています。何らかの理由で、無効にしたい場合は、VicoVR アプリケーションを利用します。[設定] [開発者オプション] [自動キャリブレーション (オフ)]で設定します。
  3. 新規シーンを作成します。[File] > [New Scene]コマンドを使用します。次に挙げるプレハブをシーンにドラッグ アンド ドロップします。
    • NuitrackScripts (Nuitrack とそのモジュールを起動するための Nuitrack Manager を含む)、Current User Tracker (現在のユーザーのトラッキングを行う)、T-Pose Calibration (キャリブレーション設定を行う)、 Calibration Info (キャリブレーション設定を保存する)
    • RiggedAvatar2 (スケルトンのダイレクトマップ方式に必要な要素すべてが含まれています。このゲームでは、ダイレクトマップ方式を使用して、アバターに生気を与え、より正確で滑らかに動くよう調整します。ダイレクトマプ方式とインダイレクトマップ方式の違いについては、「スケルトンを使用してアバターに生気を」をご覧ください。
    • HeadParent (アバターの頭。頭の回転を定義するスクリプトとカメラを含みます)。
  4. VR ゲームの間、内側から見えないように、Unitychan プレハブの頭を隠すには、[Character1_Neck] > [変形] > [スケール] を (0; 0; 0) に設定します。

    Ubox_1.png
    頭を隠す

  5. NuitrackAvatar 設定で、HeadParentElement 16 にドラッグ アンド ドロップすることで、プレイヤーのアバターが頭を動かしてパンチをよけることができます。

    Ubox_2.png
    頭の設定
    注意
    プロジェクトのデフォルト プラットフォームは、Android です。プロジェクトをビルドする前に、プラットフォームを選択することができます。iOS、Android (デフォルト) または GearVR から選べます。選択するには、[Windows] > [プラットフォーム チェンジャー] > [ターゲット プラットフォーム] > [プラットフォーム変更]を使用します。
  6. プロジェクトを形成/組立て実行します。キャリブレーションが実行され、100% に達します。その後、アバターが正しく表示され、あなたの動きに対応して動いているか確認してください。
Ubox_3.gif
T のポーズでキャリブレーション

パンチング ダミーの設定

  1. アバターが作成できたので、今度は対戦相手であるパンチング ダミーの作成に入ります。PunchingDummy プレハブをシーンにドラッグ アンド ドロップします。
  2. 新しいスクリプト、PunchSpeedMeter.cs を作成します。このスクリプトでは、ダミーが出現するタイミングとパンチ速度に関連するすべての設定を調整/指定します。スクリプトに、ダミーのフィールドを作成し、ターゲット (脊椎の関節で、階層の中で最初に動く関節、かつ体の他の関節の動きにも影響する関節) を変形します。

    [SerializeField] GameObject dummy;
    [SerializeField] Transform transformTarget;

  3. スタートアップ時に実行される Awake メソッドを作成します: キャリブレーション時に表示されないよう、ダミーの動作を停止します。

    private void Awake()
    {
    dummy.SetActive(false);
    }

  4. OnEnable メソッドを作成します。PoseCalibration スクリプトを使用して、onSuccess イベントを登録します。キャリブレーションが完了すると呼び出されます。

    private void OnEnable()
    {
    TPoseCalibration.Instance.onSuccess += OnSuccessCalibration;
    }

  5. OnSuccessCalibration メソッドを作成し、求められている引数 (Quaternion rotation) を指定します。このメソッドでは、ダミーの最初の位置を指定します。ダミーは、キャリブレーション完了後に、プレイヤーから1m、エディターで設定したターゲットとなる関節から1m下の位置にスタンバイします (距離は自由に変更できます)。

    void OnSuccessCalibration(Quaternion rotation)
    {
    dummy.SetActive(true);
    transform.position = transformTarget.position + new Vector3(0, -1, 1);
    }

  6. OnSuccessCalibration イベントの登録解除を忘れずに行ってください。

    private void OnDisable()
    {
    TPoseCalibration.Instance.onSuccess -= OnSuccessCalibration;
    }

  7. スクリプトをダミーにドラッグ アンド ドロップします。Unity では、[ダミー]フィールドを[ダミー]に、[ターゲットの変形]フィールドを[Character1_Spine]に変更することで、ダミーがこの関節との関連で設定されます。

    Ubox_4.png
    パンチング ダミーの設定

  8. プロジェクトを実行し、ダミーが正しく表示されることを確認します。この段階では、ユーザー側の手の設定を行っていないので、ダミーをパンチできず、手はダミーを貫通してしまいます。
Ubox_5.gif
ダミーは、キャリブレーション後に表示されます。

パンチング ダミーを使用してパンチ速度を表示

  1. パンチングバッグ (サンドバッグ) ゲーム機で、パンチの力を計った経験はありますか?このプロジェクトでは、記録更新に何度でも挑戦できます。パンチの最高速度がダミーの頭の上に表示され、記録が更新される度に 数字は更新されます。PunchSpeedMeter.cs スクリプトに、UI 名前空間を追加します。これは、パンチの速度に関するテキスト情報を表示するために必要です。Text フィールドも作成します。

    using UnityEngine.UI;
    public class PunchSpeedMeter :MonoBehaviour {
    ...
    [SerializeField] Text speedMeterText;
    ...
    }

  2. PunchSpeedMeter クラスに、パンチの最高速度に関する情報を保存するための maximumPunchSpeed 変数を追加します。

    float maximumPunchSpeed = 0;

  3. CalculateMaxPunchSpeed メソッド (パンチ速度の処理を行う) を作成します。新しい速度が、現在の最高速度よりも早い場合にのみ、カウンターが更新されます。

    public void CalculateMaxHitSpeed(float speed)
    {
    if (maximumPunchSpeed < speed)
    maximumPunchSpeed = speed;
    speedMeterText.text = maximumPunchSpeed + " m/s ";
    }

  4. 新しいスクリプトPunchSpeedSender.cs を作成します。ダミーの体の数か所 (TorsoBoneNeckBone) をパンチする可能性があるので、パンチを受け止めてくれるセコンドが必要です。これらの部位をパンチした場合、PunchSpeedSender はその情報をPunchSpeedMeter に送ります。このスクリプトでは、 PunchSpeedMeter に言及し、OnCollisionEnter メソッドを作成します。2つのオブジェクトが衝突する場合、相対的なパンチ速度が提示されます。

    public class HitSpeedSender :MonoBehaviour {
    [SerializeField] HitSpeedMeter hitSpeedMeter;
    private void OnCollisionEnter(Collision collision)
    {
    hitSpeedMeter.CalculateMaxHitSpeed(collision.relativeVelocity.magnitude);
    }
    }
    注意
    relativeVelocity プロパティが、2つのオブジェクトの衝突速度を正しく測定することを可能にします。この場合、2つのオブジェクトとは、Unitychan の拳とダミーです。拳の速度のみを測定した場合、正しい値を得ることはできません。relativeVelocity に関する詳細は、こちらをクリックしてください。
  5. Unity の設定で、このスクリプトをTorsoBoneNeckBone にドラッグ アンド ドロップします。[パンチ速度メーター]フィールドで、 PunchSpeedMeter を指定します。

    Ubox_6.png
    パンチ速度メーター設定

  6. Unity で、プレイヤーのアバター用ボクシング グローブとなる 2つのオブジェクトを作成します。作成には、[作成] > [空のオブジェクト] > [左のグローブ]と[右のグローブ]のコマンドを使用します。実際は、素手でダミーをパンチしますが、仮想のボクシング グローブを付けることで、パンチ速度を測定できるようになります。必要な構成要素を追加するには、[要素の追加]を使用します。[カプセル コライダー]、[RigidBody]を調整することで、衝突を正しく扱うことができます。腕の動きに合わせてグローブがどの方向に動くか設定するには、[カプセル コライダー] > [方向] > [X軸] のコマンドを使用します。グローブの位置とサイズを指定します。[高さ]を 0.2 (最適値)、[直径]を 0.05 に設定します。グローブを表示させたい場合は、プレハブを作成し、上記の設定を適用します。

    Ubox_7.png
    グローブのセットアップ

  7. スクリプト RigidbodyFollower.cs を作成し、グローブの動作を指定します。target フィールドを作成し、グローブが追いかけるターゲット オブジェクト (ここでは、プレーヤーを示すアバターの手) を指定します。さらに、rigidbody フィールドを作成します。

    public class RigidbodyFollower :MonoBehaviour
    {
    [SerializeField] Transform target;
    Rigidbody rigidbody;
    }

  8. ゲーム開始時に、カプセルに関連付けられている Rigidbody へのレファレンスを受け取ることになります。

    void Start()
    {
    rigidbody = GetComponent<Rigidbody>();
    }

  9. FixedUpdate メソッドを作成します。このメソッドでは、カプセルの動作を指定します。ターゲットの変形に応じて、位置や回転が変わります。このプロジェクトで、transform.position dehanaku MovePosition を使用しているのは、アバターのグローブが RigidBody Physics を使用して動くはずだからです。簡単な位置の変更が間違って処理されることがあるのは、変形が物理法則を無視して転送されるからです。

    void FixedUpdate()
    {
    rigidbody.MovePosition(target.position);
    rigidbody.MoveRotation(target.rotation);
    }
    注意
    FixedUpdateUpdate の代わりに使用するのは、Rigidbody を使う可能性があるからです。
  10. スクリプトを左右のグローブにドラッグ アンド ドロップし、[ターゲット]を指定します(Character1_LeftHand, Character1_RightHand)

    Ubox_8.png
    Rigidbody Follower のセットアップ

  11. プロジェクトを実行し、ダミーをパンチします。表示されるパンチ速度を確認します (ダミーの頭の上に表示)。記録更新に挑戦してください!

    Ubox_9.gif
    やっつけてしましましょう!

    おめでとうございます!スケルトン トラッキングを使った VR ボクシング ゲームの完成です!