/****************************************************************************
* 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 !");
}
}
}
}