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); } }