Skip to content

Commit 6a94c07

Browse files
committed
fix(Interaction): make force stop interactions wait for end of frame
Previously, it was possible to get the force stop interactions into an infinite loop by calling `ForceStopTouching` or `ForceStopInteracting` from within an event listener from the Stop Using event which would in turn could emit the Stop Using event again and therefore getting stuck in an infinite loop. The fix now ensures that any interactable object force stop events are done at the end of the frame giving the controller scripts time to correctly clean up.
1 parent 88dcf8e commit 6a94c07

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

Assets/SteamVR_Unity_Toolkit/Scripts/VRTK_InteractableObject.cs

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace VRTK
1212
{
1313
using UnityEngine;
14+
using System.Collections;
1415
using System.Collections.Generic;
1516

1617
public struct InteractableObjectEventArgs
@@ -200,7 +201,10 @@ public virtual void StopTouching(GameObject previousTouchingObject)
200201
{
201202
OnInteractableObjectUntouched(SetInteractableObjectEvent(previousTouchingObject));
202203
touchingObject = null;
203-
StopUsingOnControllerChange(previousTouchingObject);
204+
if(gameObject.activeInHierarchy)
205+
{
206+
StartCoroutine(StopUsingOnControllerChange(previousTouchingObject));
207+
}
204208
}
205209

206210
public virtual void Grabbed(GameObject currentGrabbingObject)
@@ -224,22 +228,9 @@ public virtual void Ungrabbed(GameObject previousGrabbingObject)
224228
grabbedSnapHandle = null;
225229
grabbingObject = null;
226230
LoadPreviousState();
227-
StopUsingOnControllerChange(previousGrabbingObject);
228-
}
229-
230-
private void StopUsingOnControllerChange(GameObject previousController)
231-
{
232-
var usingObject = previousController.GetComponent<VRTK_InteractUse>();
233-
if (usingObject)
231+
if (gameObject.activeInHierarchy)
234232
{
235-
if (holdButtonToUse)
236-
{
237-
usingObject.ForceStopUsing();
238-
}
239-
else
240-
{
241-
usingObject.ForceResetUsing();
242-
}
233+
StartCoroutine(StopUsingOnControllerChange(previousGrabbingObject));
243234
}
244235
}
245236

@@ -370,24 +361,9 @@ public bool IsValidInteractableController(GameObject actualController, AllowedCo
370361

371362
public void ForceStopInteracting()
372363
{
373-
if (touchingObject != null && touchingObject.activeInHierarchy)
374-
{
375-
touchingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
376-
forcedDropped = true;
377-
}
378-
379-
if (grabbingObject != null && grabbingObject.activeInHierarchy)
380-
{
381-
grabbingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
382-
grabbingObject.GetComponent<VRTK_InteractGrab>().ForceRelease();
383-
forcedDropped = true;
384-
}
385-
386-
if (usingObject != null && usingObject.activeInHierarchy)
364+
if (gameObject.activeInHierarchy)
387365
{
388-
usingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
389-
usingObject.GetComponent<VRTK_InteractUse>().ForceStopUsing();
390-
forcedDropped = true;
366+
StartCoroutine(ForceStopInteractingAtEndOfFrame());
391367
}
392368
}
393369

@@ -691,5 +667,46 @@ private void OnTeleported(object sender, DestinationMarkerEventArgs e)
691667
transform.position = grabbingObject.transform.position;
692668
}
693669
}
670+
671+
private IEnumerator StopUsingOnControllerChange(GameObject previousController)
672+
{
673+
yield return new WaitForEndOfFrame();
674+
var usingObject = previousController.GetComponent<VRTK_InteractUse>();
675+
if (usingObject)
676+
{
677+
if (holdButtonToUse)
678+
{
679+
usingObject.ForceStopUsing();
680+
}
681+
else
682+
{
683+
usingObject.ForceResetUsing();
684+
}
685+
}
686+
}
687+
688+
private IEnumerator ForceStopInteractingAtEndOfFrame()
689+
{
690+
yield return new WaitForEndOfFrame();
691+
if (touchingObject != null && touchingObject.activeInHierarchy)
692+
{
693+
touchingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
694+
forcedDropped = true;
695+
}
696+
697+
if (grabbingObject != null && grabbingObject.activeInHierarchy)
698+
{
699+
grabbingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
700+
grabbingObject.GetComponent<VRTK_InteractGrab>().ForceRelease();
701+
forcedDropped = true;
702+
}
703+
704+
if (usingObject != null && usingObject.activeInHierarchy)
705+
{
706+
usingObject.GetComponent<VRTK_InteractTouch>().ForceStopTouching();
707+
usingObject.GetComponent<VRTK_InteractUse>().ForceStopUsing();
708+
forcedDropped = true;
709+
}
710+
}
694711
}
695712
}

0 commit comments

Comments
 (0)