Search Unity

Question Error on Lerping Object Back to Start Position After Force Grab

Discussion in 'XR Interaction Toolkit and Input' started by FarmerInATechStack, Sep 1, 2023.

  1. FarmerInATechStack

    FarmerInATechStack

    Joined:
    Dec 28, 2020
    Posts:
    57
    Does anyone have working code or guidance on how to lerp an interactable back to its start position after it was "force grabbed" and then released by an interactor?

    I originally thought this would be a basic lerping problem and I have a somewhat working example (see the code below). My Issue: most of the time, the object returns to the correct position as planned. However, sometimes it returns to the correct position but then also moves to a slight offset.

    Code (CSharp):
    1. private IEnumerator LerpReturn()
    2. {
    3.     float elapsedTime = 0f;
    4.     Vector3 currentPosition = transform.localPosition;
    5.  
    6.     while (elapsedTime < returnTime)
    7.     {
    8.         float lerpFactor = elapsedTime / returnTime;
    9.         transform.localPosition = Vector3.Lerp(currentPosition, startPosition, lerpFactor);
    10.         yield return null;
    11.         elapsedTime += Time.deltaTime;
    12.     }
    13.  
    14.     transform.localPosition = startPosition;
    15. }
     
  2. FarmerInATechStack

    FarmerInATechStack

    Joined:
    Dec 28, 2020
    Posts:
    57
    I suspect the issue is that lerping an XR Interactable does not work well with the Process functionality in XRI, so I might have to override the Process methods. I'll try that next but please share if you've had any experience with this too.
     
  3. FarmerInATechStack

    FarmerInATechStack

    Joined:
    Dec 28, 2020
    Posts:
    57
    I've updated my code to override the ProcessInteractable function, but I'm still getting an error. Has anyone worked through this?

    Code (CSharp):
    1. public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
    2. {
    3.     base.ProcessInteractable(updatePhase);
    4.     if (updatePhase != XRInteractionUpdateOrder.UpdatePhase.OnBeforeRender) return;
    5.     if (!shouldLerp) return;
    6.      
    7.     if (elapsedTime < maxTime)
    8.     {
    9.         transform.localPosition = Vector3.Lerp(lerpStart, lerpEnd, elapsedTime / totalTime);
    10.         elapsedTime += Time.deltaTime;
    11.     }
    12.     else
    13.     {
    14.         transform.localPosition = lerpEnd;
    15.         shouldLerp = false;
    16.     }
    17. }