示例#1
0
        private void OnDisable()
        {
            Grabbable grabbable = GetComponent <Grabbable>();

            grabbable.OnAttached += OnAttached;
            grabbable.OnDetached += OnDetached;
        }
示例#2
0
        public void Store(Grabbable grabbable, CharacterVR characterVR = null)
        {
            grabbable.Rigidbody.isKinematic = true;
            grabbable.Transform.parent      = transform;
            Vector3    attachPositionOffset = Vector3.zero;
            Quaternion attachRotationOffset = Quaternion.identity;

            grabbable.GetLocalAttachmentPositionAndRotation(transform, out attachPositionOffset, out attachRotationOffset, SlotType.name);
            grabbable.Transform.localPosition = -attachPositionOffset;
            grabbable.Transform.localRotation = Quaternion.Inverse(attachRotationOffset);

            if (!DataVR.Instance.grabbable.colliderEnabledWhenStored)
            {
                for (int i = 0; i < grabbable.Colliders.Length; i++)
                {
                    grabbable.Colliders[i].enabled = false;
                }
                if (characterVR)
                {
                    characterVR.RemoveNearInteractables(grabbable);                               //if fromInitialSpawn to avoid null reference remove on RemoveNearInteractables
                }
            }

            AttachedGrabbable = grabbable;
            AttachedGrabbable.SetOwnerSlot(this);
        }
示例#3
0
        public void Unstore()
        {
            for (int i = 0; i < AttachedGrabbable.Colliders.Length; i++)
            {
                AttachedGrabbable.Colliders[i].enabled = true;
            }

            AttachedGrabbable = null;
        }
示例#4
0
        public bool Unstore(Grabbable grabbable)
        {
            if (AttachedGrabbable != grabbable)
            {
                return(false);
            }

            Unstore();
            return(true);
        }
示例#5
0
        private void OnTriggerEnter(Collider other)
        {
            Interactable i = other.GetComponentInParent <Interactable>();

            if (i)
            {
                characterVR.AddNearInteractables(i);
            }

            Rigidbody rb = other.GetComponentInParent <Rigidbody>();
            Grabbable g  = null;

            if (i)
            {
                g = i.GetComponentInParent <Grabbable>();
            }

            if (rb && (!g || !g.Attached))
            {
                rb.collisionDetectionMode = /*CollisionDetectionMode.Continuous*/ CollisionDetectionMode.ContinuousSpeculative;                                         //invalidates Rigidbody.Sleep(); in Grabbable Awake?
            }
        }
