/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using UnityEngine; /// /// An object that can be grabbed and thrown by OVRGrabber. /// public class OVRGrabbable : MonoBehaviour { [SerializeField] protected bool m_allowOffhandGrab = true; [SerializeField] protected bool m_snapPosition = false; [SerializeField] protected bool m_snapOrientation = false; [SerializeField] protected Transform m_snapOffset; [SerializeField] protected Collider[] m_grabPoints = null; protected bool m_grabbedKinematic = false; protected Collider m_grabbedCollider = null; protected OVRGrabber m_grabbedBy = null; /// /// If true, the object can currently be grabbed. /// public bool allowOffhandGrab { get { return m_allowOffhandGrab; } } /// /// If true, the object is currently grabbed. /// public bool isGrabbed { get { return m_grabbedBy != null; } } /// /// If true, the object's position will snap to match snapOffset when grabbed. /// public bool snapPosition { get { return m_snapPosition; } } /// /// If true, the object's orientation will snap to match snapOffset when grabbed. /// public bool snapOrientation { get { return m_snapOrientation; } } /// /// An offset relative to the OVRGrabber where this object can snap when grabbed. /// public Transform snapOffset { get { return m_snapOffset; } } /// /// Returns the OVRGrabber currently grabbing this object. /// public OVRGrabber grabbedBy { get { return m_grabbedBy; } } /// /// The transform at which this object was grabbed. /// public Transform grabbedTransform { get { return m_grabbedCollider.transform; } } /// /// The Rigidbody of the collider that was used to grab this object. /// public Rigidbody grabbedRigidbody { get { return m_grabbedCollider.attachedRigidbody; } } /// /// The contact point(s) where the object was grabbed. /// public Collider[] grabPoints { get { return m_grabPoints; } } /// /// Notifies the object that it has been grabbed. /// virtual public void GrabBegin(OVRGrabber hand, Collider grabPoint) { m_grabbedBy = hand; m_grabbedCollider = grabPoint; gameObject.GetComponent().isKinematic = true; } /// /// Notifies the object that it has been released. /// virtual public void GrabEnd(Vector3 linearVelocity, Vector3 angularVelocity) { Rigidbody rb = gameObject.GetComponent(); rb.isKinematic = m_grabbedKinematic; rb.velocity = linearVelocity; rb.angularVelocity = angularVelocity; m_grabbedBy = null; m_grabbedCollider = null; } void Awake() { if (m_grabPoints.Length == 0) { // Get the collider from the grabbable Collider collider = this.GetComponent(); if (collider == null) { throw new ArgumentException("Grabbables cannot have zero grab points and no collider -- please add a grab point or collider."); } // Create a default grab point m_grabPoints = new Collider[1] { collider }; } } protected virtual void Start() { m_grabbedKinematic = GetComponent().isKinematic; } void OnDestroy() { if (m_grabbedBy != null) { // Notify the hand to release destroyed grabbables m_grabbedBy.ForceRelease(this); } } }