目次
開発環境
- Quest1
- Oculus Link + SteamVR
- Unity 2021.2.0b16.3733
- Unity 2020.3.17f1
- SteamVR Plugin 2.7.3
前提
Playerプレハブを使うので前回の記事で準備ができていること。
実装
- Playerプレハブを使用する
- 床やCubeなどを適当に配置する
CubeにInteractableとRigidBodyを追加する
LeftHandにLineRendererを追加する
- Positionsの1のZを10にする、Widthを0.01にする、Use World Spaceのチェックを外す
- Widthはヘッダ部分を横にスライドすると調整できる
DistanceStayGrabスクリプトを作成する
[RequireComponent(typeof(FixedJoint))] public class DistanceStayGrab : MonoBehaviour { private FixedJoint joint; private GameObject targetObject; void Start() { joint = GetComponent<FixedJoint>(); } void Update() { if (targetObject == null && Physics.Raycast(transform.position, transform.forward, out var hit, 10)) { var interactable = hit.transform.gameObject.GetComponent<Interactable>(); if (interactable != null) { targetObject = hit.transform.gameObject; } } if(targetObject != null) { if (SteamVR_Actions.default_GrabPinch.GetStateDown(SteamVR_Input_Sources.LeftHand)) { joint.connectedBody = targetObject.GetComponent<Rigidbody>(); } else if (SteamVR_Actions.default_GrabPinch.GetState(SteamVR_Input_Sources.LeftHand)) { // 掴み中 } else { joint.connectedBody = null; targetObject = null; } } } }
- DistanceStayGrabスクリプトをLeftHandに追加する
- 一緒に追加されたRigidBodyのUseGravityのチェックを外し、IsKenematicのチェックを入れる
備考
- SteamVR/ExtrasにSteamVR_LaserPointerが同梱されている
- イベントに処理を紐付けて利用する
- サンプルシーンでは処理が設定されてないのでポインターを表示してクリックすると色が変わるだけ
- 掴む処理に使うにはイベントが別れていて煩雑になりそう
- UIをクリックするのには使えそう
- 使い方はLeftHandなどにSteamVR_LaserPointerを追加して、他のスクリプトからイベントハンドラを登録する
- イベントハンドラのサンプルコード
private SteamVR_LaserPointer laserPointer; void Start() { laserPointer = GetComponent<SteamVR_LaserPointer>(); laserPointer.PointerClick += LaserPointer_PointerClick; laserPointer.PointerIn += LaserPointer_PointerIn; laserPointer.PointerOut += LaserPointer_PointerOut; } private void LaserPointer_PointerIn(object sender, PointerEventArgs e) { // PointerのRaycastがHitした時に呼ばれる Debug.Log("In"); targetObject = e.target.gameObject; } private void LaserPointer_PointerOut(object sender, PointerEventArgs e) { // 直前にHitしていたオブジェクトがRaycastがHitしなくなった時に呼ばれる Debug.Log("Out"); if (targetObject == e.target.gameObject) { targetObject = null; } } private void LaserPointer_PointerClick(object sender, PointerEventArgs e) { // PointerのRaycastがHitしてる場合、ボタンを押して離した時に呼ばれる Debug.Log("Click"); targetObject = e.target.gameObject; }
参考
- 【連載】VRコンテンツの作り方 [5] UnityでHTC Vive用アプリを作る(2) オブジェクトの作成とコントローラの処理|開発ソフトウェア|IT製品の事例・解説記事
- 【連載】VRコンテンツの作り方 [6] UnityでHTC Vive用アプリを作る(3) 重力を設定、オブジェクトを持ち上げる|開発ソフトウェア|IT製品の事例・解説記事
- SteamVR 2.0 Tutorial: Laser Pointer | by Jesus Najera | Medium
- SteamVR 2.0 how to implement distance grab? - Unity Answers
- 【Unity】LineRendererの幅を変える設定の場所(たぶん2018.3以降用) - テラシュールブログ