示例#6
0
        /// <summary>
        /// Detection of Interactables in a radius or inside a capsule.
        /// </summary>
        /// <returns></returns>
        private Interactable HoverInteractableDetection()
        {
            int length = DataVR.Instance.hand.hoverDetectionMaxColliders;               //greater == more precision

            Collider[] results              = new Collider[length];
            float[]    sqrDistances         = new float[length];
            Vector3[]  closestPoints        = new Vector3[length];
            float      hoverDetectionRadius = DataVR.Instance.hand.hoverDetectionRadius;

            if (DataVR.Instance.hand.hoverDetectionCapsule)
            {
                Physics.OverlapCapsuleNonAlloc(transform.position, transform.position + InteractableDetectionDirection.normalized * DataVR.Instance.hand.hoverDetectionCapsuleLength, hoverDetectionRadius, results, DataVR.Instance.hand.interactableElements, QueryTriggerInteraction.Ignore);
            }
            else
            {
                Physics.OverlapSphereNonAlloc(transform.position, hoverDetectionRadius, results, DataVR.Instance.hand.interactableElements, QueryTriggerInteraction.Ignore);
            }

//#if UNITY_EDITOR
//			if(TrackedPoseDriver.poseSource == TrackedPoseDriver.TrackedPose.RightPose)
//			for (int i = 0; i < length; i++)
//			{
//				if(results[i] != null) Debug.Log("hoverResult: " + results[i], results[i].gameObject);
//			}
//#endif

            //Order by distance
            for (int i = 0; i < length; i++)
            {
                if (results[i] == null)
                {
                    sqrDistances[i] = float.MaxValue;
                    continue;
                }

                //Get the closest point in the collider of the detected interactable to the hand
                Vector3 closestPoint = Physics.ClosestPoint(transform.position, results[i], results[i].transform.position, results[i].transform.rotation);

                //SquareDistance between this hand and closest point of the hover detected collider
                sqrDistances[i]  = (closestPoint - transform.position).sqrMagnitude;
                closestPoints[i] = closestPoint;
            }

            //Sort results and closestPoints by distance
            float[] sqrDistancesCopy = new float[length];
            System.Array.Copy(sqrDistances, sqrDistancesCopy, length);

            System.Array.Sort(sqrDistances, results);
            System.Array.Sort(sqrDistancesCopy, closestPoints);

            //Return first valid result
            for (int i = 0; i < results.Length; i++)
            {
                if (sqrDistances[i] == float.MaxValue)
                {
                    return(null);
                }

                //3 types with different validation conditions to be detected
                //Interactable				-> !AttachedGrabbable, sqrDistance < hoverDetectionRadius^2, visible || ethereal
                //Interactable Slot			-> sqrDistance < hoverDetectionRadius^2, (slot.AttachedGrabbable && !AttachedGrabbable) || !slot.AttachedGrabbable && AttachedGrabbable && slot.SlotType == AttachedGrabbable.SlotType
                //Interactable Grabbable	-> !AttachedGrabbable, visible || ethereal, !Stored

                //Grabbable before Slot because results[i].GetComponentInParent<Slot>(); can be truth with Grabbables (when they are stored)
                Grabbable grabbable = results[i].GetComponentInParent <Grabbable>();

                if (grabbable)
                {
                    if (!AttachedGrabbable &&
                        !grabbable.Undetectable &&
                        (grabbable.ConstrainedDetection ? sqrDistances[i] <= hoverDetectionRadius * hoverDetectionRadius : true) &&
                        !grabbable.Stored &&
                        (grabbable.Ethereal || results[i].transform.VisibleSpecificPointFrom(transform.position, closestPoints[i], DataVR.Instance.hand.blockingElements, QueryTriggerInteraction.Ignore)))
                    {
#if UNITY_EDITOR
                        hoveredClosestPoint = closestPoints[i];
#endif
                        return(grabbable);
                    }
                    continue;
                }

                Slot slot = results[i].GetComponentInParent <Slot>();

                if (slot)
                {
                    if ((slot.ConstrainedDetection ? sqrDistances[i] <= hoverDetectionRadius * hoverDetectionRadius : true) &&
                        ((slot.AttachedGrabbable && !AttachedGrabbable) || !slot.AttachedGrabbable && AttachedGrabbable && slot.SlotType == AttachedGrabbable.SlotType))
                    {
#if UNITY_EDITOR
                        hoveredClosestPoint = closestPoints[i];
#endif
                        return(slot);
                    }

                    continue;
                }

                Interactable interactable = results[i].GetComponentInParent <Interactable>();

                //It is useful to have things in interactable layer but without interactable component
                //Because they don't collide with CharacterVR layer
                if (interactable)
                {
                    if (!AttachedGrabbable &&
                        !interactable.Undetectable &&
                        (interactable.ConstrainedDetection ? sqrDistances[i] <= hoverDetectionRadius * hoverDetectionRadius : true) &&
                        (interactable.Ethereal || results[i].transform.VisibleSpecificPointFrom(transform.position, closestPoints[i], DataVR.Instance.hand.blockingElements, QueryTriggerInteraction.Ignore)))
                    {
#if UNITY_EDITOR
                        hoveredClosestPoint = closestPoints[i];
#endif
                        return(interactable);
                    }

                    continue;
                }
                continue;
            }
            return(null);
        }