using UnityEngine; using UnityEngine.UI; public class TargetToScreen : MonoBehaviour { [Header("Assign below variables in the inspector:")] public Transform targetTransform; [SerializeField] Vector3 targetPositionOffset = new(0, 1, 0); [SerializeField] float screenBoundOffset = 0.1f; [SerializeField] RectTransform targetImage, targetImageArrow; [SerializeField] Text targetText; [Header("Below is for Debug use:")] [SerializeField] Vector3 screenPosition, screenBound; [SerializeField] Vector2 Arrowdirection; private void LateUpdate() { if(targetTransform) TargetToScreenPosition(); } /// /// This function is to convert the world position of the target to the screen position, and then update the position of the target image and the arrow image. /// public void TargetToScreenPosition() { screenPosition = Camera.main.WorldToScreenPoint(targetTransform.position + targetPositionOffset);// simple way to get the screen position of the target (screenBound.x, screenBound.y) = (Screen.width, Screen.height);//get the screen size if (screenPosition.z < 0)//if the target is behind the camera, flip the screen position { screenPosition = -screenPosition; if (screenPosition.y > screenBound.y / 2)//this is to avoid small probablity that the target is behind the camera and the screen position is flipped, but the y position is still in the screen { screenPosition.y = screenBound.y; } else screenPosition.y = 0; } //clamp the screen position to the screen bound targetImage.transform.position = new Vector2( Mathf.Clamp(screenPosition.x, screenBound.y * screenBoundOffset, screenBound.x - screenBound.y * screenBoundOffset), Mathf.Clamp(screenPosition.y, screenBound.y * screenBoundOffset, screenBound.y - screenBound.y * screenBoundOffset) ); //optional, rotate the arrow to point to the target: Arrowdirection = targetImageArrow.transform.position - screenPosition;//get the direction of the arrow by subtracting the screen position of the target from the screen position of the arrow // Debug.Log(Arrowdirection.magnitude); if (Mathf.Abs(Arrowdirection.x + Arrowdirection.y) < 0.1 || !targetTransform.gameObject.activeSelf) { //disable the arrow when the target is too close to the center of the screen targetImageArrow.gameObject.SetActive(false); //TargetImageArrow.transform.up = Vector2.zero; } else { targetImageArrow.gameObject.SetActive(true); targetImageArrow.transform.up = Arrowdirection; } //optional, update the distance text targetText.text = Vector3.Distance(targetTransform.position, Camera.main.transform.position).ToString("F1") + "m"; } }