Use Physics.Raycast to cast a ray from the Camera. See also Camera.ViewportPointToRay. (0.5, 0.5, 0) is in the middle of the screen with viewport coordinates. When the ray hit something you want to interact with, let it interact with it. It can be solved many ways. I chose to use SendMessage.
I have prepared a complete example for you to download and play around with. To get it to work, import the package and add the scene to build settings.
LookAtPointer should be configured to at least have reference to your Camera. Whatever the camera points to that has a collider will get the messages OnLookEnter, OnLookStay and OnLookExit. There are some parameters to fine tune how it will work, but you can ignore them for now.
LookAtPointer.cs
using UnityEngine;
public class LookAtPointer : MonoBehaviour
{
public new Camera camera;
public Vector2 pointer = new Vector2(0.5f, 0.5f);
public float pointerDistance = float.PositiveInfinity;
public LayerMask pointerMask = -1;
private GameObject oldGO;
private const SendMessageOptions STFU
= SendMessageOptions.DontRequireReceiver;
void Update()
{
Ray ray = camera.ViewportPointToRay(pointer);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, pointerDistance, pointerMask))
{
GameObject newGO = hit.collider.gameObject;
if (oldGO == newGO)
{
oldGO.SendMessage("OnLookStay", STFU);
}
else
{
if (oldGO)
oldGO.SendMessage("OnLookExit", STFU);
newGO.SendMessage("OnLookEnter", STFU);
}
oldGO = newGO;
}
else
{
if (oldGO)
oldGO.SendMessage("OnLookExit", STFU);
oldGO = null;
}
}
}
LookAtSetDescription will update text of a UI Text component whenever it is being looked at. The description text will be copied to that Text component. It requires to be attached to a game object with a collider on it. Optionally you can either set a reference to a Text component, or it will search the scene for a game object called “Description” and access its Text component.
LookAtSetDescription.cs
using UnityEngine;
using UnityEngine.UI;
public class LookAtSetDescription : MonoBehaviour
{
public string description;
public Text text; // Optionally, set text reference.
Text safeText
{
get
{
if (text)
return text;
var shared = GameObject.Find("Description");
if (!shared)
{
Debug.LogError("'Description' GameObject not found!", this);
return null;
}
else
{
var sharedText = shared.GetComponentInChildren<Text>();
if (!sharedText)
Debug.LogError("Text Component not found on 'Description' GameObject!", this);
return sharedText;
}
}
}
void OnLookEnter()
{
safeText.text = description;
}
void OnLookExit()
{
safeText.text = string.Empty;
}
}
LookAtLoadLevel will load the level called levelName after continously looking delay seconds on the object. This is intentionally made so it won’t accidentally load a level.
LookAtLoadLevel.cs
using UnityEngine;
public class LookAtLoadLevel : MonoBehaviour
{
public string levelName;
public float delay = 1f;
void OnLookEnter()
{
Invoke("LoadLevel", delay);
}
void OnLookExit()
{
CancelInvoke("LoadLevel");
}
void LoadLevel()
{
Application.LoadLevel(levelName ?? Application.loadedLevelName);
}
}