OculusTouchとモデルを連動させる

概要

  • プロジェクトを作成し、モデルとモーションの準備
  • Unity 上で VR デバイスを使用できるようにする
  • Humanoid リグの設定されたモデルを Oculus Touch の動きに連動させる
  • 画面内に自分を映したモニタ映像を表示させる

やる気出ない

 度々やる気が出たり出なかったりの波が激しくなることがあり、今猛烈にやる気出ないです。やる気が出ないので無理やり手を動かしてみます。とりあえず手を動かすと案外体は動くものですね。よしがんばって Oculus でキャラクターを動かしてみるぞ。

プロジェクトを作成し、モデルとモーションの準備

  • Unity3D を起動します

  • New

  • プロジェクト名を適宜入力し、Create project

 今回も新規プロジェクト作成から進めていきます。新規プロジェクトを作成したらとりあえず必要な素材として Humanoid モデルとアイドリングモーションをインポートします。 モデルは以前作成しためがみん素体を使用します。アイドリングモーションはアセットストアから MORRO MOTION の Idle MoCap を使用する事にします。

  • Project ビューの何もないところを右クリックして Create → Folder
  • フォルダ名を Models に設定する

  • 先ほどダウンロード・解凍した FBX ファイルを Project ビューの Models フォルダへドロップする

  • Project ビューの Models フォルダを展開し、インポートした FBX をクリック
  • Inspector ビューの Rig をクリック
  • Animation Type プロパティを Humanoid に設定し、 Apply

  • Window → Asset Store

  • Asset Store ビュー検索窓で Idle MoCap を入力して Enter

  • Asset Store ビュー検索結果ページを下にスクロールさせ、Idle MoCap をクリック

  • Asset Store アセット詳細ページを下にスクロールさせ、ダウンロードをクリック

  • Import

  • Project ビューの Models フォルダを右クリックし、Create → Animator Controller
  • コントローラ名を MegaminController に設定

  • Project ビューの MegaminController をダブルクリックし、Animator ビューを開く

  • Animator ビューの Base Layer の歯車マークをクリック
  • IK Pass をチェック

  • Project ビューの Idle MoCap フォルダを展開し、Idle stance 2 モーションを Animator ビューにドロップし、ステートを追加する
  • 自動的に Entry ノードからリンクが作成される(リンクというか、transition?)

  • Hierarchy ビューのモデルオブジェクトをクリック
  • Project ビューの MegaminController を Inspector ビューの Controller プロパティへ設定する

  • 実行してみてモーションが適用されていれば OK

次に色々制御するのに都合を良くするために、モデルオブジェクトに親階層を作成することにします。

  • Hierarchy ビューの何もないところを右クリックし、Create Empty
  • 作成された GameObject をクリックし、Inspector ビューで名前を MegaminRoot に設定
  • Transform の値が Position 及び Rotation の値が全て 0、Scale の値が全て 1 になっている事を確認する(なっていなければそれぞれ 0、1 に設定)

  • Hierarchy ビューのモデルオブジェクトを MegaminRoot にドロップし、MegaminRoot の子ノードに設定

次に、Oculus Rift ヘッドセットと Touch コントローラをトラッキングするオブジェクトを追加します。

  • Hierarchy ビューの MegaminRoot を右クリックし、Create Empty を3 回実行し、空のゲームオブジェクトを 3 つ作成する
  • 作成した GameObject をリネームし、それぞれ Head、RightHand、LeftHand に設定

Unity 上で VR デバイスを使用できるようにする

 モデルの準備ができたので、次は VR デバイスを使用できるようにします。うちは HTC Vive と Oculus Rift + touch を持ってますが、今回は Oculus を使用する前提で進めていきます。

  • Edit → Project Settings → Player

  • Inspector ビューの XR Settings を開き、Virtual Reality Supported をチェックする

これだけで、プログラムの実行で Oculus に実行結果が表示されるようになります。
次は、制御用のスクリプトを作成します。

  • Project ビューの何も無いところを右クリックし、Create → Folder
  • 新規フォルダ名を Scripts に設定

  • Project ビューの Scripts を右クリックし、Create → C# Script
  • 作成したスクリプト名を IKController に設定し、ソースコードを下記の通り編集する
using UnityEngine;
using UnityEngine.XR;

[RequireComponent(typeof(Animator))]
public class IKController : MonoBehaviour {

    protected Animator animator;
    public bool ikActive = false;
    public Transform rightHandObj = null;
    public Transform leftHandObj = null;
    public Transform headObj = null;

    void Start() {
        animator = GetComponent<Animator>();
        XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);
    }

    void Update() {
        // Rキーで位置トラッキングをリセットする(Stationaryでしか動作しない)
        if (Input.GetKeyDown(KeyCode.R)) {
            InputTracking.Recenter();
        }
    }

    void OnAnimatorIK() {
        if (animator) {

            //if the IK is active, set the position and rotation directly to the goal. 
            if (ikActive) {
                // Set the look target position, if one has been assigned
                if (headObj != null) {
                    animator.SetLookAtWeight(1);
                    animator.SetLookAtPosition(headObj.position);
                }

                // Set the right hand target position and rotation, if one has been assigned
                if (rightHandObj != null) {
                    animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
                    animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
                    animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
                    animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
                }

                // Set the left hand target position and rotation, if one has been assigned
                if (leftHandObj != null) {
                    animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
                    animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
                    animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandObj.position);
                    animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandObj.rotation);
                }

            }

            //if the IK is not active, set the position and rotation of the hand and head back to the original position
            else {
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);
                animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 0);
                animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 0);
                animator.SetLookAtWeight(0);
            }
        }
    }
}

  • Project ビューの IKController を Hierarchy ビューのモデルにドロップし、コンポーネントをオブジェクトに紐づける

