private static bool IsObjectPartOfTouchable(GameObject targetObject, BaseNearInteractionTouchable touchable) { return(targetObject != null && touchable != null && (targetObject == touchable.gameObject || // Descendant game objects are touchable as well. In particular, this is needed to be able to send // touch events to Unity UI control elements. (targetObject.transform != null && touchable.gameObject.transform != null && targetObject.transform.IsChildOf(touchable.gameObject.transform)))); }
public override void OnPreSceneQuery() { if (Rays == null) { Rays = new RayStep[1]; } closestNormal = Rotation * Vector3.forward; var layerMasks = PrioritizedLayerMasksOverride ?? PokeLayerMasks; // Find closest touchable BaseNearInteractionTouchable newClosestTouchable = null; foreach (var layerMask in layerMasks) { if (FindClosestTouchableForLayerMask(layerMask, out newClosestTouchable, out closestDistance, out closestNormal)) { break; } } if (newClosestTouchable != null) { // Build ray (poke from in front to the back of the pointer position) // We make a very long ray if we are touching a touchable volume to ensure that we actually // hit the volume when we are inside of the volume, which could be very large. var lengthOfPointerRay = newClosestTouchable is NearInteractionTouchableVolume ? maximumTouchableVolumeSize : touchableDistance; Vector3 start = Position + lengthOfPointerRay * closestNormal; Vector3 end = Position - lengthOfPointerRay * closestNormal; Rays[0].UpdateRayStep(ref start, ref end); line.SetPosition(0, Position); line.SetPosition(1, end); } // Check if the currently touched object is still part of the new touchable. if (currentTouchableObjectDown != null) { if (!IsObjectPartOfTouchable(currentTouchableObjectDown, newClosestTouchable)) { TryRaisePokeUp(); } } // Set new touchable only now: If we have to raise a poke-up event for the previous touchable object, // we need to do so using the previous touchable in TryRaisePokeUp(). closestProximityTouchable = newClosestTouchable; visuals.SetActive(IsActive); }
public override void OnPreSceneQuery() { if (Rays == null) { Rays = new RayStep[1]; } closestNormal = Rotation * Vector3.forward; var layerMasks = PrioritizedLayerMasksOverride ?? PokeLayerMasks; // Find closest touchable BaseNearInteractionTouchable newClosestTouchable = null; foreach (var layerMask in layerMasks) { if (FindClosestTouchableForLayerMask(layerMask, out newClosestTouchable, out closestDistance, out closestNormal)) { break; } } if (newClosestTouchable != null) { // Build ray (poke from in front to the back of the pointer position) Vector3 start = Position - newClosestTouchable.PokeThreshold * -closestNormal; Vector3 end = Position + touchableDistance * -closestNormal; Rays[0].UpdateRayStep(ref start, ref end); line.SetPosition(0, Position); line.SetPosition(1, end); } // Check if the currently touched object is still part of the new touchable. if (currentTouchableObjectDown != null) { if (!IsObjectPartOfTouchable(currentTouchableObjectDown, newClosestTouchable)) { TryRaisePokeUp(Result.CurrentPointerTarget, Position); } } // Set new touchable only now: If we have to raise a poke-up event for the previous touchable object, // we need to do so using the previous touchable in TryRaisePokeUp(). closestProximityTouchable = newClosestTouchable; visuals.SetActive(IsActive); }
private bool FindClosestTouchableForLayerMask(LayerMask layerMask, out BaseNearInteractionTouchable closest, out float closestDistance, out Vector3 closestNormal) { closest = null; closestDistance = float.PositiveInfinity; closestNormal = Vector3.zero; int numColliders = UnityEngine.Physics.OverlapSphereNonAlloc(Position, touchableDistance, queryBuffer, layerMask, triggerInteraction); if (numColliders == queryBuffer.Length) { Debug.LogWarning($"Maximum number of {numColliders} colliders found in PokePointer overlap query. Consider increasing the query buffer size in the input system settings."); } for (int i = 0; i < numColliders; ++i) { var touchable = queryBuffer[i].GetComponent <BaseNearInteractionTouchable>(); if (touchable) { float distance = touchable.DistanceToTouchable(Position, out Vector3 normal); if (distance < closestDistance) { closest = touchable; closestDistance = distance; closestNormal = normal; } } } // Unity UI does not provide an equivalent broad-phase test to Physics.OverlapSphere, // so we have to use a static instances list to test all NearInteractionTouchableUnityUI for (int i = 0; i < NearInteractionTouchableUnityUI.Instances.Count; i++) { NearInteractionTouchableUnityUI touchable = NearInteractionTouchableUnityUI.Instances[i]; float distance = touchable.DistanceToTouchable(Position, out Vector3 normal); if (distance <= touchableDistance && distance < closestDistance) { closest = touchable; closestDistance = distance; closestNormal = normal; } } return(closest != null); }