// Start is called before the first frame update
    void Start()
    {
        abilityMap = new Dictionary <int, GestureAbility>();

        foreach (GestureAbility gestureAbility in GetComponents <GestureAbility>())
        {
            int gestureHash = makeGestureHash(gestureAbility.leftGesture, gestureAbility.rightGesture);

            abilityMap.Add(gestureHash, gestureAbility);
        }

        leftTracker  = new GestureTrackingNode(this, leftControllerTransform, SteamVR_Input_Sources.LeftHand);
        rightTracker = new GestureTrackingNode(this, rightControllerTransform, SteamVR_Input_Sources.RightHand);
    }
    // Update is called once per frame
    void Update()
    {
        trackingNode = gestureHandler.GetTrackingNode(isLeft);

        // usually the confirm "animation" will play for half a second after the gesture is confirmed
        // but if the tracker starts recording again within that time we stop animating
        if (trackingNode.currentlyRecording())
        {
            gestureConfirmed = false;
        }

        if (!gestureConfirmed)
        {
            var displacementDir       = trackingNode.currentGestureDirection();
            var displacementMagnitude = Mathf.Min(maxDisplacementMagnitude, trackingNode.currentGestureMagnitude() * 0.1f);

            if (displacementMagnitude == 0)
            {
                arrow.gameObject.SetActive(false);
                return;
            }
            else
            {
                arrow.gameObject.SetActive(true);
            }

            float displacementRatio = Mathf.Clamp((displacementMagnitude / maxDisplacementMagnitude) * 2, 0, 2);

            arrowTarget.localPosition = displacementDir;
            arrow.localScale          = new Vector3(baseScale.x, baseScale.y, displacementRatio * baseScale.z);
            arrow.LookAt(arrowTarget);

            arrowMaterial.SetColor("_BaseColor", Color.Lerp(minColor, maxColor, displacementMagnitude / maxDisplacementMagnitude));
        }
        else
        {
            arrow.localScale = new Vector3(baseScale.x, baseScale.y, baseScale.z * 2);
            arrowMaterial.SetColor("_BaseColor", maxColor);
        }
    }