private void UpdatePointer(PointerData pointer)
        {
            // Call the pointer's OnPreSceneQuery function
            // This will give it a chance to prepare itself for raycasts
            // e.g., by building its Rays array
            pointer.Pointer.OnPreSceneQuery();

            // If pointer interaction isn't enabled, clear its result object and return
            if (!pointer.Pointer.IsInteractionEnabled)
            {
                // Don't clear the previous focused object since we still want to trigger FocusExit events
                pointer.ResetFocusedObjects(false);
            }
            else
            {
                // If the pointer is locked, keep the focused object the same.
                // This will ensure that we execute events on those objects
                // even if the pointer isn't pointing at them.
                if (pointer.Pointer.IsFocusLocked && pointer.Pointer.IsTargetPositionLockedOnFocusLock)
                {
                    pointer.UpdateFocusLockedHit();
                }
                else
                {
                    LayerMask[] prioritizedLayerMasks = (pointer.Pointer.PrioritizedLayerMasksOverride ?? FocusLayerMasks);

                    // Perform raycast to determine focused object
                    hitResult3d.Clear();
                    QueryScene(pointer.Pointer, prioritizedLayerMasks, hitResult3d);
                    PointerHitResult hit = hitResult3d;

                    // If we have a unity event system, perform graphics raycasts as well to support Unity UI interactions
                    if (EventSystem.current != null)
                    {
                        // NOTE: We need to do this AFTER RaycastPhysics so we use the current hit point to perform the correct 2D UI Raycast.
                        hitResultUi.Clear();
                        RaycastGraphics(pointer.Pointer, pointer.GraphicEventData, prioritizedLayerMasks, hitResultUi);

                        hit = GetPrioritizedHitResult(hit, hitResultUi, prioritizedLayerMasks);
                    }

                    // Make sure to keep focus on the previous object if focus is locked (no target position lock here).
                    if (pointer.Pointer.IsFocusLocked && pointer.Pointer.Result?.CurrentPointerTarget != null)
                    {
                        hit.hitObject = pointer.Pointer.Result.CurrentPointerTarget;
                    }

                    // Apply the hit result only now so changes in the current target are detected only once per frame.
                    pointer.UpdateHit(hit);

                    // Set the pointer's result last
                    pointer.Pointer.Result = pointer;
                }
            }

            // Call the pointer's OnPostSceneQuery function.
            // This will give it a chance to respond to raycast results
            // e.g., by updating its appearance.
            pointer.Pointer.OnPostSceneQuery();
        }
Esempio n. 2
0
        private void UpdatePointer(PointerData pointer)
        {
            // Call the pointer's OnPreRaycast function
            // This will give it a chance to prepare itself for raycasts
            // eg, by building its Rays array
            pointer.Pointer.OnPreRaycast();

            // If pointer interaction isn't enabled, clear its result object and return
            if (!pointer.Pointer.IsInteractionEnabled)
            {
                // Don't clear the previous focused object since we still want to trigger FocusExit events
                pointer.ResetFocusedObjects(false);

                // Only set the result if it's null
                // Otherwise we'd get incorrect data.
                if (pointer.Pointer.Result == null)
                {
                    pointer.Pointer.Result = pointer;
                }
            }
            else
            {
                // If the pointer is locked, keep the focused object the same.
                // This will ensure that we execute events on those objects
                // even if the pointer isn't pointing at them.
                // We don't want to update focused locked hits if we're syncing the pointer's target position.
                if (pointer.Pointer.IsFocusLocked && pointer.Pointer.SyncedTarget == null)
                {
                    pointer.UpdateFocusLockedHit();
                }
                else
                {
                    // Otherwise, continue
                    var prioritizedLayerMasks = (pointer.Pointer.PrioritizedLayerMasksOverride ?? FocusLayerMasks);

                    physicsHitResult.Clear();

                    // Perform raycast to determine focused object
                    RaycastPhysics(pointer.Pointer, prioritizedLayerMasks, physicsHitResult);
                    var currentHitResult = physicsHitResult;

                    // If we have a unity event system, perform graphics raycasts as well to support Unity UI interactions
                    if (EventSystem.current != null)
                    {
                        graphicsHitResult.Clear();
                        // NOTE: We need to do this AFTER RaycastPhysics so we use the current hit point to perform the correct 2D UI Raycast.
                        RaycastGraphics(pointer.Pointer, pointer.GraphicEventData, prioritizedLayerMasks, graphicsHitResult);

                        currentHitResult = GetPrioritizedHitResult(currentHitResult, graphicsHitResult, prioritizedLayerMasks);
                    }

                    // Apply the hit result only now so changes in the current target are detected only once per frame.
                    pointer.UpdateHit(currentHitResult, pointer.Pointer.SyncedTarget);
                }

                // Set the pointer's result last
                pointer.Pointer.Result = pointer;
            }

            Debug.Assert(pointer.Pointer.Result != null);

            // Call the pointer's OnPostRaycast function
            // This will give it a chance to respond to raycast results
            // eg by updating its appearance
            pointer.Pointer.OnPostRaycast();
        }