Edited at

NavigationとManipulationの違い

More than 1 year has passed since last update.


はじめに

3月初めよりインターンで株式会社ゆめみ(https://www.yumemi.co.jp/ja) にてHoloLensの研究開発をしている近大生のよっしーです。

国内でこの1月から提供を開始したMicroSoft製MRデバイスのHoloLensについての記事を書いていきます。


すること

INavigationHandlerとIManipulationHandlerの違いを解説

いったいこの違いはなんだろう。と一度は悩んだことがあると思います。自分もけっこう調べたので違いを解説します。


そのまえに

こちら、よく解説されているサイトなのですが、IManipulationHandlerの動画とINavigationHandlerの動画を見比べて見てください。

http://noshipu.hateblo.jp/entry/2017/01/28/133818


なにが違うの

見比べてもらうと、手の動く量に対する値の動き方が全く違うことに気づいてもらえると思います。

INavigationHandlerは、閾値を測り-1~1の間を変動します。手が右に動いた時、それがいかに右らしいか。という値です。なので10cm~20cmも動かせばxの値は1になり、左に同じぐらいの量動かせば-1になります。

IManipulationHandlerは、ホールド開始地点からの実際の手の動きの量を図ります。なので20cm動かしたら、その方向に0.2ぐらいです。


IManipurationHandler利用方法と注意

ただ、手の位置からオブジェクトまでは距離があるわけで、3m離れているときにホロオブジェクトが20cmしか動かなかったらおかしいですよね?なので三角形の相似を用いて以下のようにします。


Manipulation.cs

public class SomeObject : MonoBehaviour, IManipulationHandler {

private Vector3 manipulationPreviousPosition;

private void Start() {
InputManager.Instance.AddGlobalListener(gameObject);
}

private void OnDestroy() {
InputManager.Instance.RemoveGlobalListener(gameObject);
}

public void OnManipulationStarted(ManipulationEventData eventData) {
//初期位置
manipulationPreviousPosition = eventData.CumulativeDelta;
}

public void OnManipulationUpdated(ManipulationEventData eventData) {
Move(eventData.CumulativeDelta);
}

public void OnManipulationCompleted(ManipulationEventData eventData) {
// Do nothing
}

public void OnManipulationCanceled(ManipulationEventData eventData) {
// Do nothing
}

private void Move(Vector3 CumulativeDelta) {
Vector3 moveVector = Vector3.zero;
//最終位置との差分を取得
moveVector = CumulativeDelta - manipulationPreviousPosition;
    
//今回の位置を最終位置に
manipulationPreviousPosition = CumulativeDelta;

//手の空間上の位置は取れないので、40cmくらいとする
float distanceCameraToHand = 0.4f;
    
    //カメラとオブジェクトの距離を取る
float distanceCameraToObject = Vector3.Distance(Camera.main.transform.position, gameObject.transform.position);

//三角形の相似で、何倍にあたるかを割り出す
float correctionValue = distanceCameraToObject / distanceCameraToHand;

//相似の倍数を手の移動距離にかける
gameObject.transform.position += (moveVector * correctionValue);
}
}


このようにするとうまくいきました。

手の空間上の位置はとれないと書きましたが、なんらかの方法でもしできる場合はもっと良くなると思うので教えてください!