(この記事の使用環境: Unity5.5.0f3 Personal、Windows10、SteamVR Plugin 1.2.0、VRTK3.0.1)


VR用アセット「VRTK」の Example 023_Controller_ChildOfControllerOnGrab の解説です。
弓矢を扱うデモです。弓矢はコントローラーの子となり、他の物にぶつかってもコントローラーから離れなくなります。
SnapCrab_NoName_2017-2-15_10-28-3_No-00

■公式サイトの解説

VRTK公式サイトでこのExampleの解説文及び解説動画を見ることができます。ただし、動画に関してはVRTK旧バージョンのときに作られたものであり、VRTK3.0(以降)では設定等が異なっている場合があることに留意してください。動きを中心に見てもらえれば良いかと思います。

このExampleの解説動画


















■VRTKのセットアップ方法および使用されているスクリプトの解説

適宜、以下の記事を参照願います。
  • スクリプト「VRTK_ChildOfControllerGrabAttach」の解説
      (今後執筆予定)

■Exampleの解説

VRTK/Examples 内にある当該番号のシーンを呼び出すことで、デモを動かしてみることができます。

このデモシーンには、弓と矢のオブジェクトが配置されており、それらはコントローラーで持つとコントローラーの子(あるいはコントローラーの拡張)のようになり、他のオブジェクトとぶつかったりしてもコントローラーから離れないようになります。
このデモでは、弓と矢を左右のコントローラーに持ち、弓に矢をつがえ、引き、放つことができます。
SnapCrab_NoName_2017-2-15_10-42-0_No-00

以下、シーンに配置されているオブジェクトについての概要説明です。
  • BreakableCube: シーン上に配置されている壊せる箱。矢が当たると壊れる。解説は この記事 を参照。
  • ArrowSpawnerBox: シーン上に配置されている黄色の箱。ArrowSpawner スクリプトがアタッチされており、コントローラーで触れてグラブボタンを押すと矢を生成する。
    SnapCrab_NoName_2017-2-15_11-3-47_No-00
    ArrowSpawner スクリプトの中身。
    namespace VRTK.Examples.Archery
    {
        using UnityEngine;
    
        // --- 矢を生成する ArrowSpawner --------------------------------------------
        public class ArrowSpawner : MonoBehaviour
        {
            public GameObject arrowPrefab;
            public float spawnDelay = 1f;
    
            private float spawnDelayTimer = 0f;
            private BowAim bow;
    
            private void Start()
            {
                spawnDelayTimer = 0f;
            }
    
            // --- コントローラーと接しているときの処理 ----------------------------------
            private void OnTriggerStay(Collider collider)
            {
                // コントローラーの VRTK_InteractGrab コンポーネントを取得する
                VRTK_InteractGrab grabbingController = (collider.gameObject.GetComponent<VRTK_InteractGrab>() ? collider.gameObject.GetComponent<VRTK_InteractGrab>() : collider.gameObject.GetComponentInParent<VRTK_InteractGrab>());
    
                // --- 掴める状態で、矢をつがえておらず、遅延タイマーの条件をクリアしていれば、矢を生成する ----------
                if (CanGrab(grabbingController) && NoArrowNotched(grabbingController.gameObject) && Time.time >= spawnDelayTimer)
                {
                    GameObject newArrow = Instantiate(arrowPrefab);
                    newArrow.name = "ArrowClone";
                    grabbingController.GetComponent<VRTK_InteractTouch>().ForceTouch(newArrow);
                    grabbingController.AttemptGrab();
                    spawnDelayTimer = Time.time + spawnDelay;
                }
            }
    
            // --- 掴めるか否か(コントローラーが何も掴んでいない状態で、グラブボタンが押されていれば true --------)
            private bool CanGrab(VRTK_InteractGrab grabbingController)
            {
                return (grabbingController && grabbingController.GetGrabbedObject() == null && grabbingController.gameObject.GetComponent<VRTK_ControllerEvents>().grabPressed);
            }
    
            // --- 矢をつがえているか否か -----------------------
            private bool NoArrowNotched(GameObject controller)
            {
                if (VRTK_DeviceFinder.IsControllerLeftHand(controller))
                {
                    bow = VRTK_DeviceFinder.GetControllerRightHand(true).GetComponentInChildren<BowAim>();
                }
                else if (VRTK_DeviceFinder.IsControllerRightHand(controller))
                {
                    bow = VRTK_DeviceFinder.GetControllerLeftHand(true).GetComponentInChildren<BowAim>();
                }
                return (bow == null || !bow.HasArrow());
            }
        }
    }
    

  • Headset(HeadQuiver):  [VRTK] ゲームオブジェクトの下に配置されているゲームオブジェクト。Headset オブジェクトにはシンプルな Follow スクリプトがアタッチされており、[CameraRig] の Camera (eye) の位置・回転を追従するようになっている。
    Headset オブジェクトの下には HeadQuiver オブジェクトがぶら下げられており、それには ArrowSpawner スクリプトおよびRigidbody(isKinematic)、Box Colliderがアタッチされている。
    これらの設定により、プレイヤーの頭の付近でコントローラーのグラブボタンを押すと、そのコントローラーに矢を生成する。
    SnapCrab_NoName_2017-2-15_11-19-4_No-00
    SnapCrab_NoName_2017-2-15_11-19-6_No-00

  • Left Controller、RightController: [VRTK] ゲームオブジェクトの下に配置されている、左右のコントローラー用のVRTKスクリプトをアタッチするゲームオブジェクト。
    VRTK_ControllerEvents 、VRTK_InteractGrab スクリプトほかがアタッチされている。

    SnapCrab_NoName_2017-2-15_11-23-16_No-00

  • BasicBow: 弓の形に組み合わされたオブジェクト。VRTK_InteractableObject スクリプトがアタッチされており、isGrabbable がチェックされているため、コントローラーで掴むことができる。
    また、VRTK_ChildOfControllerGrabAttach スクリプトがアタッチされているため、コントローラーで持つと弓はコントローラーの子となり、他のオブジェクトにぶつかってもグラついたり落としてしまったりしなくなる。SnapPoint の位置でコントローラーに固定される。
    また、BowAim スクリプトのインスペクタで、弓の各種パラメータを設定できる。
    SnapCrab_NoName_2017-2-15_11-27-56_No-00

  • BasicArrow: 矢の形に組み合わされたオブジェクト(プレハブ)。VRTK_InteractableObject スクリプトがアタッチされており、isGrabbable がチェックされているため、コントローラーで掴むことができる。
    また、VRTK_ChildOfControllerGrabAttach スクリプトがアタッチされているため、コントローラーで持つと矢はコントローラーの子となり、他のオブジェクトにぶつかってもグラついたり落としてしまったりしなくなる。SnapPoint の位置でコントローラーに固定される。
    また、ArrowNotch スクリプトの処理により、矢を弓につがえることができるようになっている(Arrowの親オブジェクトに、Bowの持ち手付近のノッキングポイントを設定する処理)。
    SnapCrab_NoName_2017-2-15_11-45-3_No-00

今回は以上です。