Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

【Oculus Touch開発メモ】最初から物を掴んだ状態でシーンを開始する【Unity】

今回はOculus Touchの開発ネタをやっていきます。
Oculus Quest及びOculus Rift Sで使える内容です。

 

 

本記事は読者様からのコメントネタです。

ゲパルト  

いつもわかりやすくお世話になっております。
Oculus touchを使って片手にオブジェクトを初期から固定で持たせておきたいのですが、この場合もOculus intagrationの機能には無く、作らねばならないのでしょうか?

シーン開始時にすでに物を持った状態で始めたいというアイデア
ただ手の位置に追従させたいだけなら、手の子オブジェクトにすればよさそうですが、
後から持ち直したりしたい場合は独自に実装しないといけなさそうです。

 

 

今回は2つのパターン
最初から最後までオブジェクトが固定の場合
途中で物を持ち替えさせたい場合
をお送りします。

f:id:Raspberly:20190918005721p:plain



 

 

 

 

開発環境

Windows 10

Unity 2018.4.5f

Oculus Integration ver1.40

Oculus Quest

 

 

 

 

セットアップ

開発環境を整えていない方は先にこちらをどうぞ。

raspberly.hateblo.jp

 

 

 

サンプルシーンの確認+準備

基本的な掴む投げる動作を学ぶことができるAvatarGrabシーンを使います。
OVR Grabber、DistanceGrabber共に動くのでDistanceGrabシーンでも特に問題はありません。

f:id:Raspberly:20190911231416p:plain

【追記】 2020/02/18

AvatarGrabシーンが削除されました。詳しくはこちら。

raspberly.hateblo.jp

 

手を出す

ALVRでやる場合はこちらを参考に手を用意しておきましょう。

raspberly.hateblo.jp

 

Hand.csの修正も忘れずに

raspberly.hateblo.jp

 

 

 

 

使用するアセット

刀アセット Wakizashi

前回でもお馴染みの刀です。

 

懐中電灯

今回初登場、ホラーゲームにもぴったりな懐中電灯です。

 

 

 

 

3Dモデルのセットアップ

前回の記事と同じです。
Rigidbody、適当なコライダー、OVRGrabbableコンポーネントをアタッチしておきましょう。

raspberly.hateblo.jp

 

 

 

 

 

 

 

 

 

アプローチ1 最初から最後までオブジェクトが固定の場合

シーン開始時、オブジェクトを手に持った状態で始まりますが、
このオブジェクトを途中で落としたり、投げつけたりせず、ずっと固定のパターン
これはとても簡単です
手のモーションを変更、手の子オブジェクトに持たせたいものを設定するだけです。

 

アプローチ1は刀を持たせます。

 

1. 手のアニメーションを変更

手のアニメーションは握っているモーションで固定します。
新しくAnimatorControllerを作成します。名前はFirstGrabMotionとおきます。

f:id:Raspberly:20190917213804p:plain

Animatorビューから新しくステートを作成します。

f:id:Raspberly:20190917214059p:plain

 

FirstGrabMotionのMotionを「r_hand_relax_3qtr_fist」にします。
左手なら「l_hand_relax_3qtr_fist」です。

f:id:Raspberly:20190917222013p:plain


ちなみに「r_hand_relax_3qtr_fist」モーションはこんな感じ。

f:id:Raspberly:20190917221927p:plain



2. Handの子オブジェクト化

KatanaをCustomHandの子オブジェクトに入れます。

f:id:Raspberly:20190917222722p:plain

この時、いい感じの位置に調整してあげましょう。
一度再生し、プレイモードで位置を合わせてから

f:id:Raspberly:20190917223509g:plain

インスぺクターの値をコピーして、プレイモードを解除後に値をペーストして上書きします。

f:id:Raspberly:20190917223939g:plain




 

 

 

3. Grabbableオブジェクトの設定

忘れてならないのがこれです。
最初に持たせておきたいオブジェクトのGrabbableですが、使わないので無効化しておきましょう。
そしてRigidbodyのIsKinematicにチェックを入れます。

f:id:Raspberly:20190917223729p:plain



4. Grabberの設定

OVRGrabberは手OculusTouchからの位置の同期に必須なので無効化していけません。
ただし、他の物を掴んでほしくないのでGrabBeginは2にしておきます。
GrabEndは0にしていますが、ここはあまり関係ないようです。

 

次にHandは無効化しておきます。(ここが詰まりポイント)
Handは子オブジェクトのコライダーやレンダラーに対してスケールを自動で調整する機能がありますが、
今回は邪魔になるので無効化しておきます。

