/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal { using UnityEngine; using System; /// A nr grabbable object. [RequireComponent(typeof(Rigidbody))] public class NRGrabbableObject : MonoBehaviour { /// Gets a value indicating whether we can grab. /// True if we can grab, false if not. public bool CanGrab { get { return Grabber == null; } } /// Gets a value indicating whether this object is being grabbed. /// True if this object is being grabbed, false if not. public bool IsBeingGrabbed { get { return Grabber; } } /// Gets or sets the grabber. /// The grabber. public NRGrabber Grabber { get; private set; } /// Gets the attached colliders. /// The attached colliders. public Collider[] AttachedColliders { get { CheckAttachedColliders(); return m_AttachedColliders; } } /// Event queue for all listeners interested in OnGrabBegan events. public event Action OnGrabBegan { add { m_OnGrabBegan += value; } remove { m_OnGrabBegan -= value; } } /// Event queue for all listeners interested in OnGrabEnded events. public event Action OnGrabEnded { add { m_OnGrabEnded += value; } remove { m_OnGrabEnded -= value; } } /// The attached rigidbody. protected Rigidbody m_AttachedRigidbody; /// The attached colliders. [SerializeField] private Collider[] m_AttachedColliders; /// True to origin rigidbody kinematic. private bool m_OriginRigidbodyKinematic; /// The on grab began. private Action m_OnGrabBegan; /// The on grab ended. private Action m_OnGrabEnded; /// Awakes this object. protected virtual void Awake() { m_AttachedRigidbody = GetComponent(); m_OriginRigidbodyKinematic = m_AttachedRigidbody.isKinematic; CheckAttachedColliders(); } /// Grab begin. /// The grabber. public void GrabBegin(NRGrabber grabber) { if (IsBeingGrabbed || grabber == null) return; gameObject.GetComponent().isKinematic = true; Grabber = grabber; if (m_OnGrabBegan != null) { m_OnGrabBegan(); } } /// Grab end. public void GrabEnd() { m_AttachedRigidbody.isKinematic = m_OriginRigidbodyKinematic; Grabber = null; if (m_OnGrabEnded != null) { m_OnGrabEnded(); } } /// Move rigidbody. /// Target position. /// Target rot. public void MoveRigidbody(Vector3 targetPos, Quaternion targetRot) { if (!IsBeingGrabbed) return; m_AttachedRigidbody.MovePosition(targetPos); m_AttachedRigidbody.MoveRotation(targetRot); } /// Move transform. /// Target position. /// Target rot. public void MoveTransform(Vector3 targetPos, Quaternion targetRot) { if (!IsBeingGrabbed) return; transform.position = targetPos; transform.rotation = targetRot; } /// Check attached colliders. private void CheckAttachedColliders() { if (m_AttachedColliders != null && m_AttachedColliders.Length > 0) return; m_AttachedColliders = GetComponentsInChildren(); if (m_AttachedColliders == null) { NRDebugger.Error("AttachedColliders can not be null for NRGrabbableObject, please set collider !"); } } } }