しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

HoloLens 用に Unity で目の前に回り込んでくる動きを実装する

※ これは 2016/04/27 Unity HoloLens Technical Preview ver.5.4.0beta14(Windows版) 時点の情報です

最新版では動作が異なる可能性がありますのでご注意ください

こんな神イベントがみつばさんと田淵さんによって開催されるようです

私も参加応募したのですが抽選制なので行けるかどうか・・・

というわけで当選したときのために HoloLens でお試しできる Unity アプリを急きょ作ります

HoloLens は複合現実なので、目の前にねこが歩いてくる動作を作ってみました

まずは最新の開発環境インストール

手順的には上記と同じなのですが HoloLens Technical Preview がバージョンアップしていたので 5.4.0b14 にあらためてインストールし直しました

Unity の 3D プロジェクトを新規作成して上記記事にあるような HoloLens 用の設定を行います

ここから本題、まずは地面(Ground)や 3D ねこ(Hachiware, Point)とかを下記のような感じで配置

f:id:matatabi_ux:20160427052916p:plain

このあたりの Unity 一般の構成方法についてはすでにたくさん紹介されているので詳しくは省きますが、地面は Rendering Mode を Transparent にして Albedo の色のアルファ値を下げて新規作成した Material を適用して半透明にしました

f:id:matatabi_ux:20160427052832p:plain

ハチワレのねこは位置比較用で、ポインテッドのねこを今回カメラの目の前に動かすべく下記のような設定にしています

f:id:matatabi_ux:20160427042805p:plain

Rigidbody を追加し重力や物理演算を適用するようにしています

また Sphere Collider により一番処理負荷の低い球状のあたり判定を追加し、ねこが重力を受けても地面をすり抜けずとどまれるようにしました

あとはカメラの目の前に移動してくる ChaseCamera.cs というスクリプトを作成し追加しました

ChaseCamera のコードは次のような感じ

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Animator))]
public class ChaseCamera : MonoBehaviour
{
    /// <summary>
    /// メインカメラ
    /// </summary>
    private Camera mainCamera;

    /// <summary>
    /// 物理演算コンポーネント
    /// </summary>
    private Rigidbody rigid;

    /// <summary>
    /// アニメーター
    /// </summary>
    private Animator animator;

    /// <summary>
    /// 歩行中フラグ
    /// </summary>
    private bool isWalking = false;

    /// <summary>
    /// 初期処理
    /// </summary>
    public void Awake()
    {
        this.mainCamera = Camera.main;
        this.rigid = this.GetComponent<Rigidbody>();
        this.animator = this.GetComponent<Animator>();
    }

    /// <summary>
    /// 一定間隔で実行される更新ループ
    /// </summary>
    public void FixedUpdate()
    {
        // カメラの目の前 1.25 Unit(移動目標地点、1 Unit = 1 m くらいのはず? )の座標取得
        var frontPosition = this.mainCamera.transform.position + this.mainCamera.transform.forward * 1.25f;
        frontPosition.y = 0f;

        // ねこと目の前の位置の距離を算出
        var distance = Vector3.Distance(frontPosition, transform.position);

        // 歩行中でない場合
        if (!this.isWalking)
        {
            // 立ち止まってカメラの方に顔を向ける
            this.rigid.velocity = Vector3.zero;
            this.transform.LookAt(this.mainCamera.transform.position);

            // 距離が 0.3 Unit を超える場合
            if (distance > 0.3f)
            {
                // 歩行中にして歩行アニメーションに遷移
                this.isWalking = true;
                this.animator.SetBool("walking", true);
            }
            return;
        }

        // 歩行中の場合

        // カメラの目の前の位置(移動目標地点)にねこを[f:id:matatabi_ux:20160427044537g:plain]向ける
        this.transform.LookAt(frontPosition);

        // 距離が 0.1 Unit を超える場合
        if (distance > 0.1f)
        {
            // 移動方向を修正してさらに移動させる
            this.rigid.velocity = transform.TransformDirection(Vector3.forward) * 1.2f;
            return;
        }

        // 距離が 0.1 Unit 以内の場合、歩行中フラグをおろしてアニメーションをもとに戻す
        this.isWalking = false;
        this.animator.SetBool("walking", false);
    }
}

それほどコードを書かなくても実装できました

ここまでやったらまずは Unity Editor 上で動作確認

f:id:matatabi_ux:20160427052943g:plain

あざとくカメラの前まで歩いてますね!

これを UWP プロジェクトとしてエクスポートして HoloLens エミュレーター上で動かしてみました

f:id:matatabi_ux:20160427053133g:plain

現実ではありえないほどデレデレで目の前に回り込んでくるねこさん完成