https://gamedevelopment.tutsplus.com/tutorials/positioning-on-screen-indicators-to-point-to-off-screen-targets--gamedev-6644
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScreenIndicator : MonoBehaviour {
public Transform targetPosOnScreen;
public Transform Indicator;
public float IndicatorEdgeDistance = 0.9f;
void Update(){
// Create a variable for the center position of the screen.
Vector3 screenCenter = new Vector3(Screen.width, Screen.height, 0) / 2;
// Set newIndicatorPos anchor to the center of the screen instead of bottom left
Vector3 newIndicatorPos = targetPosOnScreen.position - screenCenter;
// Flip the newIndicatorPos to correct the calculations for indicators behind the camera.
if (newIndicatorPos.z < 0)
newIndicatorPos *= -1;
// Get angle from center of screen to target position
float angle = Mathf.Atan2(newIndicatorPos.y, newIndicatorPos.x);
angle -= 90 * Mathf.Deg2Rad;
// y = mx + b (intercept forumla)
float cos = Mathf.Cos(angle);
float sin = Mathf.Sin(angle);
float m = cos / sin;
// Create the screen boundaries that the indicators reside in.
Vector3 screenBounds = new Vector3(screenCenter.x*IndicatorEdgeDistance, screenCenter.y*IndicatorEdgeDistance);
// Check which screen side the target is currently in.
// Check top & bottom
if (cos > 0)
newIndicatorPos = new Vector2(-screenBounds.y / m, screenBounds.y);
else
newIndicatorPos = new Vector2(screenBounds.y / m, -screenBounds.y);
// Check left & right
if (newIndicatorPos.x > screenBounds.x)
newIndicatorPos = new Vector2(screenBounds.x, -screenBounds.x * m);
else if (newIndicatorPos.x < -screenBounds.x)
newIndicatorPos = new Vector2(-screenBounds.x, screenBounds.x * m);
// Reset the newIndicatorPos anchor back to bottom left corner.
newIndicatorPos += screenCenter;
Indicator.position = newIndicatorPos;
}
}
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
/// <summary>
/// User interface manager.
/// </summary>
public class ScreenIndicatorEasy : MonoBehaviour
{
public Transform targetPosition;
public Image targetIndicator;
/// <summary>
/// Sets the position and visibility for an offscreen indicator for one of the moving objects.
/// </summary>
/// <param name="indicator">The indicator image.</param>
/// <param name="objectPos">Object position.</param>
void SetIndicatorPosition(Image indicator, Vector3 objectPos)
{
// Convert world position to screen position
Vector3 objectScreenPos = Camera.main.WorldToScreenPoint(objectPos);
// Clamp the obhject position to screen boundaries
Vector3 indicatorPos = new Vector3();
indicatorPos.x = Mathf.Clamp(objectScreenPos.x, 0, Screen.width);
indicatorPos.y = Mathf.Clamp(objectScreenPos.y, 0, Screen.height);
indicatorPos.z = objectScreenPos.z;
// Adjust indicator position to be fully on-screen, instead of halfway off-screen.
indicatorPos.x = Mathf.Clamp(objectScreenPos.x, indicator.rectTransform.rect.width, Screen.width - indicator.rectTransform.rect.width);
indicatorPos.y = Mathf.Clamp(objectScreenPos.y, indicator.rectTransform.rect.height, Screen.height - indicator.rectTransform.rect.height);
indicatorPos.z = 0.0F;
// Point the indicator in the direction of the off-screen object,
// and move it to the correct location.
Vector3 indicatorDir = objectScreenPos - indicatorPos;
indicator.transform.up = indicatorDir.normalized;
indicator.transform.position = indicatorPos;
}
}