void UpdateIndicatorElement(HUDNavigationElement element, Vector3 screenPos, float distance)
        {
            if (useIndicators && element.ShowIndicator)
            {
                // update distance text
                if (useIndicatorDistanceText && element.IndicatorDistance != null)
                {
                    element.IndicatorDistance.text = string.Format(IndicatorDistanceText.TextFormat, (int)distance);
                }

                // check distance and visibility
                if ((distance > IndicatorRadius && !element.IgnoreIndicatorRadius) || (screenPos.z <= 0 && !useIndicatorOffscreen))
                {
                    element.SetIndicatorActive(false);

                    // invoke events
                    if (element.IsInIndicatorRadius)
                    {
                        element.IsInIndicatorRadius = false;
                        element.OnLeaveRadius.Invoke(NavigationElementType.Indicator);
                    }
                }
                else
                {
                    // calculate off-screen position, if indicator is not in sight
                    if (useIndicatorOffscreen && !element.IsVisibleOnScreen(screenPos))
                    {
                        // flip if indicator is behind us
                        if (screenPos.z < 0f)
                        {
                            screenPos.x = Screen.width - screenPos.x;
                            screenPos.y = Screen.height - screenPos.y;
                        }

                        // calculate off-screen position/rotation
                        Vector3 screenCenter = new Vector3(Screen.width, Screen.height, 0f) / 2f;
                        screenPos -= screenCenter;
                        float angle = Mathf.Atan2(screenPos.y, screenPos.x);
                        angle -= 90f * Mathf.Deg2Rad;
                        float cos       = Mathf.Cos(angle);
                        float sin       = -Mathf.Sin(angle);
                        float cotangent = cos / sin;
                        screenPos = screenCenter + new Vector3(sin * 50f, cos * 50f, 0f);

                        // is indicator inside the defined bounds?
                        Vector3 screenBounds = screenCenter * (1f - IndicatorOffscreenBorder);
                        float   boundsY      = (cos > 0f) ? screenBounds.y : -screenBounds.y;
                        screenPos = new Vector3(boundsY / cotangent, boundsY, 0f);

                        // when out of bounds, get point on appropriate side
                        if (screenPos.x > screenBounds.x)                         // out => right
                        {
                            screenPos = new Vector3(screenBounds.x, screenBounds.x * cotangent, 0f);
                        }
                        else if (screenPos.x < -screenBounds.x)                         // out => left
                        {
                            screenPos = new Vector3(-screenBounds.x, -screenBounds.x * cotangent, 0f);
                        }
                        screenPos += screenCenter;

                        // update indicator rotation
                        element.SetIndicatorRotation(Quaternion.Euler(0f, 0f, angle * Mathf.Rad2Deg));

                        // update indicator icon
                        element.SetIndicatorSprite(IndicatorOffscreenSprite, true);

                        // show indicator distance offscreen?
                        element.ShowIndicatorDistance(!hideIndicatorDistanceOffscreen);
                    }
                    else
                    {
                        // reset indicator rotation
                        element.SetIndicatorRotation(Quaternion.identity);

                        // reset indicator icon
                        element.SetIndicatorSprite(null, false);

                        // show indicator distance
                        element.ShowIndicatorDistance(useIndicatorDistanceText);
                    }

                    // update indicator values
                    element.SetIndicatorPosition(screenPos, _HUDNavigationCanvas.Indicator.ElementContainer);
                    element.SetIndicatorScale(distance, IndicatorScaleRadius, IndicatorMinScale);
                    element.SetIndicatorActive(true);

                    // invoke events
                    if (!element.IsInIndicatorRadius)
                    {
                        element.IsInIndicatorRadius = true;
                        element.OnEnterRadius.Invoke(NavigationElementType.Indicator);
                    }
                }
            }
            else
            {
                element.SetIndicatorActive(false);
            }
        }
예제 #2
0
        void UpdateIndicatorElement(HUDNavigationElement element, Vector3 screenPos, float distance)
        {
            if (useIndicators && element.showIndicator)
            {
                // check indicator distance
                if ((distance > indicatorRadius && !element.ignoreIndicatorRadius))
                {
                    element.SetIndicatorActive(false);

                    // invoke events
                    if (element.IsInIndicatorRadius)
                    {
                        element.IsInIndicatorRadius = false;
                        element.OnLeaveRadius.Invoke(element, NavigationElementType.Indicator);
                    }
                }
                else
                {
                    // check if element is visible on screen
                    bool _isElementOnScreen = element.IsVisibleOnScreen(screenPos);
                    if (!_isElementOnScreen)
                    {
                        if (useOffscreenIndicators && element.showOffscreenIndicator)
                        {
                            // flip if indicator is behind us
                            if (screenPos.z < 0f)
                            {
                                screenPos.x = Screen.width - screenPos.x;
                                screenPos.y = Screen.height - screenPos.y;
                            }

                            // calculate off-screen position/rotation
                            Vector3 screenCenter = new Vector3(Screen.width, Screen.height, 0f) / 2f;
                            screenPos -= screenCenter;
                            float angle = Mathf.Atan2(screenPos.y, screenPos.x);
                            angle -= 90f * Mathf.Deg2Rad;
                            float cos       = Mathf.Cos(angle);
                            float sin       = -Mathf.Sin(angle);
                            float cotangent = cos / sin;
                            screenPos = screenCenter + new Vector3(sin * 50f, cos * 50f, 0f);

                            // is indicator inside the defined bounds?
                            float offset = Mathf.Min(screenCenter.x, screenCenter.y);
                            offset = Mathf.Lerp(0f, offset, indicatorOffscreenBorder);
                            Vector3 screenBounds = screenCenter - new Vector3(offset, offset, 0f);
                            float   boundsY      = (cos > 0f) ? screenBounds.y : -screenBounds.y;
                            screenPos = new Vector3(boundsY / cotangent, boundsY, 0f);

                            // when out of bounds, get point on appropriate side
                            if (screenPos.x > screenBounds.x)                             // out => right
                            {
                                screenPos = new Vector3(screenBounds.x, screenBounds.x * cotangent, 0f);
                            }
                            else if (screenPos.x < -screenBounds.x)                             // out => left
                            {
                                screenPos = new Vector3(-screenBounds.x, -screenBounds.x * cotangent, 0f);
                            }
                            screenPos += screenCenter;

                            // update indicator rotation
                            element.SetIndicatorOffscreenRotation(Quaternion.Euler(0f, 0f, angle * Mathf.Rad2Deg));
                        }
                        else
                        {
                            // hide indicator offscreen
                            element.SetIndicatorActive(false);
                            return;
                        }
                    }

                    // show indicator distance?
                    element.ShowIndicatorDistance(_isElementOnScreen, (int)distance);

                    // set indicator on/offscreen
                    element.SetIndicatorOnOffscreen(_isElementOnScreen);

                    // update indicator values
                    element.SetIndicatorPosition(screenPos, _HUDNavigationCanvas.Indicator.ElementContainer);
                    element.SetIndicatorScale(distance, indicatorScaleRadius, indicatorMinScale);
                    element.SetIndicatorActive((indicatorHideDistance > 0f && !element.ignoreIndicatorHideDistance) ? distance > indicatorHideDistance : true);

                    // invoke events
                    if (!element.IsInIndicatorRadius)
                    {
                        element.IsInIndicatorRadius = true;
                        element.OnEnterRadius.Invoke(element, NavigationElementType.Indicator);
                    }
                }
            }
            else
            {
                element.SetIndicatorActive(false);
            }
        }