< Summary

Class:DCL.PointerEventsController
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/PointerEventsController/PointerEventsController.cs
Covered lines:190
Uncovered lines:49
Coverable lines:239
Total lines:564
Line coverage:79.4% (190 of 239)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
PointerEventsController()0%110100%
Initialize()0%440100%
Update()0%32.531088.41%
EventObjectCanBeHovered(...)0%440100%
ResolveGenericRaycastHandlers(...)0%1101000%
UnhoverLastHoveredObject()0%660100%
Dispose()0%4.034087.5%
RetrieveCamera()0%220100%
GetRayFromCamera()0%110100%
OnButtonEvent(...)0%14.669058.82%
ProcessButtonUp(...)0%5.295077.27%
ProcessButtonDown(...)0%13.9813082.05%
ReportGlobalPointerUpEvent(...)0%5.935066.67%
ReportGlobalPointerDownEvent(...)0%550100%
AreSameEntity(...)0%330100%
IsBlockingOnClick(...)0%440100%
EntityHasPointerEvent(...)0%440100%
AreCollidersFromSameEntity(...)0%5.025090.91%
HandleCursorLockChanges(...)0%220100%
HideOrShowCursor(...)0%440100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/PointerEventsController/PointerEventsController.cs

#LineLine coverage
 1using System;
 2using DCL.Components;
 3using DCL.Configuration;
 4using DCL.Helpers;
 5using DCL.Interface;
 6using UnityEngine;
 7using UnityEngine.UI;
 8using UnityEngine.EventSystems;
 9using System.Collections.Generic;
 10using System.Linq;
 11using DCL.Models;
 12using Ray = UnityEngine.Ray;
 13
 14namespace DCL
 15{
 16    public class PointerEventsController : IPointerEventsController
 17    {
 018        private static bool renderingEnabled => CommonScriptableObjects.rendererState.Get();
 19        public System.Action OnPointerHoverStarts;
 20        public System.Action OnPointerHoverEnds;
 21
 22        InteractionHoverCanvasController hoverController;
 23        RaycastHitInfo lastPointerDownEventHitInfo;
 24        IPointerInputEvent pointerInputUpEvent;
 66725        IRaycastHandler raycastHandler = new RaycastHandler();
 26
 27        Camera charCamera;
 28
 29        GameObject lastHoveredObject = null;
 30        GameObject newHoveredGO = null;
 31
 32        IPointerEvent newHoveredInputEvent = null;
 33        IPointerEvent[] lastHoveredEventList = null;
 34
 35        RaycastHit hitInfo;
 66736        PointerEventData uiGraphicRaycastPointerEventData = new PointerEventData(null);
 66737        List<RaycastResult> uiGraphicRaycastResults = new List<RaycastResult>();
 38        GraphicRaycaster uiGraphicRaycaster;
 39
 40        public void Initialize()
 41        {
 2001042            for (int i = 0; i < Enum.GetValues(typeof(WebInterface.ACTION_BUTTON)).Length; i++)
 43            {
 933844                var buttonId = (WebInterface.ACTION_BUTTON)i;
 45
 933846                if (buttonId == WebInterface.ACTION_BUTTON.ANY)
 47                    continue;
 48
 867149                InputController_Legacy.i.AddListener(buttonId, OnButtonEvent);
 50            }
 51
 66752            hoverController = InteractionHoverCanvasController.i;
 53
 66754            if (CursorController.i != null)
 55            {
 57256                OnPointerHoverStarts += CursorController.i.SetHoverCursor;
 57257                OnPointerHoverEnds += CursorController.i.SetNormalCursor;
 58            }
 59
 66760            RetrieveCamera();
 61
 66762            Environment.i.platform.updateEventHandler.AddListener(IUpdateEventHandler.EventType.Update, Update);
 66763            Utils.OnCursorLockChanged += HandleCursorLockChanges;
 64
 66765            HideOrShowCursor(Utils.IsCursorLocked);
 66766        }
 67
 68        private IRaycastPointerClickHandler clickHandler;
 69
 70        public void Update()
 71        {
 761072            if ( charCamera == null )
 155073                RetrieveCamera();
 74
 761075            if (!CommonScriptableObjects.rendererState.Get() || charCamera == null)
 151376                return;
 1163377            if (!Utils.IsCursorLocked) return;
 78
 56179            IWorldState worldState = Environment.i.world.state;
 80
 81            // We use Physics.Raycast() instead of our raycastHandler.Raycast() as that one is slower, sometimes 2x, bec
 56182            bool didHit = Physics.Raycast(GetRayFromCamera(), out hitInfo, Mathf.Infinity, PhysicsLayers.physicsCastLaye
 56183            bool uiIsBlocking = false;
 56184            string currentSceneId = worldState.currentSceneId;
 85
 56186            bool validCurrentSceneId = !string.IsNullOrEmpty(currentSceneId);
 56187            bool validCurrentScene = validCurrentSceneId && worldState.loadedScenes.ContainsKey(currentSceneId);
 88
 89            // NOTE: in case of a single scene loaded (preview or builder) sceneId is set to null when stepping outside
 56190            if (didHit && validCurrentSceneId && validCurrentScene)
 91            {
 31092                UIScreenSpace currentUIScreenSpace = worldState.loadedScenes[currentSceneId].GetSharedComponent<UIScreen
 31093                GraphicRaycaster raycaster = currentUIScreenSpace?.graphicRaycaster;
 94
 31095                if (raycaster)
 96                {
 697                    uiGraphicRaycastPointerEventData.position = new Vector2(Screen.width / 2, Screen.height / 2);
 698                    uiGraphicRaycastResults.Clear();
 699                    raycaster.Raycast(uiGraphicRaycastPointerEventData, uiGraphicRaycastResults);
 6100                    uiIsBlocking = uiGraphicRaycastResults.Count > 0;
 101                }
 102            }
 103
 561104            if (!didHit || uiIsBlocking)
 105            {
 253106                clickHandler = null;
 253107                UnhoverLastHoveredObject();
 253108                return;
 109            }
 110
 308111            var raycastHandlerTarget = hitInfo.collider.GetComponent<IRaycastPointerHandler>();
 308112            if (raycastHandlerTarget != null)
 113            {
 0114                ResolveGenericRaycastHandlers(raycastHandlerTarget);
 0115                UnhoverLastHoveredObject();
 0116                return;
 117            }
 118
 308119            if (CollidersManager.i.GetColliderInfo(hitInfo.collider, out ColliderInfo info))
 308120                newHoveredInputEvent = info.entity.gameObject.GetComponentInChildren<IPointerEvent>();
 121            else
 0122                newHoveredInputEvent = hitInfo.collider.GetComponentInChildren<IPointerEvent>();
 123
 308124            clickHandler = null;
 125
 308126            if (!EventObjectCanBeHovered(info, hitInfo.distance))
 127            {
 21128                UnhoverLastHoveredObject();
 21129                return;
 130            }
 131
 287132            newHoveredGO = newHoveredInputEvent.GetTransform().gameObject;
 133
 287134            if (newHoveredGO != lastHoveredObject)
 135            {
 18136                UnhoverLastHoveredObject();
 137
 18138                lastHoveredObject = newHoveredGO;
 139
 18140                lastHoveredEventList = newHoveredInputEvent.entity.gameObject.transform.Cast<Transform>()
 37141                                                           .Select(child => child.GetComponent<IPointerEvent>())
 37142                                                           .Where(pointerComponent => pointerComponent != null)
 143                                                           .ToArray();
 144
 145                // NOTE: this case is for the Avatar, since it hierarchy differs from other ECS components
 18146                if (lastHoveredEventList?.Length == 0)
 147                {
 0148                    lastHoveredEventList = newHoveredGO.GetComponents<IPointerEvent>();
 149                }
 150
 18151                OnPointerHoverStarts?.Invoke();
 152            }
 153
 154            // OnPointerDown/OnClick and OnPointerUp should display their hover feedback at different moments
 287155            if (lastHoveredEventList != null && lastHoveredEventList.Length > 0)
 156            {
 287157                bool isEntityShowingHoverFeedback = false;
 158
 1150159                for (int i = 0; i < lastHoveredEventList.Length; i++)
 160                {
 288161                    if (lastHoveredEventList[i] is IPointerInputEvent e)
 162                    {
 280163                        bool eventButtonIsPressed = InputController_Legacy.i.IsPressed(e.GetActionButton());
 164
 280165                        bool isClick = e.GetEventType() == PointerInputEventType.CLICK;
 280166                        bool isDown = e.GetEventType() == PointerInputEventType.DOWN;
 280167                        bool isUp = e.GetEventType() == PointerInputEventType.UP;
 168
 280169                        if (isUp && eventButtonIsPressed)
 170                        {
 0171                            e.SetHoverState(true);
 0172                            isEntityShowingHoverFeedback = isEntityShowingHoverFeedback || e.ShouldShowHoverFeedback();
 0173                        }
 280174                        else if ((isDown || isClick) && !eventButtonIsPressed)
 175                        {
 278176                            e.SetHoverState(true);
 278177                            isEntityShowingHoverFeedback = isEntityShowingHoverFeedback || e.ShouldShowHoverFeedback();
 278178                        }
 2179                        else if (!isEntityShowingHoverFeedback)
 180                        {
 2181                            e.SetHoverState(false);
 182                        }
 2183                    }
 184                    else
 185                    {
 8186                        lastHoveredEventList[i].SetHoverState(true);
 187                    }
 188                }
 189            }
 190
 287191            newHoveredGO = null;
 287192            newHoveredInputEvent = null;
 287193        }
 194
 195        private bool EventObjectCanBeHovered(ColliderInfo colliderInfo, float distance)
 196        {
 308197            return newHoveredInputEvent != null &&
 198                   newHoveredInputEvent.IsAtHoverDistance(distance) &&
 199                   newHoveredInputEvent.IsVisible() &&
 200                   AreSameEntity(newHoveredInputEvent, colliderInfo);
 201        }
 202
 203        private void ResolveGenericRaycastHandlers(IRaycastPointerHandler raycastHandlerTarget)
 204        {
 0205            if (Utils.LockedThisFrame())
 0206                return;
 207
 0208            var mouseIsDown = Input.GetMouseButtonDown(0);
 0209            var mouseIsUp = Input.GetMouseButtonUp(0);
 210
 0211            if (raycastHandlerTarget is IRaycastPointerDownHandler down)
 212            {
 0213                if (mouseIsDown)
 0214                    down.OnPointerDown();
 215            }
 216
 0217            if (raycastHandlerTarget is IRaycastPointerUpHandler up)
 218            {
 0219                if (mouseIsUp)
 0220                    up.OnPointerUp();
 221            }
 222
 0223            if (raycastHandlerTarget is IRaycastPointerClickHandler click)
 224            {
 0225                if (mouseIsDown)
 0226                    clickHandler = click;
 227
 0228                if (mouseIsUp)
 229                {
 0230                    if (clickHandler == click)
 0231                        click.OnPointerClick();
 0232                    clickHandler = null;
 233                }
 234            }
 0235        }
 236
 237        void UnhoverLastHoveredObject()
 238        {
 335239            if (lastHoveredObject == null)
 240            {
 317241                if ( hoverController != null )
 309242                    hoverController.SetHoverState(false);
 243
 317244                return;
 245            }
 246
 18247            OnPointerHoverEnds?.Invoke();
 248
 74249            for (int i = 0; i < lastHoveredEventList.Length; i++)
 250            {
 19251                if (lastHoveredEventList[i] == null)
 252                    continue;
 19253                lastHoveredEventList[i].SetHoverState(false);
 254            }
 255
 18256            lastHoveredEventList = null;
 18257            lastHoveredObject = null;
 18258        }
 259
 260        public void Dispose()
 261        {
 20010262            for (int i = 0; i < Enum.GetValues(typeof(WebInterface.ACTION_BUTTON)).Length; i++)
 263            {
 9338264                var buttonId = (WebInterface.ACTION_BUTTON)i;
 265
 9338266                if (buttonId == WebInterface.ACTION_BUTTON.ANY)
 267                    continue;
 268
 8671269                InputController_Legacy.i.RemoveListener(buttonId, OnButtonEvent);
 270            }
 271
 667272            lastHoveredObject = null;
 667273            newHoveredGO = null;
 667274            newHoveredInputEvent = null;
 667275            lastHoveredEventList = null;
 276
 667277            if (CursorController.i != null)
 278            {
 0279                OnPointerHoverStarts -= CursorController.i.SetHoverCursor;
 0280                OnPointerHoverEnds -= CursorController.i.SetNormalCursor;
 281            }
 282
 667283            Environment.i.platform.updateEventHandler.RemoveListener(IUpdateEventHandler.EventType.Update, Update);
 667284            Utils.OnCursorLockChanged -= HandleCursorLockChanges;
 667285        }
 286
 287        void RetrieveCamera()
 288        {
 2217289            if (charCamera == null)
 290            {
 2217291                charCamera = Camera.main;
 292            }
 2217293        }
 294
 575295        public Ray GetRayFromCamera() { return charCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height /
 296
 297        void OnButtonEvent(WebInterface.ACTION_BUTTON buttonId, InputController_Legacy.EVENT evt, bool useRaycast, bool 
 298        {
 299            //TODO(Brian): We should remove this when we get a proper initialization layer
 14300            if (!EnvironmentSettings.RUNNING_TESTS)
 301            {
 0302                if (Utils.LockedThisFrame())
 0303                    return;
 304
 0305                if (!Utils.IsCursorLocked || !renderingEnabled)
 0306                    return;
 307            }
 308
 14309            if (charCamera == null)
 310            {
 0311                RetrieveCamera();
 312
 0313                if (charCamera == null)
 0314                    return;
 315            }
 316
 14317            var pointerEventLayer = PhysicsLayers.physicsCastLayerMaskWithoutCharacter; //Ensure characterController is 
 14318            var globalLayer = pointerEventLayer & ~PhysicsLayers.physicsCastLayerMask;
 319
 14320            if (evt == InputController_Legacy.EVENT.BUTTON_DOWN)
 321            {
 11322                ProcessButtonDown(buttonId, useRaycast, enablePointerEvent, pointerEventLayer, globalLayer);
 11323            }
 3324            else if (evt == InputController_Legacy.EVENT.BUTTON_UP)
 325            {
 3326                ProcessButtonUp(buttonId, useRaycast, enablePointerEvent, pointerEventLayer, globalLayer);
 327            }
 3328        }
 329
 330        private void ProcessButtonUp(WebInterface.ACTION_BUTTON buttonId, bool useRaycast, bool enablePointerEvent, Laye
 331        {
 3332            IWorldState worldState = Environment.i.world.state;
 333
 3334            if (string.IsNullOrEmpty(worldState.currentSceneId))
 0335                return;
 336
 337            RaycastHitInfo raycastGlobalLayerHitInfo;
 3338            Ray ray = GetRayFromCamera();
 339
 340            // Raycast for global pointer events
 3341            RaycastResultInfo raycastInfoGlobalLayer = raycastHandler.Raycast(ray, charCamera.farClipPlane, globalLayer,
 3342            raycastGlobalLayerHitInfo = raycastInfoGlobalLayer.hitInfo;
 343
 3344            if (pointerInputUpEvent != null)
 345            {
 346                // Raycast for pointer event components
 3347                RaycastResultInfo raycastInfoPointerEventLayer = raycastHandler.Raycast(ray, charCamera.farClipPlane, po
 348
 3349                bool isOnClickComponentBlocked = IsBlockingOnClick(raycastInfoPointerEventLayer.hitInfo, raycastGlobalLa
 3350                bool isSameEntityThatWasPressed = AreCollidersFromSameEntity(raycastInfoPointerEventLayer.hitInfo, lastP
 351
 3352                if (!isOnClickComponentBlocked && isSameEntityThatWasPressed && enablePointerEvent)
 353                {
 3354                    pointerInputUpEvent.Report(buttonId, ray, raycastInfoPointerEventLayer.hitInfo.hit);
 355                }
 356
 3357                pointerInputUpEvent = null;
 358            }
 359
 3360            ReportGlobalPointerUpEvent(buttonId, useRaycast, raycastGlobalLayerHitInfo, raycastInfoGlobalLayer, worldSta
 361
 362            // Raycast for global pointer events (for each PE scene)
 3363            List<string> currentPortableExperienceIds = WorldStateUtils.GetActivePortableExperienceIds();
 6364            for (int i = 0; i < currentPortableExperienceIds.Count; i++)
 365            {
 0366                raycastInfoGlobalLayer = raycastHandler.Raycast(ray, charCamera.farClipPlane, globalLayer, worldState.lo
 0367                raycastGlobalLayerHitInfo = raycastInfoGlobalLayer.hitInfo;
 368
 0369                ReportGlobalPointerUpEvent(buttonId, useRaycast, raycastGlobalLayerHitInfo, raycastInfoGlobalLayer, curr
 370            }
 3371        }
 372
 373        private void ProcessButtonDown(WebInterface.ACTION_BUTTON buttonId, bool useRaycast, bool enablePointerEvent, La
 374        {
 11375            IWorldState worldState = Environment.i.world.state;
 376
 11377            if (string.IsNullOrEmpty(worldState.currentSceneId))
 0378                return;
 379
 380            RaycastHitInfo raycastGlobalLayerHitInfo;
 11381            Ray ray = GetRayFromCamera();
 382
 383            // Raycast for pointer event components
 11384            RaycastResultInfo raycastInfoPointerEventLayer = raycastHandler.Raycast(ray, charCamera.farClipPlane, pointe
 385
 386            // Raycast for global pointer events
 11387            RaycastResultInfo raycastInfoGlobalLayer = raycastHandler.Raycast(ray, charCamera.farClipPlane, globalLayer,
 11388            raycastGlobalLayerHitInfo = raycastInfoGlobalLayer.hitInfo;
 389
 11390            bool isOnClickComponentBlocked = IsBlockingOnClick(raycastInfoPointerEventLayer.hitInfo, raycastGlobalLayerH
 391
 11392            if (!isOnClickComponentBlocked && raycastInfoPointerEventLayer.hitInfo.hit.collider)
 393            {
 10394                Collider collider = raycastInfoPointerEventLayer.hitInfo.hit.collider;
 395
 396                GameObject hitGameObject;
 397
 10398                if (CollidersManager.i.GetColliderInfo(collider, out ColliderInfo info))
 10399                    hitGameObject = info.entity.gameObject;
 400                else
 0401                    hitGameObject = collider.gameObject;
 402
 10403                var events = hitGameObject.GetComponentsInChildren<IPointerInputEvent>();
 404
 36405                for (var i = 0; i < events.Length; i++)
 406                {
 8407                    IPointerInputEvent e = events[i];
 8408                    bool areSameEntity = AreSameEntity(e, info);
 409
 8410                    switch (e.GetEventType())
 411                    {
 412                        case PointerInputEventType.CLICK:
 1413                            if (areSameEntity && enablePointerEvent)
 1414                                e.Report(buttonId, ray, raycastInfoPointerEventLayer.hitInfo.hit);
 1415                            break;
 416                        case PointerInputEventType.DOWN:
 4417                            if (areSameEntity && enablePointerEvent)
 4418                                e.Report(buttonId, ray, raycastInfoPointerEventLayer.hitInfo.hit);
 4419                            break;
 420                        case PointerInputEventType.UP:
 3421                            if (areSameEntity && enablePointerEvent)
 3422                                pointerInputUpEvent = e;
 423                            else
 0424                                pointerInputUpEvent = null;
 425                            break;
 426                    }
 427                }
 428
 10429                lastPointerDownEventHitInfo = raycastInfoPointerEventLayer.hitInfo;
 430            }
 431
 11432            ReportGlobalPointerDownEvent(buttonId, useRaycast, raycastGlobalLayerHitInfo, raycastInfoGlobalLayer, worldS
 433
 434            // Raycast for global pointer events (for each PE scene)
 11435            List<string> currentPortableExperienceIds = WorldStateUtils.GetActivePortableExperienceIds();
 22436            for (int i = 0; i < currentPortableExperienceIds.Count; i++)
 437            {
 0438                raycastInfoGlobalLayer = raycastHandler.Raycast(ray, charCamera.farClipPlane, globalLayer, worldState.lo
 0439                raycastGlobalLayerHitInfo = raycastInfoGlobalLayer.hitInfo;
 440
 0441                ReportGlobalPointerDownEvent(buttonId, useRaycast, raycastGlobalLayerHitInfo, raycastInfoGlobalLayer, cu
 442            }
 11443        }
 444
 445        private void ReportGlobalPointerUpEvent(
 446            WebInterface.ACTION_BUTTON buttonId,
 447            bool useRaycast,
 448            RaycastHitInfo raycastGlobalLayerHitInfo,
 449            RaycastResultInfo raycastInfoGlobalLayer,
 450            string sceneId)
 451        {
 3452            if (useRaycast && raycastGlobalLayerHitInfo.isValid)
 453            {
 3454                CollidersManager.i.GetColliderInfo(raycastGlobalLayerHitInfo.hit.collider, out ColliderInfo colliderInfo
 455
 3456                WebInterface.ReportGlobalPointerUpEvent(
 457                    buttonId,
 458                    raycastInfoGlobalLayer.ray,
 459                    raycastGlobalLayerHitInfo.hit.point,
 460                    raycastGlobalLayerHitInfo.hit.normal,
 461                    raycastGlobalLayerHitInfo.hit.distance,
 462                    sceneId,
 463                    colliderInfo.entity != null ? colliderInfo.entity.entityId : null,
 464                    colliderInfo.meshName,
 465                    isHitInfoValid: true);
 3466            }
 467            else
 468            {
 0469                WebInterface.ReportGlobalPointerUpEvent(buttonId, raycastInfoGlobalLayer.ray, Vector3.zero, Vector3.zero
 470            }
 0471        }
 472
 473        private void ReportGlobalPointerDownEvent(
 474            WebInterface.ACTION_BUTTON buttonId,
 475            bool useRaycast,
 476            RaycastHitInfo raycastGlobalLayerHitInfo,
 477            RaycastResultInfo raycastInfoGlobalLayer,
 478            string sceneId)
 479        {
 11480            if (useRaycast && raycastGlobalLayerHitInfo.isValid)
 481            {
 10482                CollidersManager.i.GetColliderInfo(raycastGlobalLayerHitInfo.hit.collider, out ColliderInfo colliderInfo
 483
 10484                WebInterface.ReportGlobalPointerDownEvent(
 485                    buttonId,
 486                    raycastInfoGlobalLayer.ray,
 487                    raycastGlobalLayerHitInfo.hit.point,
 488                    raycastGlobalLayerHitInfo.hit.normal,
 489                    raycastGlobalLayerHitInfo.hit.distance,
 490                    sceneId,
 491                    colliderInfo.entity != null ? colliderInfo.entity.entityId : null,
 492                    colliderInfo.meshName,
 493                    isHitInfoValid: true);
 10494            }
 495            else
 496            {
 1497                WebInterface.ReportGlobalPointerDownEvent(buttonId, raycastInfoGlobalLayer.ray, Vector3.zero, Vector3.ze
 498            }
 1499        }
 500
 296501        bool AreSameEntity(IPointerEvent pointerInputEvent, ColliderInfo colliderInfo) { return pointerInputEvent != nul
 502
 503        bool IsBlockingOnClick(RaycastHitInfo targetOnClickHit, RaycastHitInfo potentialBlockerHit)
 504        {
 14505            return
 506                potentialBlockerHit.hit.collider != null // Does a potential blocker hit exist?
 507                && targetOnClickHit.hit.collider != null // Was a target entity with a pointer event component hit?
 508                && potentialBlockerHit.hit.distance <= targetOnClickHit.hit.distance // Is potential blocker nearer than
 509                && !AreCollidersFromSameEntity(potentialBlockerHit, targetOnClickHit); // Does potential blocker belong 
 510        }
 511
 512        bool EntityHasPointerEvent(IDCLEntity entity)
 513        {
 32514            return entity.components.ContainsKey(Models.CLASS_ID_COMPONENT.UUID_CALLBACK) ||
 515                   entity.components.ContainsKey(Models.CLASS_ID_COMPONENT.UUID_ON_UP) ||
 516                   entity.components.ContainsKey(Models.CLASS_ID_COMPONENT.UUID_ON_DOWN) ||
 517                   entity.components.ContainsKey(Models.CLASS_ID_COMPONENT.UUID_ON_CLICK);
 518        }
 519
 520        bool AreCollidersFromSameEntity(RaycastHitInfo hitInfoA, RaycastHitInfo hitInfoB)
 521        {
 16522            CollidersManager.i.GetColliderInfo(hitInfoA.hit.collider, out ColliderInfo colliderInfoA);
 16523            CollidersManager.i.GetColliderInfo(hitInfoB.hit.collider, out ColliderInfo colliderInfoB);
 524
 16525            var entityA = colliderInfoA.entity;
 16526            var entityB = colliderInfoB.entity;
 527
 16528            bool entityAHasEvent = entityA != null && EntityHasPointerEvent(entityA);
 16529            bool entityBHasEvent = entityB != null && EntityHasPointerEvent(entityB);
 530
 531            // If both entities has OnClick/PointerEvent component
 16532            if (entityAHasEvent && entityBHasEvent)
 533            {
 14534                return entityA == entityB;
 535            }
 536            // If only one of them has OnClick/PointerEvent component
 2537            else if (entityAHasEvent ^ entityBHasEvent)
 538            {
 0539                return false;
 540            }
 541            // None of them has OnClick/PointerEvent component
 542            else
 543            {
 2544                return colliderInfoA.entity == colliderInfoB.entity;
 545            }
 546        }
 547
 548        private void HandleCursorLockChanges(bool isLocked)
 549        {
 81550            HideOrShowCursor(isLocked);
 551
 81552            if (!isLocked)
 43553                UnhoverLastHoveredObject();
 81554        }
 555
 556        private void HideOrShowCursor(bool isCursorLocked)
 557        {
 748558            if (isCursorLocked)
 46559                CursorController.i?.Show();
 560            else
 702561                CursorController.i?.Hide();
 702562        }
 563    }
 564}