// distance to hand in world scale private float HandDistance(InteractionHand hand) { if (!hand.isTracked) { return(float.PositiveInfinity); } var lossyScale = transform.lossyScale.x; switch (objectType) { case ObjectType.Point: return(transform.position.sqrDist(HandPointerPos(hand))); case ObjectType.Line: return(DistToLineSegment(HandPointerPos(hand), lineRenderer)); case ObjectType.Circle: return(ClosestPointOnCircleToHand(hand).sqrDist(HandPointerPos(hand))); case ObjectType.Rect: Vector3 pointerInObjSpace; pointerInObjSpace = (transform.InverseTransformPoint(HandPointerPos(hand)) - buttonPivot) * lossyScale; Vector3 worldButtonSize = buttonSize * lossyScale; if (Mathf.Abs(pointerInObjSpace.x) < worldButtonSize.x / 2 && Mathf.Abs(pointerInObjSpace.y) < worldButtonSize.y / 2 && Mathf.Abs(pointerInObjSpace.z) < hoverDistance) { return(pointerInObjSpace.z * pointerInObjSpace.z); } else { return(float.PositiveInfinity); } } return(float.PositiveInfinity); }
private void Awake() { userRig = GetComponentInParent <UserRig>(); platformManager = GetComponent <PlatformManager>(); interactionManager = Leap.Unity.Interaction.InteractionManager.instance; if (interactionManager != null) { controllerManager = interactionManager.GetComponent <PlatformControllerManager>(); } if (interactionManager) { foreach (InteractionController controller in interactionManager.interactionControllers) { if (controller is InteractionHand) { InteractionHand hand = (InteractionHand)controller; if (hand.isLeft) { leftInteractionHand = hand; } else { rightInteractionHand = hand; } hand.leapProvider = defaultProvider; } } } SkeletalControllerHand[] hands = transform.parent.GetComponentsInChildren <SkeletalControllerHand>(true); leftSkeletalControllerHand = hands.First(item => item.IsLeft); rightSkeletalControllerHand = hands.First(item => !item.IsLeft); }
protected override void WhileGestureActive(Hand hand) { base.WhileGestureActive(hand); Chirality chirality = Chirality.Right; //choose opposite hand for iHand; InteractionHand iHand = leapHandDataLogger.ins.currHands.rIhand; if (hand.IsLeft) { iHand = leapHandDataLogger.ins.currHands.rIhand; chirality = Chirality.Left; } handColourManager.setHandColorMode(chirality, handColourManager.handModes.snappingPalm); if (iHand.isGraspingObject && iHand.graspedObject.gameObject.GetComponent <straightEdgeBehave>() == myStraightEdge) { Debug.Log("Trying to snap to floor"); //iHand.ReleaseObject(myStraightEdge.GetComponent<InteractionBehaviour>()); myStraightEdge.snapToFloor(); } }
private Tuple <InteractionHand, IPinchable> DetermineBestPinchable(IEnumerable <InteractionHand> hands) { IPinchable best = null; InteractionHand bestHand = null; float minDistance = float.MaxValue; foreach (var hand in hands) { var pos = hand.leapHand.GetPinchPosition(); foreach (var pinchComponent in pinchables) { pinchComponent.CheckPinchStart(hand, out bool isValid, out float distance); if (isValid && distance < minDistance) { minDistance = distance; best = pinchComponent; bestHand = hand; } } } return(Tuple.Create <InteractionHand, IPinchable>(bestHand, best)); }
// How closed is the pinch : fully open 0 .. 1 fully closed public static float pinchCloseness(this InteractionHand hand, float maxWidth = 0.06f) { float activateDistance = 0.02f; //HandUIManager.pinchRight.pinchActivateDistance; return(Mathf.InverseLerp(activateDistance * activateDistance, maxWidth * maxWidth, hand.pinchSqrWidth())); }
private void Start() { hand = HandUIManager.GetHand(whichHand); Hide(); }
public Vector3 ClosestPointOnCircleToHand(InteractionHand hand) { return(closestPointOnCircle(transform.position, circleRadius * transform.lossyScale.x, HandPointerPos(hand))); }
public static float pinchSqrWidth(this InteractionHand hand, float maxWidth = 0.06f) { return(!hand.isTracked ? maxWidth : hand.indexPos().sqrDist(hand.leapHand.GetThumb().TipPosition.ToVector3())); }
private Vector3 GetObjectSpaceGrabPoint(InteractionHand hand) { return(this.transform.InverseTransformVector(_intObj.GetGraspPoint(hand) - this.transform.position)); }
private void HandleActiveMode() { bool hasHoverHand = false; foreach (var controller in leap.hoveringControllers) { if (controller.isGraspingObject) { continue; } hasHoverHand |= IsHandInActivationPose(controller.intHand); } if (hasHoverHand) { hoverTime += Time.deltaTime; } else { hoverTime = 0f; } if (graspedPoseHandler.InteractingHands == 0) { inactiveTime += Time.deltaTime; if (inactiveTime > InactiveTimeout) { ChangeMode(ManipulationMode.Hover); graspedPoseHandler.SetEnabled(false); } else { ChangeMode(ManipulationMode.Active); } } else if (graspedPoseHandler.InteractingHands == 1) { inactiveTime = 0f; // Don't allow going from Translating into anchoring if (Mode == ManipulationMode.Translating) { hasHoverHand = false; } // Have slight delay on anchoring start as not to trigger it on rotation/scaling if (hasHoverHand && hoverTime > 0.2f) { anchorHand = leap.graspingController.intHand; anchoringStart = anchorHand.isGraspingObject ? anchorHand.GetGraspPoint() : anchorHand.position; anchoringStopTimer = 0f; lineRenderer.enabled = true; ChangeMode(ManipulationMode.Anchoring); Player.Instance?.ShowAnchoringTarget(); graspedPoseHandler.SetEnabled(false); } else { ChangeMode(ManipulationMode.Translating); } } else if (graspedPoseHandler.InteractingHands == 2) { inactiveTime = 0f; if (proxyNode.Radius < MINIMIZE_THRESHOLD) { graspedPoseHandler.SetEnabled(false); proxyNode.Minimize(); ChangeMode(ManipulationMode.Minimized); } else { ChangeMode(ManipulationMode.ScalingAndRotating); } } }
public static Chirality chirality(this InteractionHand hand) { return(hand.isLeft ? Chirality.Left : Chirality.Right); }
public static Vector3 stablePinchPos(this InteractionHand hand) { return(HandUIManager.GetPinchGesture(hand.chirality()).stablePinch.position); }
public static InteractionHand otherHand(this InteractionHand hand) { return(hand.isLeft ? HandUIManager.handRight : HandUIManager.handLeft); }
public static Vector3 pinchPos(this InteractionHand hand) { return((hand.indexPos() + hand.thumbPos()) / 2); }
public static bool isPinched(this InteractionHand hand) { return(HandUIManager.GetPinchGesture(hand.chirality()).isActive&& hand.isTracked); }
private void Update() { closestHand = null; //find closest hand dL = HandDistance(HandUIManager.handLeft); dR = HandDistance(HandUIManager.handRight); if (dL <= dR) { closestHand = HandUIManager.handLeft; } else if (dR < dL) { closestHand = HandUIManager.handRight; } closestHandDist = Mathf.Min(dL, dR); dist = closestHandDist; handIsClose = dist < hoverDistance * hoverDistance; if (handIsClose && !hovered && canBeHovered && !isClosestPinching()) { BeginHover(); } if (!handIsClose && !pinched && hovered) { EndHover(); } reset = false; if (hovered && !pinched && isClosestPinching() && !isClosestHandHolding()) { BeginPinch(); } if (pinched && !isClosestPinching()) { EndPinch(); } if (!bothHandsPinched && pinched && closestHand.otherHand().isPinched() && isHandClose(closestHand.otherHand())) { // start double pinch bothHandsPinched = true; onGrabDistanceBetweenHands = Vector3.Distance(HandUIManager.pinchLeft.pose.position, HandUIManager.pinchRight.pose.position); onGrabScale = transform.localScale; onGrabEulerAngles = transform.eulerAngles; var midpoint = (HandUIManager.pinchLeft.pose.position + HandUIManager.pinchLeft.pose.position) / 2; prevMidpointPos = midpoint; deltaAngle = 0; reset = true; onGrabMidpointOffset = midpoint - transform.position; onGrabRightToLeft = HandUIManager.pinchLeft.pose.position - HandUIManager.pinchRight.pose.position; onGrabRightToLeft.y = 0; } if (bothHandsPinched && !(closestHand.isPinched() && closestHand.otherHand().isPinched())) { //end double pinch bothHandsPinched = false; onGrabMidpointOffset = HandPointerPos(closestHand) - transform.position; } if (pinched) { var currentPinchPos = HandPointerPos(closestHand); currentDeltaPinchPos = currentPinchPos - prevPinchPos; distanceFromInitPinchPos = currentPinchPos - initPositionWhenPinched; prevPinchPos = currentPinchPos; } if (pinched && moveWithPinch) { if (twoHandedTRS && bothHandsPinched) { // TRS with 2 hands var midpoint = (HandUIManager.pinchLeft.pose.position + HandUIManager.pinchLeft.pose.position) / 2; var currentDistance = Vector3.Distance(HandUIManager.pinchLeft.pose.position, HandUIManager.pinchRight.pose.position); var currentRightToLeft = HandUIManager.pinchLeft.pose.position - HandUIManager.pinchRight.pose.position; currentRightToLeft.y = 0; var angle = Vector3.SignedAngle(currentRightToLeft, onGrabRightToLeft, Vector3.up); if (!reset) { deltaAngle = prevAngle - angle; } else { reset = false; } prevAngle = angle; onGrabMidpointOffset = Quaternion.Euler(0, deltaAngle, 0) * onGrabMidpointOffset; transform.Rotate(deltaAngle * Vector3.up); transform.position = midpoint - onGrabMidpointOffset * currentDistance / onGrabDistanceBetweenHands; transform.localScale = onGrabScale * currentDistance / onGrabDistanceBetweenHands; } else { // move with one hand transform.position = HandPointerPos(closestHand) - onGrabMidpointOffset; } } }
protected virtual INTERACTION_HAND_RESULT getHandResults(InteractionHand hand) { if (!_graspingEnabled) { INTERACTION_HAND_RESULT result = new INTERACTION_HAND_RESULT(); result.classification = ManipulatorMode.Contact; result.handFlags = HandResultFlags.ManipulatorMode; result.instanceHandle = new INTERACTION_SHAPE_INSTANCE_HANDLE(); return result; } INTERACTION_HAND_RESULT handResult; InteractionC.GetHandResult(ref _scene, (uint)hand.hand.Id, out handResult); return handResult; }
private bool ShakaIsShown(InteractionHand hand) { return(hand.isTracked && hand.leapHand.GetThumb().IsExtended&& hand.leapHand.GetPinky().IsExtended&& !hand.leapHand.GetIndex().IsExtended&& !hand.leapHand.GetMiddle().IsExtended&& !hand.leapHand.GetRing().IsExtended); }
private void GrabSphereGraspedEnd() { grabHand = null; grabSphereMaterial.DOColor(GrabSphereDefaultColor, 0.1f); }
private void Awake() { uiColorMode = _uiColorMode; whitePoint = _whitePoint; colorGradient = _colorGradient; head = Hands.Provider.transform; var pinchGestures = FindObjectsOfType <PinchGesture>(); if (pinchGestures.Length > 1) { foreach (var item in pinchGestures) { if (item.whichHand == Chirality.Left) { pinchLeft = item; } else if (item.whichHand == Chirality.Right) { pinchRight = item; } else { Warn("Both left and right PinchGestures are required in the scene", this); } } } var interactionHands = FindObjectsOfType <InteractionHand>(); if (interactionHands.Length > 1) { foreach (var item in interactionHands) { if (item.isLeft) { handLeft = item; } else { handRight = item; } } } else { Warn("Both left and right InteractionHands are required in the scene", this); } var raycasts = FindObjectsOfType <HandRaycast>(); if (raycasts.Length > 1) { foreach (var item in raycasts) { if (item.whichHand == Chirality.Left) { rayLeft = item; } else if (item.whichHand == Chirality.Right) { rayRight = item; } else { Warn("Couldn't find both left and right HandRaycasts in the scene", this); } } } prevPosR = handRight.leapHand.GetIndex().TipPosition.ToVector3(); prevPosL = handLeft.leapHand.GetIndex().TipPosition.ToVector3(); prevHeadRot = head.rotation; }
/// <summary> /// Call this at the start of an Interaction engine test with the name of a stage /// object and the name of a rig object to load those objects and fill utility /// parameters such as manager, leftHand, box0, etc. for testing. /// </summary> protected void InitTest(string rigObjName, string stageObjName) { // Load test rig objects. base.InitTest(rigObjName); rigObj = testObj; recording = rigObj.GetComponentInChildren <PlayableDirector>(); provider = rigObj.GetComponentInChildren <LeapProvider>(); manager = rigObj.GetComponentInChildren <InteractionManager>(); foreach (var controller in manager.interactionControllers) { if (controller.intHand != null && controller.isLeft) { leftHand = controller.intHand; continue; } if (controller.intHand != null && !controller.isLeft) { rightHand = controller.intHand; continue; } var vrController = controller as InteractionXRController; if (vrController != null && vrController.isLeft) { leftVRController = vrController; continue; } if (vrController != null && !vrController.isLeft) { rightVRController = vrController; continue; } } // Load stage objects. stageObj = LoadObject(stageObjName); var intObjs = Pool <List <InteractionBehaviour> > .Spawn(); try { stageObj.GetComponentsInChildren <InteractionBehaviour>(true, intObjs); // Load "simple box" interaction objects. foreach (var simpleBoxObj in intObjs .Query() .Where(o => o.primaryHoverColliders.Count == 1 && o.primaryHoverColliders[0] is BoxCollider && !o.ignoreContact && !o.ignoreGrasping)) { if (box0 == null) { box0 = simpleBoxObj; continue; } if (box1 == null) { box1 = simpleBoxObj; continue; } if (box2 == null) { box2 = simpleBoxObj; continue; } } foreach (var interactionButtonObj in intObjs.Query() .Where(o => o is InteractionButton)) { if (button == null) { button = interactionButtonObj as InteractionButton; } } } finally { intObjs.Clear(); Pool <List <InteractionBehaviour> > .Recycle(intObjs); } }
private void updateForHand(Hand hand, out bool areFingertipsOutsideSurface) { InteractionHand intHand = null; if (hand != null && InteractionManager.instance != null) { intHand = getIntHand(InteractionManager.instance, hand.IsLeft); } areFingertipsOutsideSurface = true; if (hand != null && (intHand == null || !intHand.isGraspingObject)) { for (int i = 0; i < hand.Fingers.Count; i++) { int fingerArrayBaseIdx = hand.IsLeft ? 0 : 5; var finger = hand.Fingers[i]; var fingertipPosition = finger.TipPosition.ToVector3(); _fingertipPositions[fingerArrayBaseIdx + i] = fingertipPosition; var portalPose = portalObj.transform.ToPose() + new Pose(portalObj.transform.forward * depthOffset); var isFingertipProjectionInRect = false; var sqrDistToRect = 0f; var clampedFingertip = fingertipPosition .ClampedToRect(portalPose, portalObj.width, portalObj.height, out sqrDistToRect, out isFingertipProjectionInRect); // Check whether we should 'pop' because the user reached too far. var fingertipPlaneSpace = fingertipPosition.GetLocalPlanePosition(portalPose); var fingertipDepth = fingertipPlaneSpace.z; var popDepth = 0.02f; // TODO: Turn into param if (fingertipDepth > popDepth) { _popped = true; } // We detect whether all fingertips "leave the portal surface" either sideways or depth-wise // to eventually reset the "popped" state of the portal surface. if (isFingertipProjectionInRect && !(fingertipDepth < depthOffset - thickness)) { areFingertipsOutsideSurface = false; } if (!_popped) { var pressStrength = sqrDistToRect.Map(0f, thickness * thickness, 1f, 0f); if (pressStrength > 0f && isFingertipProjectionInRect) { _touchingFingerPositions[fingerArrayBaseIdx + i] = clampedFingertip; _fingerStrengths[fingerArrayBaseIdx + i] = pressStrength; if (drawInteractionDebug) { //DebugPing.Ping(clampedFingertip, LeapColor.amber, 0.10f); } } } } } if (intHand != null && intHand.isGraspingObject) { areFingertipsOutsideSurface = false; } }
private void updateHands() { foreach (Hand hand in mostRecentFrame.Hands) { InteractionHand matchingHand = _trackingHands.FirstOrDefault(h => h.leapHand.Id == hand.Id); if (matchingHand == null) { //If the new hand does not have the same ID as any hand we have been tracking //See if it matches the handedness of a hand that has been untracked for a little bit of time InteractionHand matchingStaleHand = _trackingHands.FirstOrDefault(h => h.timeSinceUpdated > 0.1f && h.leapHand.IsRight == hand.IsRight); if (matchingStaleHand != null) { //if it does, the new hand assumes control of the abandonded hand matchingStaleHand.updateInfo(hand); } else { //otherwise we create a new hand to be tracked InteractionHand newHand = new InteractionHand(); newHand.updateInfo(hand); _trackingHands.Add(newHand); } } else { //We found the match, simply update it matchingHand.updateInfo(hand); } } HandModel[] physicsModels = HandControllerUtil.handController.GetAllPhysicsHands(); //All hands that haven't been updated for too long foreach (InteractionHand kHand in _trackingHands.Where(h => h.timeSinceUpdated > handDisapearDelay && h.grabbedObject != null && h.cachedRigidbody != null && h.cachedRigidbody.isKinematic)) { kHand.cachedRigidbody.isKinematic = false; foreach (HandModel model in physicsModels) { Leap.Utils.IgnoreCollisions(kHand.grabbedObject.gameObject, model.gameObject, false); } } //Remove all the stale hands from the set _trackingHands.RemoveWhere(h => h.timeSinceUpdated > handDisapearDelay); }
public static Transform stablePinchTransform(this InteractionHand hand) { return(HandUIManager.GetPinchGesture(hand.chirality()).stablePinch); }
protected virtual void updateInteractionStateChanges(Frame frame) { var hands = frame.Hands; INTERACTION_HAND_RESULT handResult = new INTERACTION_HAND_RESULT(); //First loop through all the hands and get their classifications from the engine for (int i = 0; i < hands.Count; i++) { Hand hand = hands[i]; bool handResultForced = false; //Get the InteractionHand associated with this hand id InteractionHand interactionHand; if (!_idToInteractionHand.TryGetValue(hand.Id, out interactionHand)) { //First we see if there is an untracked interactionHand that can be re-connected using this one InteractionHand untrackedInteractionHand = null; foreach (var pair in _idToInteractionHand) { //If the old ieHand is untracked, and the handedness matches, we re-connect it if (pair.Value.isUntracked && pair.Value.hand.IsLeft == hand.IsLeft) { untrackedInteractionHand = pair.Value; break; } } if (untrackedInteractionHand != null) { //If we found an untrackedIeHand, use it! interactionHand = untrackedInteractionHand; //Remove the old id from the mapping _idToInteractionHand.Remove(untrackedInteractionHand.hand.Id); _idToInteractionHand[hand.Id] = interactionHand; try { //This also dispatched InteractionObject.OnHandRegainedTracking() interactionHand.RegainTracking(hand); if (interactionHand.graspedObject == null) { continue; } // NotifyHandRegainedTracking() did not throw, continue on to NotifyHandsHoldPhysics(). dispatchOnHandsHolding(hands, interactionHand.graspedObject, isPhysics: true); } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionHand.graspedObject); Debug.LogException(e); continue; } //Override the existing classification to force the hand to grab the old object handResultForced = true; handResult.classification = ManipulatorMode.Grasp; handResult.handFlags = HandResultFlags.ManipulatorMode; handResult.instanceHandle = interactionHand.graspedObject.ShapeInstanceHandle; if (_graspingEnabled) { InteractionC.OverrideHandResult(ref _scene, (uint)hand.Id, ref handResult); } } else { //Otherwise just create a new one interactionHand = new InteractionHand(hand); _idToInteractionHand[hand.Id] = interactionHand; } } if (!handResultForced) { handResult = getHandResults(interactionHand); } interactionHand.UpdateHand(hand); if (!interactionHand.isUserGrasp) { switch (handResult.classification) { case ManipulatorMode.Grasp: { IInteractionBehaviour interactionBehaviour; if (_instanceHandleToBehaviour.TryGetValue(handResult.instanceHandle, out interactionBehaviour)) { if (interactionHand.graspedObject == null) { if (!interactionBehaviour.IsBeingGrasped) { _graspedBehaviours.Add(interactionBehaviour); } try { interactionHand.GraspObject(interactionBehaviour, isUserGrasp: false); //the grasp callback might have caused the object to become ungrasped //the component might have also destroyed itself! if (interactionHand.graspedObject == interactionBehaviour && interactionBehaviour != null) { dispatchOnHandsHolding(hands, interactionBehaviour, isPhysics: true); } } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionBehaviour); Debug.LogException(e); continue; } } } else { Debug.LogError("Recieved a hand result with an unkown handle " + handResult.instanceHandle.handle); } break; } case ManipulatorMode.Contact: { if (interactionHand.graspedObject != null) { if (interactionHand.graspedObject.GraspingHandCount == 1) { _graspedBehaviours.Remove(interactionHand.graspedObject); } try { interactionHand.ReleaseObject(); } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionHand.graspedObject); Debug.LogException(e); continue; } } break; } default: throw new InvalidOperationException("Unexpected classification " + handResult.classification); } } } //Loop through all ieHands to check for timeouts and loss of tracking foreach (var pair in _idToInteractionHand) { var id = pair.Key; var ieHand = pair.Value; float handAge = Time.unscaledTime - ieHand.lastTimeUpdated; //Check to see if the hand is at least 1 frame old //We assume it has become untracked if this is the case if (handAge > 0) { //If the hand isn't grasping anything, just remove it if (ieHand.graspedObject == null) { _handIdsToRemove.Add(id); continue; } //If is isn't already marked as untracked, mark it as untracked if (!ieHand.isUntracked) { try { //This also dispatches InteractionObject.OnHandLostTracking() ieHand.MarkUntracked(); } catch (Exception e) { _activityManager.NotifyMisbehaving(ieHand.graspedObject); Debug.LogException(e); } } //If the age is longer than the timeout, we also remove it from the list if (handAge >= ieHand.maxSuspensionTime) { _handIdsToRemove.Add(id); try { if (ieHand.graspedObject.GraspingHandCount == 1) { _graspedBehaviours.Remove(ieHand.graspedObject); } //This also dispatched InteractionObject.OnHandTimeout() ieHand.MarkTimeout(); } catch (Exception e) { _activityManager.NotifyMisbehaving(ieHand.graspedObject); Debug.LogException(e); } } } } //Loop through the stale ids and remove them from the map for (int i = 0; i < _handIdsToRemove.Count; i++) { _idToInteractionHand.Remove(_handIdsToRemove[i]); } _handIdsToRemove.Clear(); }
public static Vector3 indexPos(this InteractionHand hand) { return(hand.leapHand.GetIndex().TipPosition.ToVector3()); }
public static Vector3 thumbPos(this InteractionHand hand) { return(hand.leapHand.GetThumb().TipPosition.ToVector3()); }
/// <summary> /// To be called at the start of an Interaction Engine test. Loads the named object /// by finding it in the current scene or otherwise by spawning it by prefab name. /// /// After calling this method, the following fields are set: /// /// PROVIDERS /// - testProvider: The LeapProvider designed for IE unit tests. /// /// MANAGERS /// - manager: The Interaction Manager. /// /// CONTROLLERS /// - leftHand: The left Interaction Hand, if there is one. /// - rightHand: The right Interaction Hand, if there is one. /// - leftVRController: The left VR controller, if there is one. /// - rightVRController: The right VR Controller, if there is one. /// /// OBJECTS /// - box0: An InteractionBehaviour with an attached BoxCollider, if there is one. /// - box1: Another InteractionBehaviour with an attached BoxCollider, if it exists. /// - box2: Yet another InteractionBehaviour with a BoxCollider, if it exists. /// </summary> protected override void InitTest(string objectName) { base.InitTest(objectName); testProvider = testObj.GetComponentInChildren <StationaryTestLeapProvider>(); manager = testObj.GetComponentInChildren <InteractionManager>(); foreach (var controller in manager.interactionControllers) { if (controller.intHand != null && controller.isLeft) { leftHand = controller.intHand; continue; } if (controller.intHand != null && !controller.isLeft) { rightHand = controller.intHand; continue; } var vrController = controller as InteractionVRController; if (vrController != null && vrController.isLeft) { leftVRController = vrController; continue; } if (vrController != null && !vrController.isLeft) { rightVRController = vrController; continue; } } var intObjs = Pool <List <InteractionBehaviour> > .Spawn(); try { testObj.GetComponentsInChildren <InteractionBehaviour>(true, intObjs); // Load "simple box" interaction objects. foreach (var simpleBoxObj in intObjs.Query().Where(o => o.primaryHoverColliders.Count == 1 && o.primaryHoverColliders[0] is BoxCollider)) { if (box0 == null) { box0 = simpleBoxObj; continue; } if (box1 == null) { box1 = simpleBoxObj; continue; } if (box2 == null) { box2 = simpleBoxObj; continue; } } } finally { intObjs.Clear(); Pool <List <InteractionBehaviour> > .Recycle(intObjs); } }
public void BeginPinch(InteractionHand hand) { tether.enabled = true; UpdatePinch(hand); OnAnchoringStart?.Invoke(this, null); }