/*---------------------------------------------------------------------------------------------------*/ void PinchObject() { if (currentFingerDist < pinchStartThreshold) { if (pinchedObject == null) { Vector3 middlePoint = this.transform.position; /// Iterate the cubes, find the closest one in range and start to pinch foreach (PinchableObject obj in PinchableObject.instances) { if (Vector3.Distance(middlePoint, obj.transform.position) < interactionDistanceThreshold && previousFingerDist > pinchEnableThreshold) { pinchedObject = obj; pinchedObject.OnPickUp.Invoke(); pinchedObjectParent = pinchedObject.transform.parent; pinchedObject.transform.parent = this.transform; pinchedObject.transform.localPosition = Vector3.zero; break; } } } } else { if (currentFingerDist > pinchEndThreshold) { if (pinchedObject != null) { pinchedObject.transform.parent = pinchedObjectParent; pinchedObject.OnRelease.Invoke(); pinchedObject.OnThrow.Invoke(this.speed); pinchedObject = null; } } } }
void UpdatePinchState() { GestureName currentGesture = hand.GetGestureName(); bool isClosingFingers = (pinchSpeed < -closingSpeedThresh); bool isOpeningFingers = (pinchSpeed > openingSpeedThresh); if (activeObject != null && activeObject.IsAvailableForPinch() == false && pinchState != PinchState.ObjectInHold) // pinched by the other hand { activeObject = null; pinchState = PinchState.ObjectOutOfReach; } if ((pinchState == PinchState.ObjectOutOfReach) || (pinchState == PinchState.ObjectInReach && !isClosingFingers) || (pinchState == PinchState.ObjectReleased)) { // Iterate all pinchable objects, find the closest available one. PinchableObject closestAvailableObj = null; float minDistance = 1000f; foreach (PinchableObject obj in PinchableObject.instances) { if (obj.IsAvailableForPinch()) { float distance = Vector3.Distance(this.transform.position, obj.transform.position); if (distance < minDistance) { minDistance = distance; closestAvailableObj = obj; } } } // Mark the closest available object as active activeObject = closestAvailableObj; // Check if it is range. bool inReach = (minDistance < pinchEnableDistance); if (activeObject != null) { // To give user visual feedbacks, update the outline color on the active object // based on its current distance to the hand. activeObject.UpdateOutlineColorBasedOnDistance(minDistance); // Reset the outline color (fully transparent) on the last active object if it was different if (prevActiveObject != null && prevActiveObject != activeObject) { prevActiveObject.SetOutlineColorTransparency(0); } // If we are able to pinch the currently active object if (inReach && currentTipDist > pinchEnableTipDistance) { if (pinchState != PinchState.ObjectInReach || activeObject != prevActiveObject) { activeObject.OnGetInReach.Invoke(); pinchState = PinchState.ObjectInReach; } } } // Note, we want to ignore movement (which can cause ObjectInReach state to change to ObjectOutOfReach) // if user is already in the middle of pinching the object if (!inReach && !(pinchState == PinchState.ObjectInReach && isClosingFingers)) { if (pinchState != PinchState.ObjectOutOfReach || activeObject != prevActiveObject) { if (activeObject != null) { activeObject.OnOutOfReach.Invoke(); } pinchState = PinchState.ObjectOutOfReach; } } } if (pinchState == PinchState.ObjectInReach) { if ((currentTipDist < pinchStartTipDistance || currentGesture == GestureName.PinchCloseMRP || currentGesture == GestureName.PinchOpenMRP) && isClosingFingers) { // To give user visual feedbacks, make the hand transparent. if (meshHandRenderMgr != null) { meshHandRenderMgr.DisableHandOutline(); meshHandRenderMgr.FadeOut(); } if (activeObject != null) { activeObject.OnPickUp.Invoke(); // Save the parent transform pinchedObjectParent = activeObject.transform.parent; activeObject.transform.parent = this.transform; activeObject.transform.localPosition = Vector3.zero; // Disable the object for pinch activeObject.SetAvailableForPinch(false); } pinchState = PinchState.ObjectInHold; } } if (pinchState == PinchState.ObjectInHold) { if (currentTipDist > pinchEndTipDistance && isOpeningFingers) { // To give user visual feedbacks, make the hand opaque (default). if (meshHandRenderMgr != null) { meshHandRenderMgr.FadeIn(); } if (activeObject != null) { activeObject.OnRelease.Invoke(); Vector3 velocity = (velocityCalculator != null) ? velocityCalculator.CalculateVelocity() : Vector3.zero; if (Vector3.Magnitude(velocity) > 0) { activeObject.OnThrow.Invoke(velocity); // Enable the object for pinch later activeObject.SetAvailableForPinch(true, activeObject.FlyBackTime()); } else { // Enable the object for pinch right away activeObject.SetAvailableForPinch(true, 0); } // Restore the parent transform activeObject.transform.parent = pinchedObjectParent; } pinchState = PinchState.ObjectReleased; } } //Debug.Log("Pinch state = " + pinchState); // To give user visual feedbacks, highlight hand outline if it is hovering an object, otherwise disable outline. bool isHovering = (pinchState == PinchState.ObjectInReach); if (meshHandRenderMgr != null) { if (isHovering && !isHoveringLastFrame) { meshHandRenderMgr.EnableHandOutline(); } else if (!isHovering && isHoveringLastFrame) { meshHandRenderMgr.DisableHandOutline(); } } isHoveringLastFrame = isHovering; prevActiveObject = activeObject; }
// Start is called before the first frame update void Start() { rBody = gameObject.GetComponent <Rigidbody>(); pBody = gameObject.GetComponent <PinchableObject>(); originalPos = gameObject.transform.localPosition; }