public override List <InteractableCollisionInfo> GetNextIntersectingObjects() { if (!_initialized) { return(_currentIntersectingObjects); } // if we already have focused on something, keep it until the angle between // our forward direction and object vector becomes too large if (_currInteractableCastedAgainst != null && HasRayReleasedInteractable(_currInteractableCastedAgainst)) { // reset state _currInteractableCastedAgainst = null; } // Find target interactable if we haven't found one before. if (_currInteractableCastedAgainst == null) { _currentIntersectingObjects.Clear(); _currInteractableCastedAgainst = FindTargetInteractable(); // If we have found one, query collision zones. if (_currInteractableCastedAgainst != null) { var targetHitPoint = _currInteractableCastedAgainst.transform.position; int numHits = Physics.OverlapSphereNonAlloc(targetHitPoint, COLLIDER_RADIUS, _collidersOverlapped); // find all colliders encountered; focus only on ones belonging to target element for (int i = 0; i < numHits; i++) { Collider colliderHit = _collidersOverlapped[i]; var colliderZone = colliderHit.GetComponent <ColliderZone>(); if (colliderZone == null) { continue; } Interactable interactableComponent = colliderZone.ParentInteractable; if (interactableComponent == null || interactableComponent != _currInteractableCastedAgainst) { continue; } InteractableCollisionInfo collisionInfo = new InteractableCollisionInfo(colliderZone, colliderZone.CollisionDepth, this); _currentIntersectingObjects.Add(collisionInfo); } // clear intersecting object if no collisions were found if (_currentIntersectingObjects.Count == 0) { _currInteractableCastedAgainst = null; } } } return(_currentIntersectingObjects); }
/// <summary> /// For each intersecting interactable, update meta data to indicate deepest collision only. /// </summary> public virtual void UpdateCurrentCollisionsBasedOnDepth() { _currInteractableToCollisionInfos.Clear(); foreach (InteractableCollisionInfo interactableCollisionInfo in _currentIntersectingObjects) { var interactable = interactableCollisionInfo.InteractableCollider.ParentInteractable; var depth = interactableCollisionInfo.CollisionDepth; InteractableCollisionInfo collisionInfoFromMap = null; if (!_currInteractableToCollisionInfos.TryGetValue(interactable, out collisionInfoFromMap)) { _currInteractableToCollisionInfos[interactable] = interactableCollisionInfo; } else if (collisionInfoFromMap.CollisionDepth < depth) { collisionInfoFromMap.InteractableCollider = interactableCollisionInfo.InteractableCollider; collisionInfoFromMap.CollisionDepth = depth; } } }
/// <summary> /// For each interactable, update meta data to indicate deepest collision only. /// </summary> /// <param name="allCollisions">All current collisions.</param> /// <param name="interactableToCollisionInfo">Interactable->collision info map.</param> private void UpdateInteractableDeepestCollisionMap(List<InteractableCollisionInfo> allCollisions, Dictionary<Interactable, InteractableCollisionInfo> interactableToCollisionInfo) { interactableToCollisionInfo.Clear(); foreach (InteractableCollisionInfo interactableCollisionInfo in allCollisions) { var interactable = interactableCollisionInfo.InteractableCollider.ParentInteractable; var depth = interactableCollisionInfo.CollisionDepth; InteractableCollisionInfo collisionInfoFromMap = null; if (!interactableToCollisionInfo.TryGetValue(interactable, out collisionInfoFromMap)) { interactableToCollisionInfo[interactable] = interactableCollisionInfo; } else if (collisionInfoFromMap.CollisionDepth < depth) { collisionInfoFromMap.InteractableCollider = interactableCollisionInfo.InteractableCollider; collisionInfoFromMap.CollisionDepth = depth; } } }