読者です 読者をやめる 読者になる 読者になる

MEBIUSTOSのブログ

主にUnityに関する技術的な事を書いていきます。 Twitter @xflutexx

LeapMotion 突き抜けない手がほしい - 第2回 | Unity3D

前回は手がモデルに接触した際に、接触部に留まるオブジェクトをテスト的に可視化してみました。今回はその可視化したオブジェクトの位置にグラフィックハンドモデルを強制的に移動させてみます。

グラフィックハンドモデルの強制移動

LeapMotionのHandControllerでは、グラフィックハンドモデルをUpdateで移動させているようです。なので、LateUpdateて位置を上書きしてやれば良さそう。ではさっそく、なにも考えずに位置と回転をPalmの位置に合わせてみましょう。

f:id:mebius-tos:20150813190721j:plain
画像:回転がずれる物理ハンドとグラフィックハンド

合わせてみると分かるんですが回転がずれます。物理ハンドはおっぱい側を向いてるのに、グラフィックハンドは反対方向に手のひらを向け、y軸も傾いているようです。しかも、右手と左手で回転のズレが違う模様。めんどくさい。。。最終的に次のようにするとピタッとあいました。また位置についてはPalmの位置に単純に合わせるとおっぱいと手の間に隙間が開くので、1cmほど手のひら方向にずらしました。

void ForceMoveGraphicsHand() {
    var handContainer = this.graphicsHandTransform.GetChild(1);

    // グラフィクスハンド回転追随
    handContainer.rotation = this.SlerpPalmTransform.rotation;
    if (this.myHand.IsLeft) {
        handContainer.Rotate(new Vector3(0f, 270f, 0f));
    } else {
        handContainer.Rotate(new Vector3(180f, 90f, 0f));
    }

    // グラフィクスハンド位置追随
    var palmDirection = this.myHand.PalmNormal.ToUnity();
    palmDirection = new Vector3(palmDirection.x * -1, palmDirection.y, palmDirection.z * -1);
    handContainer.position = this.SlerpPalmTransform.position - palmDirection * -1;
}

myHandは別途下記のように取得してます。

Hand GetMyHand() {
    Frame frame = this.handCtrler.GetFrame();
    Hand myHand = null;
    if (frame != null) {
        var leapHand = this.rigidHand.GetLeapHand();
        foreach (var hand in frame.Hands) {
            if (leapHand != null || leapHand.Id == hand.Id) {
                myHand = hand;
                break;
            }
        }
    }
    return myHand;
}

そして完成したAlpha版がこちら

見えない物理演算用のハンドモデルはそのまま体を突き抜けるバージョンですが、動かしてみるとこうなります。

おっぱいに手が吸い付く!すごい!!グラフィックハンドの位置調整だけでも揉んでる感はかなり向上しました。
ただ実際の指のColliderはモデルを突き抜けているのでおっぱいの動きが怪しいです。見えている手もベースとなるColliderの挙動に位置と回転をあわせてるだけなので、Colliderが何かに引っかかってひっくり返ったりすると実際の手の向きとは関係なく画面内の手もひっくり返ります。まぁAlpha版だしね。

次は実際の当たり判定の位置調整を行う予定です。

ダウンロード(Alpha版)

OppaiHandAlpha20150814.zip
最新版はこちらからどうぞ。

(つづく)