Off-Camera view Object tracker

Hello everybody!

So I have this problem: basically I want to have a kind of tracker that tells the direction of a certain object e.g. an enemy when it goes off the camera view. The situation would be something like in the image below:

The player being the red square, the object that I want to track the blue ellipse and the tracker the yellow arrow. We are talking of a top-down 2D game.
I was thinking to give the arrow the angle between player and object to have the direction; my specific problem, however, is that I do not know where to start from in order to bound the arrow on the screen borders and only when the targeted object is out of sight. I imagine it should be something tweaking something with the camera? Is the arrow supposed to be an UI element or something else?

Thanks to whoever can give me even a hint! :wink:

Getting the line between the player and your target is easy. But then to put the arrow on that line requires some college algebra: the slope-intercept formula. With that formula you can pick an X pos (the edge of the screen) to get the Y pos of the line at that point.

	public GameObject player;
	public GameObject target;
	public Image arrowPointerUI;

	public void Update()
	{
		float x = 0f;
		float y = 0f;

		Vector2 A = Camera.main.WorldToScreenPoint(player.transform.position);
		Vector2 B = Camera.main.WorldToScreenPoint(target.transform.position);

		// slope
		var m = (B.y - A.y) / (B.x - A.x);
		// y-intercept
		var b = A.y + (-m * A.x);

		// x and y formulas reference
		// y = (m * x) + b;
		// x = (y - b) / m;

		Vector2 offset = arrowPointerUI.rectTransform.sizeDelta / 2;
		Rect scrRect = new Rect(offset, new Vector2(Screen.width - offset.x, Screen.height - offset.y));

		// clamp target x pos to screen to help find y
		x = Mathf.Clamp(B.x, scrRect.xMin, scrRect.xMax);
		y = (m * x) + b;

		// if y is off screen clamp it, then find a better x
		if (y < scrRect.yMin || y > scrRect.yMax) {
			y = Mathf.Clamp(y, scrRect.yMin, scrRect.yMax);
			x = (y - b) / m;
		}

		// arrow position
		Vector2 C = new Vector2(x, y);

		// this checks if target is on screen or not
		if (Vector2.Distance(B, C) > offset.x) {
			// target is far from arrow, so it is off screen
			// show arrow and position it
			arrowPointerUI.enabled = true;
			arrowPointerUI.transform.position = C;

			// rotate arrow to point from player to target
			float angle = Mathf.Atan2(B.y - A.y, B.x - A.x) * Mathf.Rad2Deg;
			arrowPointerUI.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

		} else {
			// target is close to arrow, so it is on screen
			// hide arrow
			arrowPointerUI.enabled = false;
		}
	}

	private void OnDrawGizmos()
	{
		// Draw line between player and target for debugging
		Vector2 A = player.transform.position;
		Vector2 B = target.transform.position;
		Gizmos.DrawLine(A, B);
	}

This assumes a top-down view with the arrow being an UI Image and that it is square. This works fine as long as the player remains inside the scrRect bounds that was set up. If the player leaves those bounds, you can set up a check to hide the arrow.