Пример #1
0
        //--------------------------------------------------------------------------------------

        #region Monobehaviour Functions
        protected virtual void Awake()
        {
            FocusList      = new List <GameObject>();
            FocusExitList  = new List <GameObject>();
            FocusEnterList = new List <GameObject>();
            FocusHitInfo   = new FocusInfo();

            if (CursorPrefab != null)
            {
                SetCursor(CursorPrefab);
            }
        }
Пример #2
0
        /// <summary>
        /// Will fill the list with UI elements from EventSystem raycast.
        /// </summary>
        /// <param name="focusedItems">The list to be filled.</param>
        /// <returns>Did the raycast hit anything.</returns>
        private bool GetUIRaycasts(ref List <FocusInfo> focusedItems)
        {
            bool hit = false;

            // Get UI raycasts
            m_UIRaycastResults.Clear();
            if (EventSystem.current != null)
            {
                EventSystem.current.RaycastAll(GetPointerData(), m_UIRaycastResults);
                hit = hit ? hit : (m_UIRaycastResults != null && m_UIRaycastResults.Count > 0);

                if (hit)
                {
                    // Add UI hits
                    for (int i = 0; i < m_UIRaycastResults.Count; ++i)
                    {
                        UnityEngine.EventSystems.RaycastResult raycastResult = m_UIRaycastResults[i];

                        float distance = raycastResult.distance;

                        if (distance <= FocusManager.Instance.MaxGazeDistance)
                        {
                            FocusInfo focusInfo = m_FocusInfoPool.GetObject();
                            focusInfo.SetUI(raycastResult.gameObject, true, raycastResult.index, distance, TargetOrigin + (TargetDirection.normalized * distance), -raycastResult.gameObject.transform.forward, raycastResult.gameObject.transform, Vector2.zero, raycastResult);
                            focusedItems.Add(focusInfo);
                        }
                    }

                    // Sort via render order
                    focusedItems.Sort((FocusInfo a, FocusInfo b) => {
                        if (a.raycastResult.sortingLayer != b.raycastResult.sortingLayer)
                        {
                            return(a.raycastResult.sortingLayer.CompareTo(b.raycastResult.sortingLayer));
                        }

                        if (a.raycastResult.sortingOrder != b.raycastResult.sortingOrder)
                        {
                            return(b.raycastResult.sortingOrder.CompareTo(a.raycastResult.sortingOrder));
                        }

                        bool distanceSimilar = Mathf.Approximately(a.distance, b.distance);
                        if (distanceSimilar)
                        {
                            return(a.raycastResult.index.CompareTo(b.raycastResult.index));
                        }
                        return(a.distance.CompareTo(b.distance));
                    });
                }
            }

            return(hit);
        }
Пример #3
0
        /// <summary>
        /// Will fill the list will all colliders from physics raycast.
        /// </summary>
        /// <param name="focusedItems">The list to be filled.</param>
        /// <returns>Did the raycast hit anything.</returns>
        private bool GetColliderRaycasts(ref List <FocusInfo> focusedItems)
        {
            // Get world collider raycasts
            int numberOfHits = Physics.RaycastNonAlloc(FocusRay, m_ColliderRaycastHits, FocusManager.Instance.MaxGazeDistance, FocusManager.Instance.RaycastLayerMask);

            bool hit = numberOfHits > 0;

            if (hit)
            {
                for (int i = 0; i < numberOfHits; ++i)
                {
                    RaycastHit raycastHit = m_ColliderRaycastHits[i];
                    FocusInfo  focusInfo  = m_FocusInfoPool.GetObject();
                    focusInfo.Set(raycastHit.transform.gameObject, raycastHit.distance, raycastHit.point, raycastHit.normal, raycastHit.transform, raycastHit.textureCoord);
                    focusedItems.Add(focusInfo);
                }
            }

            return(hit);
        }
Пример #4
0
        /// <summary>
        /// Calculates the Focus hit position and normal.
        /// </summary>
        public void UpdateRaycast()
        {
            OnPreRaycast();

            Hit = false;
            FocusInfo hitInfo = null;

            FocusRay = new Ray(TargetOrigin, TargetDirection);

            // This must be called at the start of the function, as functions called later in the frame rely on the data.
            CleanFocusedItemCollection();

            // Add UI items
            bool      hitUI       = GetUIRaycasts(ref m_FocusedItems);
            FocusInfo mainUIFocus = null;

            if (hitUI && m_FocusedItems.Count > 0)
            {
                mainUIFocus = m_FocusedItems[0];
            }

            // Perform a preemptive raycast to determine if we are looking at the SR or nothing.
            // If we are doing either, return out of the function early to avoid doing the extra raycast.
            // Bug-Fix: This also fixed a bug where the SR would not allow the pins panel to be opened.
            if (!hitUI)
            {
                RaycastHit hit;
                bool       hitSomething = Physics.Raycast(FocusRay, out hit, FocusManager.Instance.MaxGazeDistance, FocusManager.Instance.RaycastLayerMask);
                if (!hitSomething || hit.transform.gameObject.layer == LayerMask.NameToLayer("SR"))
                {
                    if (hitSomething)
                    {
                        Position = hit.point;
                        Normal   = hit.normal;
                    }
                    else
                    {
                        Position = TargetOrigin + TargetDirection * FocusManager.Instance.MaxGazeDistance;
                        Normal   = TargetDirection;
                    }
                    return;
                }
            }

            // Add colliders
            bool hitCollider = GetColliderRaycasts(ref m_FocusedItems);

            // Check if we hit anything
            if (hitCollider || hitUI)
            {
                // Sort via distance
                m_FocusedItems.Sort((FocusInfo focusInfo1, FocusInfo focusInfo2) => {
                    int ret = focusInfo1.distance.CompareTo(focusInfo2.distance);
                    if (ret == 0)
                    {
                        Graphic graph1 = focusInfo1.gameObject.GetComponent <Graphic>();
                        Graphic graph2 = focusInfo2.gameObject.GetComponent <Graphic>();
                        if (graph1 != null && graph2 != null)
                        {
                            ret = graph2.depth.CompareTo(graph1.depth);
                        }
                    }

                    return(ret);
                });

                // Get the closest valid collider
                for (int i = 0; i < m_FocusedItems.Count; ++i)
                {
                    FocusInfo focusInfo = m_FocusedItems[i];

                    // Check if the transform has a valid filter
                    if (FocusManager.Instance.ContainsValidFilter(focusInfo.transform))
                    {
                        if (focusInfo.isUI && mainUIFocus != null)
                        {
                            focusInfo = mainUIFocus;
                        }

                        hitInfo = focusInfo;
                        Hit     = true;
                        break;
                    }
                }
            }

            if (hitInfo != null)
            {
                // The raycast hit a valid hologram
                FocusHitInfo = hitInfo;
                Position     = hitInfo.point;
                Normal       = hitInfo.normal;
            }
            else
            {
                // If raycast did not hit a hologram... Save defaults
                Position = TargetOrigin + (TargetDirection * FocusManager.Instance.MaxGazeDistance);
                Normal   = TargetDirection;
            }

            OnPostRaycast();
        }