/// <summary> /// Attach the XRGrabInteractable in the center (+offset) of the socket. Also makes the Rigidbody kinematic /// </summary> /// <param name="objectToAttach">The XRGrabInteractable to attach</param> private void Attach(XRGrabInteractable objectToAttach) { Debug.Log($"Attach {objectToAttach}"); socketedInteractable = objectToAttach; baseScale = socketedInteractable.transform.localScale; // since XRGrabInteractable modifies the rigidbodies after grab event we must modify the rigidbody after it does socketedInteractable.selectExited.AddListener(_ => { Debug.Log("Select exit Attach"); var rb = socketedInteractable.GetComponent <Rigidbody>(); rb.useGravity = false; rb.isKinematic = true; socketedInteractable.transform.parent = transform; socketedInteractable.transform.localRotation = Quaternion.identity; // set the socketInteractable rotation the same as the parent socket socketedInteractable.selectExited.RemoveAllListeners(); }); // force drop the holdedObject and don't allow regrab it with the same input socketedInteractable.selectingInteractor.allowSelect = false; StartCoroutine(AllowSelect(socketedInteractable.selectingInteractor)); socketedInteractable.retainTransformParent = false; socketedInteractable.transform.position = transform.position + offsetY * transform.up; socketedInteractable.selectEntered.AddListener(_ => Release()); // once the object is in the inventory the grab event will release it parentInventory.AddObject(socketedInteractable.gameObject); }
static void DisableDelayProperties(XRGrabInteractable grabInteractable) { grabInteractable.velocityDamping = 1f; grabInteractable.velocityScale = 1f; grabInteractable.angularVelocityDamping = 1f; grabInteractable.angularVelocityScale = 1f; grabInteractable.attachEaseInTime = 0f; var rigidbody = grabInteractable.GetComponent <Rigidbody>(); rigidbody.maxAngularVelocity = float.PositiveInfinity; }
void Update() { if (m_CurrentSelectionOutline != null) { m_CurrentSelectionOutline.RemoveHighlight(); } if (m_TractingObject) { Tracting(); } else if (IsEnabled) { Vector3 worldAxis = m_DirectInteractor.transform.TransformDirection(LocalRayAxis); m_HighlightedRigidbody = null; int mask = ~0; mask &= ~(1 << LayerMask.NameToLayer("Hands")); int count = Physics.SphereCastNonAlloc(m_DirectInteractor.transform.position, 0.2f, worldAxis, m_HitCache, 15.0f, mask, QueryTriggerInteraction.Ignore); if (count != 0) { float closestDistance = float.MaxValue; float closestDistanceGrabbable = float.MaxValue; XRGrabInteractable closestGrababble = null; for (int i = 0; i < count; ++i) { if (closestDistance > m_HitCache[i].distance) { closestDistance = m_HitCache[i].distance; } if (m_HitCache[i].rigidbody == null) { continue; } var grabbable = m_HitCache[i].rigidbody.GetComponentInChildren <XRGrabInteractable>(); if (grabbable != null && m_HitCache[i].distance < closestDistanceGrabbable) { closestDistanceGrabbable = m_HitCache[i].distance; closestGrababble = grabbable; } } BeamRenderer.SetPosition(1, LocalRayAxis * closestDistance); if (closestGrababble != null) { var filter = closestGrababble.GetComponentInChildren <MeshFilter>(); if (filter != null) { m_HighlightedRigidbody = closestGrababble.GetComponent <Rigidbody>(); var outline = m_HighlightedRigidbody.GetComponentInChildren <SelectionOutline>(); if (outline != null) { m_CurrentSelectionOutline = outline; m_CurrentSelectionOutline.Highlight(); } } } } } }