Humanoid リグの設定されたモデルを Oculus Touch の動きに連動させる

 モデルの動きを Oculus のトラッキングに連動させるために、Oculus SDK を使用します。

  • Unity をクリック

  • Oculus Utilities for Unity をクリック

  • I have read and agree to the terms of the EULA, Terms of Use and Privacy Policy を確認し、チェックする
  • Download をクリック

  • ダウンロードしたファイルを展開する

  • 展開した圧縮ファイル内の OculusUtilities.unitypackage をダブルクリックする

  • Import

  • 何気に新しいバージョンのプラグインが出てるそうなのでここは Yes

  • エディターの再起動を提案されたので、ここは素直に従って Restart

  • シーンのセーブをするか問われたのでここは当然 Save

  • 新しいフォルダー

  • フォルダ名を Scenes に設定し、ダブルクリックしてフォルダ内へ移動

  • VTuberTest という名前で保存する

この後、UnityEditor が再起動します。

  • Project ビューの OVR / Prefabs フォルダを展開し、OVRCameraRig を Hierarchy ビューの MegaminRoot にドロップする

  • めがみんモデルのサイズがちょっとバカでかかったので、身長 155cm くらいにするためにスケール値を 0.335 くらいに設定する

  • Hierarchy ビューの Head を CenterEyeAnchor にドロップする

  • Head オブジェクトをモデルの注目点として使用するため、CenterEyeAnchor よりちょっと前方に移動させておく
  • Hierarchy ビューの Head をクリックしInspector ビューの Transform を Position = (0, 0, 10)、Rotation = (0, 0, 0)、Scale = (1, 1, 1)に設定

  • Hierarchy ビューの OVRCameraRig をクリック
  • Inspector ビューの Transform を Position = (0, 1.5, 0)に設定
  • Trancking Origin Type を EyeLevel に設定

  • Hierarchy ビューのモデルオブジェクトをクリック
  • Inspector ビューの IK Active をチェック
  • Hierarchy ビューの Head を Inspector ビューの Head Obj にドロップ
  • Hierarchy ビューの RightHandAnchor を Inspector ビューの Right Hand Obj にドロップ
  • Hierarchy ビューの LeftHandAnchor を Inspector ビューの Left Hand Obj にドロップ

以上で最低限の挙動が設定できたはずっ

  • 実行してみる

おぉ、動いた!!

ただ、まだまだ問題点があるのでこれからはちょっと色々微調整が必要そうです。

  • 座った姿勢の状態で収録できるように、EyeLevel に設定したものの、初期位置がどうも床に合わせられてるような気がする
  • 初期位置が OVRCameraRig を設定した位置よりも前に移動してるような気がする
  • でもまぁ立って自分が位置を微調整すれば済む事なので(いやそれよくないだろ)

でもまぁ、動いたのでよしとします。次は、バーチャル空間内で自分の姿が見れるように設定します。

画面内に自分を映したモニタ映像を表示させる

 で、とりあえず Oculus でモデルを制御するところまでは出来ましたが、自分がどんな風に映っているのかがわからないので、シーン内に自分の姿を表示させるようにします。具体的にはこんなイメージです。

具体的には、シーン内にカメラを設置し、レンダーテクスチャにレンダリングし、シーン内にレンダーれくすちゃを張り付けたオブジェクトを配置します。ではやってみましょう。

  • Project ビューの何もないところを右クリックし、Create → Render Texture
  • 作成した RenderTexture の名前を VRCamera に設定

  • プロジェクト作成時に元から存在していたカメラを流用します
  • Hierarchy ビューの Main Camera を選択し、Inspector ビューの Audio Listener の歯車マークをクリックし、Remove Component をクリックして、Audio Listener を削除
    • Audio Listener OVRCameraRig 以下のカメラオブジェクトにも存在しているため、重複したものを削除する必要があるというのが理由

  • Hierarchy ビューの Main Camera をクリック
  • Project ビューの VR Camera を Inspector ビューの Target Texture にドロップ

  • Hierarchy viewの Main Camera を CenterEyeAnchor にドロップ

  • Hierarchy ビューの Main Camera をクリック
  • Inspector ビューの Transform を Position = (0, -0.5, 3)、Rotation = (0, 180, 0)に設定
  • これで、自分の視線の先にカメラがあり、常に自分を映している状態になる

  • Hierarchy ビューの CenterEyeAnchor を右クリックし、3D Object → Plane をクリック

  • Hierarchy ビューの Plane をクリック
  • Inspector ビューの Transform を Position = (0, 0, 10)、Rotation = (270, 0, 0)、Scale = (1, 1, -1)に設定
  • Project ビューの VR Camera を Hierarchy ビューの Plane にドロップ

  • 実行してみる

おおお、映ったわ。

ここまでできたら後は簡単(多分)

 とりあえずこれで最低限な仕組みはできましたが、色々と気になる点はあります。

  • Oculus SDK を使っているので、他の XR デバイスに対応させる時はまた考えないといけない
  • 直接 Oculus のコンポーネントを突っ込むのではなく、いったん何かのオブジェクト経由でトラッキング情報を持ってきた方が良いと思う
  • 動画収録用のウインドウを別途表示させたいので、あともうひとつカメラが必要かもかも
  • 次はシーンの作り込みとかも必要ですね
  • あれもやりたいこれもやりたい

と、色々夢が膨らんできたところで今日はここまで。

ではまた!

ツイートツイート