I have absolutely no idea if what I am trying to do even has a name at all, so please bare with me.
I want to have a UI Object on screen during the game, it is just basic text and an image behind it for contrast and it will change throughout the game, but if your character were to walk in the direction the UI is on the screen, eventually when the gameobject comes into view, you’d see the UI lock on the game object, so you know that’s what is speaking etc.
Like being able to hear something from far off, but once you approach it, you can see whats actually talking. you know?
Would anyone know what this is called or how I can perform this using the new Unity UI elements?
Thanks
I made a simplified version of this tutorial here:
Here is the script, its not perfect but should give you an idea on how it works
using UnityEngine;
using UnityEngine.UI;
public class OffScreenIndicator : MonoBehaviour
{
[SerializeField] private Image _uiArrow;
[SerializeField] private Image _uiIndicator;
[SerializeField] private Transform _trackingObject;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
UpdateOffscrenIndicator(_trackingObject.position);
}
private void UpdateOffscrenIndicator(Vector3 position)
{
// Based on code from https://www.youtube.com/watch?v=gAQpR1GN0Os
// youtube user digijin
Vector3 screenpos = Camera.main.WorldToScreenPoint(position);
if (screenpos.z > 0 && screenpos.x > 0 && screenpos.x < Screen.width && screenpos.y > 0 && screenpos.y < Screen.height)
{
// THE OBJECT IS INSIDE VIEW
_uiIndicator.transform.position = screenpos;
_uiIndicator.transform.rotation = Quaternion.Euler(0, 0, 0);
_uiIndicator.enabled = true;
_uiArrow.enabled = false;
}
else
{
// THE OBJECT IS OUTSIDE VIEW
_uiIndicator.enabled = false;
_uiArrow.enabled = true;
Vector3 screenCenter = new Vector3(Screen.width, Screen.height, 0) / 2;
screenpos -= screenCenter;
if (screenpos.z < 0)
{
screenpos *= -1;
}
float angle = Mathf.Atan2(screenpos.y, screenpos.x);
angle -= 90 * Mathf.Deg2Rad;
float cos = Mathf.Cos(angle);
float sin = Mathf.Sin(angle);
screenpos = screenCenter + new Vector3(sin * 150, cos * 150, 0);
float m = cos / sin;
Vector3 screenBounds = screenCenter * 1f;
screenpos = cos > 0 ? new Vector3(-screenBounds.y / m, screenCenter.y, 0) : new Vector3(screenBounds.y / m, -screenCenter.y, 0);
if (screenpos.x > screenBounds.x)
{
screenpos = new Vector3(screenBounds.x, -screenBounds.x * m, 0);
}
else if (screenpos.x < -screenBounds.x)
{
screenpos = new Vector3(-screenBounds.x, screenBounds.x * m, 0);
}
screenpos += screenCenter;
_uiArrow.transform.position = screenpos;
_uiArrow.transform.rotation = Quaternion.Euler(0, 0, angle * Mathf.Rad2Deg);
}
}
}