How to make an Inspect tool in-game?

Hey @Funderful,

A simple solution would be this, using OnMouseEnter and Exit like you suggested:

Simple Package:

Visually:

Code:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class InspectableSimple : MonoBehaviour {

    public RectTransform m_tooltipCanvas;
    public Text m_tooltipText;
    private Transform m_transform;
    private CharacterController m_player;

    void Start()
    {
        m_player = FindObjectOfType<CharacterController>(); // Note that this object is not the player.
        m_transform = transform;
        m_tooltipText.text = string.Format( "Hi, my name is {0}", this.name );
    }

    void Update()
    {
        // Since a canvas' forward is turned away from the camera by default, we'll make the canvas look in the opposite direction.
        Vector3 inverseDirection = m_tooltipCanvas.position - m_player.transform.position;
        m_tooltipCanvas.rotation = Quaternion.LookRotation( inverseDirection );
    }

	void OnMouseEnter()
    {
        _setTooltip( true );
    }

    void OnMouseExit()
    {
        _setTooltip( false );
    }

    private void _setTooltip(bool visible)
    {
        m_tooltipCanvas.gameObject.SetActive( visible );
    }
}

Note however, that this can cause some problems when the inspectable object doesn’t have a “Uniform” (1,1,1) scale, because the TooltipCanvas will deform.

Instead you can try the following (Has 2 classes, Inspectable and ToolTipHandler )

Package:

Notice that the tooltip is not deformed for either of the 3 cubes you can look at.
(Preview image below)

The code for the scaleproof variant:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Inspectable : MonoBehaviour
{
    public Transform m_tooltTipShowTransform;
    private Transform m_transform;
    private CharacterController m_player;
    private Transform m_currentTooltip;

    void Start()
    {
        m_player = FindObjectOfType<CharacterController>(); // Note that this object is not the player.
        m_transform = transform;
    }

    void Update()
    {
        if ( m_currentTooltip != null )
        {
            // Since a canvas' forward is turned away from the camera by default, we'll make the canvas look in the opposite direction.
            Vector3 inverseDirection = m_currentTooltip.position - m_player.transform.position;
            m_currentTooltip.rotation = Quaternion.LookRotation( inverseDirection );
        }
    }

    void OnMouseEnter()
    {
        _setTooltip( true );
    }

    void OnMouseExit()
    {
        _setTooltip( false );
    }

    private void _setTooltip( bool visible )
    {
        if( visible )
        {
            m_currentTooltip = ToolTipHandler.Instance.GetTooltip( m_tooltTipShowTransform.position, _getTextToDisplay() ).transform;
        }
        else if (m_currentTooltip != null)
        {
            Destroy( m_currentTooltip.gameObject );
        }
    }

    private string _getTextToDisplay()
    {
        return string.Format( "Hi, my name is {0}", this.name );
    }
}

Tooltip Pool-like class:

using UnityEngine;
using UnityEngine.UI; 
using System.Collections;

public class ToolTipHandler : MonoBehaviour {

    public static ToolTipHandler Instance;
    void Awake() { Instance = this; }

    public GameObject m_tooltipPrefab;

    public GameObject GetTooltip( Vector3 position, string displayText )
    {
        GameObject newTooltip = (GameObject) Instantiate( m_tooltipPrefab, position, Quaternion.identity );
        newTooltip.GetComponentInChildren<Text>().text = displayText;
        return newTooltip;
    }
}

To improve this setup:

  1. Instead of using OnMouseEnter and OnMouseExit (if those don’t work out for you), use Physics.Raycast

  2. Instead of creating an destroying the tooltip everytime, you could apply the Instance Pool Pattern, to improve performance on larger scales.

I hope this answer helps you out! Best of luck in school and with that deadline, you can do it :slight_smile:
If you need anything else, let me know.
Also, if this helped, please accept this answer, it’d be much appreciated!

Cheers,

ThePersister

Thank you so much! You added way more info than I needed, but thats okay. The script works great! I accepted the answer and gave you a point. I'll definitely be able to finish my project now. :D Funderful

Okay, so I got the new version of Unity (5.4.1), and I started seeing problems. As in, the way I was attaching the script to my gameObjects was no longer working and was generating lots of errors. If you can suggest any method of using these scripts on gameObjects, that would be great. In case it matters, I'm using humanoids with animations, along with other irregular objects. Thanks! Funderful

that also crossed my mind but it didn't work :( thanks for trying though!

It isn't five frames. It's a lightening fast short while loop executing in this one frame. Watch make a while loop inside of Update() depending on some property that only increments between frames like Time.time. CTRL-ALT-DLT