Skip to content

Instantly share code, notes, and snippets.

@smkplus
Last active July 17, 2018 03:48
Show Gist options
  • Save smkplus/6a31a5b2b252db6d74e3dc24180174c5 to your computer and use it in GitHub Desktop.
Save smkplus/6a31a5b2b252db6d74e3dc24180174c5 to your computer and use it in GitHub Desktop.
Positioning On-Screen Indicators to Point to Off-Screen Targets

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;
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment