MRが楽しい

MRやVRについて学習したことを書き残す

ユニティちゃんが障害物をジャンプする

さて今回はもっとMRらしいチャレンジです。
前回の記事ではユニティちゃんがカメラに向かって自動で移動し続けるスクリプトを作成しました。
しかし、現実世界を歩かせてみると様々な障害物があり、一筋縄ではカメラ位置にたどり着けません。

という訳で、障害物をジャンプするという機能を追加しました。
今回は参考記事はありません。
ただ技術としては以下の記事で学んだ、アタリ判定の応用となります。
・こっち向いて機能の実装
 http://unimake2.blog.fc2.com/blog-entry-21.html

こちらの記事ではカメラが近づいたことを衝突判定により、検知していました。

今回は以下のようにユニティちゃんの膝の辺りにアタリ判定を作成しました。
f:id:bluebirdofoz:20170415012057j:plain
膝に物体がアタリ続ければ、障害物により移動が阻害されていると判定してジャンプする。
ロジックとしてはそれだけです。


ではユニティちゃんの手前に障害物を置きます。
f:id:bluebirdofoz:20170415012133j:plain
「here」とユニティちゃんに声をかけて、こちらへの自動移動を開始すると…
f:id:bluebirdofoz:20170415012142j:plain
障害物をジャンプして超えてきました。成功です。

ジャンプの際に、ユニティちゃんのアタリ判定(CapsuleCollider)も変更させることを忘れないでください。
アタリ判定が変わらないと、見た目がジャンプしているだけで、障害物は飛び越えられません。
判定の変更方法はユニティちゃんに付属しているUnityChanControlScriptWithRgidBody.csが参考になります。


更にもう一つアタリ判定を追加し、カメラに近寄った際は勝利ポーズを取るようにしてみました。
f:id:bluebirdofoz:20170415012156j:plain
カメラ(hololens)に一定距離まで近づくと、ポーズと共に「捕まえた!」と言います。
より鬼ごっこっぽくなりましたね。


アタリ判定のJumpCubeには以下のスクリプトを自作し、追加しています。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JumpCollider : MonoBehaviour {

    AudioSource audioSource = null;
    XboxOneController xboxOneController = null;
    HeadLookController headLookController = null;

    public string searchTarget = "MainCamera";
    public GameObject messageTarget;

    public AudioClip impactClip = null;
    public AudioClip impactClip2 = null;
    public float impactVolume = 0.5f;

    public SkinnedMeshRenderer MthDef;

    public int colCountBorder = 100;
    int colcount = 0;
    int trycount = 0;

    // Use this for initialization
    void Start()
    {
        audioSource = messageTarget.GetComponent<AudioSource>();
        xboxOneController = messageTarget.GetComponent<XboxOneController>();
        headLookController = messageTarget.GetComponent<HeadLookController>();
        colcount = 0;
        trycount = 0;
    }

    void OnTriggerEnter(Collider col)
    {
        // 衝突対象が検索対象以外ならば実行
        if (col.tag != searchTarget)
        {
            // 自動操作中ならば実行
            if (xboxOneController.moveAwayCamera || xboxOneController.moveToCamera)
            {
                colcount = 0;
                trycount = 0;
            }
        }
    }

    void OnTriggerStay(Collider col)
    {
        // 衝突対象が検索対象以外ならば実行
        if (col.tag != searchTarget)
        {
            // 自動操作中ならば実行
            if (xboxOneController.moveAwayCamera || xboxOneController.moveToCamera)
            {
                colcount++;
                // 敷居値以上の衝突が継続すれば実行
                if ((trycount == 0) && (colcount > colCountBorder))
                {
                    xboxOneController.superjumpFlg = true;
                    audioSource.clip = impactClip;
                    audioSource.Play();
                    colcount = 0;
                    trycount++;
                }
            }
        }
    }

    void OnTriggerExit(Collider col)
    {
        // 衝突対象が検索対象以外ならば実行
        if (col.tag != searchTarget)
        {
            // 自動操作中ならば実行
            if (xboxOneController.moveAwayCamera || xboxOneController.moveToCamera)
            {
                colcount = 0;
                trycount = 0;
            }
        }
    }
}

衝突判定をカウントし、敷居値を超えればControllerのジャンプフラグをONにします。
ジャンプフラグONのときのジャンプ動作は前回のXboxOneController.csに合わせて仕込んでおきます。

横着してここでジャンプ時の音声再生を行っています。
本来ならばモーションにイベントを仕込んで、そこから音声を再生するのがより賢いやり方です。