Unity+OculusRift+LeapMotionで3Dキャラクターに触れる

  • 29
    Like
  • 2
    Comment
More than 1 year has passed since last update.

デモ

こんな感じのを作りました。

画像:
demo.jpg

動画:
OculusRift & LeapMotion with Hatsune Miku

材料

  • Unity v4.3.1(Oculusを使うにはProライセンスが必要)
  • Oculus Rift, Oculus SDK v0.2.5c : Unity 4 Pro Integration
  • Leap Motion, Leap Motion SDK v1.0.9
  • MikuMikuDance for Unity (バージョン不明。たぶん master branch から last commit d944c94063 のものを使った)

以下は各人のお好みで

*各バージョンは制作時のもの

作り方

材料を混ぜる

各材料をDLしたらUnityプロジェクトに放り込みます。

それぞれの放り込み方は各ダウンロードしたファイルに添付されているreadmeファイルや以下を参照。

特定の部位に触れるようにする

LeapMotionで触れるのは下図のPhysicsの部分。
physics.png

LeapMotion SDK から引っ張ってきたResources > Prefab > LeapFinger >Tip にアタッチされている Collider の Is Trigger を OFFにする。

これでキャラクターに触れるようになります。

触れると反応を返すようにする

まず空のGameObjectを作る。名前はとりあえず”Controller”とする。
そしてその"Controller"に以下のコードをアタッチする。

AnimationScript.cs
using UnityEngine;
using System.Collections;

public class AnimationScript : MonoBehaviour {

    public GameObject miku = null;
    private Animation mikuAnime;

    // Use this for initialization
    void Start () {
        if (miku == null)
            return;

        mikuAnime = miku.GetComponent<Animation>();
    }

    // Update is called once per frame
    void Update () {
    }

    public void touch(AnimationClip clip) {
        mikuAnime[clip.name].wrapMode = WrapMode.Once;
        mikuAnime[clip.name].layer = 2;
        mikuAnime.CrossFade(clip.name);
    }
}

Mikuには下図のようにアニメーションさせるGameObjectを設定する。
controller.jpg

次に反応を返したい部位(Physicsの下にある)に以下のコードをアタッチする。

TouchMessage.cs
using UnityEngine;
using System.Collections;

public class TouchMessage :   MonoBehaviour {

    public AnimationClip  animationClip = null;
    private GameObject controller = null;
    private float timer = 0.0f;

    // Use this for initialization
    void Start () {
        controller = GameObject.Find("Controller");
    }

    // Update is called once per frame
    void Update () {
        if (timer > 0)
            timer -= Time.deltaTime;
    }

    private void OnCollisionEnter(Collision collision) {
        if (animationClip == null)
            return;

        if (timer > 0)
            return;

        if (collision.gameObject.CompareTag("FingerTip")) {
            controller.SendMessage("touch",animationClip);
            timer = animationClip.length;
        }
    }

}

animationClipには下図のように反応させたいアニメーションを設定する。
touch.jpg

この方法だといちいち衝突時にどこの部位と衝突したかをif文等で判定する必要がなくて楽ちんです。
ですが、複数の反応箇所に触った時の排他制御を書いていないのでその辺りもしっかり書いておきたいところです。
このままでもUnityさんがよしなにやってくれるので放っておいてますが反応箇所が多くなるとよくないことが起きそうな気がします。

これで無事に反応を返してくれるようになりました。
以上となります。お読みいただきありがとうございました。

謝辞

各ツール・データ・開発情報を公開されている皆様に感謝の意を表します。
これらがなければ私では到底開発できません。ありがとうございます。