59 lines
3.0 KiB
C#
59 lines
3.0 KiB
C#
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();
|
|
}
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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";
|
|
}
|
|
} |