本日はHoloLens アプリの表現の実験枠です。
ここ何回かでHoloLens 2でのキャラクター表現に関する取り組みを行っています。
今回はHoloLens 2のHandTrackingを使用してキャラクターに触る表現を行います。
〇キャラクターとのインタラクション
VRMのキャラクターにはキャラクターのインタラクションを表現する様々なコンポーネントが用意されています。
[VRMLookAt]コンポーネントはキャラクターの目線を動かすコンポーネントです。

前回はこのコンポーネントを使用してHoloLens 2のEyeTrackingを使用してユーザーを見てくれる機能を作りました。
[VRMBlendShape]はキャラクターの表情(ShapeKey)を変化させるコンポーネントです。

前回は[Come On Smile!]というと笑ってくれる仕組みを作りました。
今回はVRMBlendShapeとHoloLens 2のHandTrackingを用いてキャラクターに触る表現を行いました。
〇スクリプト
今回以下のようなスクリプトを用意しました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRM;
using System;
using System.Linq;
using RootMotion.FinalIK;
public class VRMReactor : MonoBehaviour
{
//VRMData
[SerializeField] GameObject _vrm;
VRMBlendShapeProxy _blendShapeProxy;
VRMLookAtHead _vRMLookAtHead;
FaceAnimation FaceAnimation;
//UserData
Transform _usersTransform;
//Parameter
public bool isLookHead;
// Start is called before the first frame update
void Start()
{
if (_vrm == null)
{
_vrm = this.gameObject;
}
_blendShapeProxy = this.gameObject.GetComponent<VRMBlendShapeProxy>();
_vRMLookAtHead = this.gameObject.GetComponent<VRMLookAtHead>();
_usersTransform = GameObject.Find("UIRaycastCamera").transform;
FaceAnimation = this.GetComponent<FaceAnimation>();
VRIK vrik = _vrm.GetComponent<VRIK>();
Debug.Log(_usersTransform);
}
// Update is called once per frame
void Update()
{
}
public void HeadLook()
{
if (isLookHead)
{
isLookHead = false;
}
else
{
isLookHead = true;
}
}
public void VRMLookAtUser()
{
Debug.Log("Hoge");
_vRMLookAtHead.Target = _usersTransform;
}
public void VRMUnLookAtUser()
{
_vRMLookAtHead.Target = null;
}
public void BlendShapeChangeAngly()
{
resetBlendShape();
_blendShapeProxy.SetValue(BlendShapePreset.Angry, 1f);
FaceAnimation.ModulateRatio = 0f;
}
public void BlendShapeChangeFun()
{
resetBlendShape();
_blendShapeProxy.SetValue(BlendShapePreset.Fun, 1f);
FaceAnimation.ModulateRatio = 0f;
}
public void BlendShapeChangeJoy()
{
resetBlendShape();
_blendShapeProxy.SetValue(BlendShapePreset.Joy,1f);
FaceAnimation.ModulateRatio = 0f;
Debug.Log("Joy");
}
public void resetBlendShape()
{
_blendShapeProxy.SetValue(BlendShapePreset.Angry, 0f);
_blendShapeProxy.SetValue(BlendShapePreset.Fun,0f);
_blendShapeProxy.SetValue(BlendShapePreset.Joy, 0f);
FaceAnimation.ModulateRatio = 1f;
}
}
これは以前の記事でも使用したものです。これをVRMキャラクターにアタッチします。

〇Interactableコンポーネント
[Interactable]コンポーネントはMRTKで提供されているコンポーネントでアクション(Input)に対してリアクションを返すコンポーネントです。

[Interactable]コンポーネントは[Receivers]の[Event Receivers Type]に[InteractableOnGrabReceiver]を設定することでオブジェクトをつかんだ際のイベントを返すことができます。

VRMキャラクターのボーン構造に対応するようにコライダー付きのオブジェクトをアタッチし、Interactableコンポーネントをアタッチし、Grabのイベントに[VRMReaction]コンポーネントの任意の表情の関数を指定します。

キャラクターのボーンの子オブジェクトとして配置したオブジェクトはボーンに合わせて動きます。
今回はボーンに対して肉が付くようにコライダーのオブジェクトをアタッチしています。
最後にコライダーとInteractableコンポーネントをアタッチしたオブジェクトに[NearInteractionGrabbable]コンポーネントをアタッチします。これはHandTrackingによるGrabの動作を検知するコンポーネントです。

以上でユーザーがHandTrackingを使用してキャラクターを触ると表情が変化するようになりました。
〇実機で確認
実機で確認します。 手でキャラクターの顔を触るとくすぐったくて笑ってくれるようになりました。
例えば足、首や胸、脇など細かくコライダーを配置することで触る部位によって違う表情を返すことができます。
これでユーザーがキャラクターを触った際に自然な様子になるようになりました。