Search code examples
c#unity-game-enginevrtk

How to get time of how long an object is grabbed?


Currently I am working on a project using Unity and the Virtual Reality Toolkit (VRTK). I want to log the times of the grabbed objects (How long the user grabs an object).

So far I got this:

using System;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRTK;

public class System_2_Script_Slider_X : MonoBehaviour
{
    float Timer;

    void Start()

    {
        Timer = 0;

        if (GetComponent<VRTK_InteractableObject>() == null)
        {
            Debug.LogError("Team3_Interactable_Object_Extension is required to be attached to an Object that has the VRTK_InteractableObject script attached to it");

            return;
        }

        GetComponent<VRTK_InteractableObject>().InteractableObjectGrabbed += new InteractableObjectEventHandler(ObjectGrabbed);

        GetComponent<VRTK_InteractableObject>().InteractableObjectUngrabbed += new InteractableObjectEventHandler(ObjectUngrabbed);
    }

    private void ObjectGrabbed(object sender, InteractableObjectEventArgs e)

    {
        //Some Code

        Timer += Time.deltaTime;
    }

    private void ObjectUngrabbed(object sender, InteractableObjectEventArgs e)

    {
        //Some Code

        File.AppendAllText("PATH/Timer.txt", Timer.ToString());

        Timer = 0;
    }
}

Unfortunately this doesn't work as I get times of around 2 milliseconds even though I grabbed the object way longer. So it seems the ObjectGrabbed() function starts the timer but stops it immediately.

How can I fix this?


Solution

  • The object grabbed function is likely only called once (when you grab). It doesn't start a timer, it just add the time since last frame to your variable. If it is only called once, it will only add the time of one frame to the Time variable.

    What you should do instead is register when the object was grabbed so you can compute the total length when it is released:

    using System;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using VRTK;
    
    public class System_2_Script_Slider_X : MonoBehaviour
    {
        private float _timeWhenGrabbed;
    
        void Start()
        {
            if (GetComponent<VRTK_InteractableObject>() == null)
            {
                Debug.LogError("Team3_Interactable_Object_Extension is required to be attached to an Object that has the VRTK_InteractableObject script attached to it");
    
                return;
            }
    
            GetComponent<VRTK_InteractableObject>().InteractableObjectGrabbed += new InteractableObjectEventHandler(ObjectGrabbed);
    
            GetComponent<VRTK_InteractableObject>().InteractableObjectUngrabbed += new InteractableObjectEventHandler(ObjectUngrabbed);
        }
    
        private void ObjectGrabbed(object sender, InteractableObjectEventArgs e)
    
        {
            //Some Code
    
            _timeWhenGrabbed = Time.time;
        }
    
        private void ObjectUngrabbed(object sender, InteractableObjectEventArgs e)
    
        {
            //Some Code
            var grabDuration = Time.time - _timeWhenGrabbed;
            File.AppendAllText("PATH/Timer.txt", grabDuration.ToString());
        }
    }