f:id:Raspberly:20190917235623p:plain

 

 

完成

これで完成です。
シーン開始時から刀を持った状態で始まります。

中指トリガーをガチャガチャやっても、途中で離したりはしません。

f:id:Raspberly:20190918000004g:plain

 

 

途中で持ち替えたりする必要がないのならこれで十分だと思います。
OculusTouchの操作時に誤って手を離したりすることがないため、操作性も良い。

 

 

 

 

 

 

 

 

 

 

 

アプローチ2 途中で物を持ち替えさせたい場合

シーン開始時、オブジェクトを手に持った状態で始まりますが、
このオブジェクトを途中で落としたり投げたり、空いた手で別のオブジェクトを掴めるようにします。

こちらは自分でスクリプトを書いていく必要があります。

 

 

アプローチ1とは違い懐中電灯を持たせます。

 

1.手のアニメーションを変更

アプローチ1とほとんど同じですが、モーションだけ差し替えます。

FirstGrabMotionのMotionを「r_hand_hold_billiard_ball_anim」にします。
左手なら「l_hand_hold_billiard_ball_anim」です。

f:id:Raspberly:20190917214319p:plain

ちなみに「r_hand_hold_billiard_ball_anim」モーションはこんな感じ。

f:id:Raspberly:20190917222537p:plain

 

 

2. コンポーネントの設定

GitHubからあらかじめOVRFirstGrabberスクリプトを落としておきます。 

github.com

 

このOVRFirstGrabberをCustomHandにアタッチします。
OVR GrabberやHandコンポーネントがアタッチされているオブジェクトと同じところです。

f:id:Raspberly:20190917212943p:plain

 

OVR FirstGrabber

シーン開始時に最初から物を掴んだ状態で始めるコンポーネントです。

流れとしてはこんな感じ
1.シーン開始時、OVR Grabberが有効なら無効化する。
2.OculusTouchの中指トリガーが押されていようがいまいが最初は常に持ち続ける。
3.一度中指トリガーが押されたのち離されると、持つことを解除する。
4.同時に、通常のOVRGrabberを有効化し、AnimatorControllerを差し替え、自身(OVR FirstGrabber)を無効化する。

 

インスペクターパラメーター

枠で囲んである所がOVR Grabberにないオリジナルのパラメータです。
他の部分はOVR Grabberと同じ値にしておきましょう。

f:id:Raspberly:20190917211655p:plain

First Grabbable

最初に持たせておきたいオブジェクトのGrabbable。
今回の場合、FlashlightのGrabbableになります。

Hand Animator

手のAnimator。
今回の場合、CustomHandの子オブジェクトにある「r_hand_skeltal_lowres

f:id:Raspberly:20190917212456p:plain

Hand Animator Controller

手のAnimatorに初期からついているAnimatorController。
右手の場合はRightHandAnimator、左手の場合はLeftHandAnimator

f:id:Raspberly:20190917212741p:plain



 

完成

これで完成です。
シーン開始時から懐中電灯を持った状態で始まります。
一度懐中電灯を離した後は、別のオブジェクトを掴むこともできますし、懐中電灯を拾いなおすこともできます。

f:id:Raspberly:20190917223035g:plain

 

 

 

 

おまけ

以下のスクリプトをそのままコピペして、lightComの所に懐中電灯のライトを紐づけると、
Bボタンで懐中電灯のオンオフを切り替えられます。
ホラーゲームなどの雰囲気作りにどうぞ。

using UnityEngine;

public class FlashlightOnOff : MonoBehaviour
{

    [SerializeField] Light lightCom;

    void Update()
    {
        if(OVRInput.GetDown(OVRInput.RawButton.B))
        {
            lightCom.enabled = !lightCom.enabled;
        }
    }
}

f:id:Raspberly:20190918005540g:plain



 

 

 

 

まとめ

最初から物を持たせたい時は二つのアプローチがある

基本的には子オブジェクトにするだけのアプローチ1の方がよい 

プレイヤーの誤動作をなくし、落ちたものを拾いに行かせなくて済むので、
アプローチ1の方がよさそうです。

 

先日の銀座VR3で「狂気の城」というコンテンツを体験させていただきましたが、
こちらもアプローチ1の方でした。

 

 

 

 

 

 

 

 

 

今回は読者様のコメントネタを取り上げましたが、
同じく読者様からのリクエスト記事が完全に止まっているので、こちらも近いうちに仕上げたい所。

raspberly.hateblo.jp

 

 

 

 

他間違っている箇所、わかりにくい所がありましたらコメントにお願いします。