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