Displaying UI with OnMouseOver

Sharing is caring:

Using Mouse Over to Control the Display of UI Elements In-Game

In this Unity 4.6 tutorial I’ll show you how you can use the OnMouseOver function in C# to display a UI element. In this case we’ll be using a World Space canvas to display our UI elements as a 3d object. What this means is that we can place this UI as a child object of a game object in our environment and have it display as if it were an actual game object.

We’ll use a mouse over effect to detect if we want to display this UI element. This effect is common in games where you’d want to display specific info about an object such character names, objects of interest, pickups, etc.

I’m keeping it simple by just displaying a typical name for our game object, in this case a television. We’ll use a String variable to change the name of the UI Text to something that we want. This will make it much easier to change what the text is displaying without having to jump back into the script to make changes.

This also makes it more of a general script for displaying info which can be used on multiple objects. Using Color.Lerp we’ll fade between two colors, our starting color and our target color. This will create the fade effect by transitioning between a Color.clear and Color.white.

Find out more specifics by watching the video above. You’ll find the script used below.

 

DisplayInfo.CS (apply this to a game object with a collider)

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

public class displayUI : MonoBehaviour {

	public string myString;
	public Text myText;
	public float fadeTime;
	public bool displayInfo;

	// Use this for initialization
	void Start () {
	
		myText = GameObject.Find ("Text").GetComponent<Text> ();
		myText.color = Color.clear;
		//Screen.showCursor = false;
		//Screen.lockCursor = true;
	}
	
	// Update is called once per frame
	void Update () 
	{

		FadeText ();

		/*if (Input.GetKeyDown (KeyCode.Escape)) 
		
		        {
						Screen.lockCursor = false;
						
				}
				*/

	
	}

	void OnMouseOver()
	{
		displayInfo = true;

	}



	void OnMouseExit()

	{
		displayInfo = false;

	}


	void FadeText ()

	{


		if(displayInfo)
		{

			myText.text = myString;
			myText.color = Color.Lerp (myText.color, Color.white, fadeTime * Time.deltaTime);
		}
	
		else
		{
		
			myText.color = Color.Lerp (myText.color, Color.clear, fadeTime * Time.deltaTime);
		}
		



		}



}

Jonathan Gonzalez

I love all things in game development and want to contribute by teaching others how to create games. I'm always looking to help others create awesome digital worlds. I've been a hardcore gamer since I was a kid and now it's my turn to create awesome digital experiences.

More Posts - Website

Follow Me:
TwitterYouTube

Comments

  1. Hey Jonathan, thanks for this! One question:
    in FadeText, if displayInfo is False, isn’t it inefficient to keep calling:

    myText.color = Color.Lerp (myText.color, Color.clear, fadeTime * Time.deltaTime);

    I am not familiar with the Color class’s Lerp method. If it jumps out if it detects whether the myText.color == Color.clear then maybe my concern is moot.

    🙂

    • The second line checks to see if we’re hovering, if we’re not (displayInfo is false) then we lerp back to clear, which will make it “invisible”. If you remove that section or that line it will stay visible at all times.

  2. I am trying to add this script to a UI button, but it seems that OnMouseEnter is never being called. Do you know how I can do this?

    • You might be too far from the UI to activate the onMouseEnter. You have to be fairly close for it to work. If that’s not the case, then I’d add in a Debug.Log into the function to see if it’s being called at all, or if it’s an issue with the Color.Lerp.

  3. hi man i want to use a third person controller for this

    • It’s the same concept although it will require you to get fairly close to the object. You could also use a trigger near the object instead so that the text appears when they are within the trigger near the object.

  4. hi jonathan it is working one fine for one obeject.what if i want to display more than one object?i mean in a scene suppose say there are 5 objects.for each object do i have to add the same script and text object as child object…how to display object’s name OnMouseOver () for each object?
    and one more doubt is how can i create an object as a child object at run time .what i mean is here in this video you are creating UI Text as child object for TV.i want to create this UI text as child object for TV object at runtime and display the object’s name in the center of the TV Screen.and what does fadetime indicate?

    • You can use the UI element to display the name of the object or tag as long as you apply the script to those objects. You can use one canvas that uses ScreenSpace Overlay versus using “World Space”. Fadetime is just a float value that determines how quickly the text will fade, it’s a necessary value to use when using “Lerp” (linear interpolation).

      • Have you fixed this problem Sridevi? Also have this problem

        • If you want to apply this to multiple objects, just apply this script to every object that has a world space canvas on it. I would recommend creating multiple canvases. Each object should have a world space canvas and a text element as a child object of the object.

          Apply this script to the canvas on each object and change the ” myText = GameObject.Find (“Text”).GetComponent ();” so that it reads “myText = myText.GetComponent();” so that it gets the Text component on that object. Assign that text component to the script, and ensure you do this for every object that has the script. Hope that makes sense. Every object should have it’s own canvas and text element, as well as a copy of this script attached to it.

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

    public class displayUI : MonoBehaviour {
    public string myString;
    public Text myText , myText1 ;
    public float fadeTime;
    public bool displayInfo;
    private GameObject cube , sphere;

    // Use this for initialization
    void Start () {
    myText = GameObject.Find (“Text”).GetComponent ();
    myText.color = Color.clear;
    myText1 = GameObject.Find (“Text1”).GetComponent ();
    myText1.color = Color.clear;
    //Screen.showCursor = false;
    //Screen.lockCursor = true;
    cube = GameObject.Find(“Cube”);
    sphere = GameObject.Find(“Sphere”);

    }

    // Update is called once per frame
    void Update () {
    FadeText ();
    /*if (Input.GetKeyDown (KeyCode.Escape))

    {
    Screen.lockCursor = false;

    }
    */

    }
    void OnMouseOver()
    {
    displayInfo = true;

    }

    void OnMouseExit()

    {
    displayInfo = false;

    }
    void FadeText ()

    {

    if(displayInfo)
    {

    myText.text = cube.name;
    myText.color = Color.Lerp (myText.color, Color.white, fadeTime * Time.deltaTime);
    myText1.text = sphere.name;
    myText1.color = Color.Lerp (myText1.color, Color.white, fadeTime * Time.deltaTime);

    }

    else
    {

    myText.color = Color.Lerp (myText.color, Color.clear, fadeTime * Time.deltaTime);
    myText1.color = Color.Lerp (myText1.color, Color.clear, fadeTime * Time.deltaTime);

    }

    }
    }
    here the issue i am facing is when i place the mouse on cube , the cube name is getting displayed on the top of cube object.In addition the sphere name also is getting displayed on the top of sphere object., which actually shouldn’t.how to restrict this.when i place the mouse on one object only that object’s name should be displayed , rest of the object’s names shouldn’t be displayed.

    • It’s doing that because you added “cube.name” and “sphere.name” in the script. You’re telling it to display all this info for the same objects.

      You need to just use one and it shouldn’t be “cube.name” but rather “gameObject.transform.name;”

      • ok .i will make a note of gameObject.tranform.name.then do i have to write seperately csharp for each object which contains same lines of code but with corresponding object name to display…..is this correct?i mean only the statement myText.text = cube.tranform.name for cube object script and myText1.text = sphere.tranform.name; for sphere object script.rest of the lines are same for both the objects …..

  6. My code is exactly the same as yours. However, my text only shows in Scene, but in Game mode, the text disappears and when the mouse hovers, nothing happens. What do you think I am doing wrong?

    • OnMouseOver requires you to be relatively close to the object so this can be hit and miss. I would rather do something like a Raycast or a trigger instead as it’s a far more accurate and dependable way to get this same thing done. I mostly did this tutorial as someone wanted to know how to use OnMouseOver specifically.

  7. Hi @Jonathan thanks for the tut, I just have doubt, since I’m working on a second camera minimap I’m not using UI text, I’m using 3d TextMesh instead and I’m having troubles to adapt this script to TextMesh.

  8. So I came here from CGCookie to check how you use Lerp in your other examples. Looking at this, it makes much more sense to me now how that other example was meant to work.

    myText.color = Color.Lerp (myText.color, Color.white, fadeTime * Time.deltaTime);

    ^ This is a cool way to “abuse” Lerp! Will keep that in mind for later. It’s essentially the same trick explained here but with Lerp instead of the Math:
    https://youtu.be/Fy0aCDmgnxg?t=233

    Is the Time.deltaTime in here to make it framerate-independent?

    • The other example in the CGCookie lesson was going to work similarly but it didn’t seem to work as expected so I just left it as is since it still switched from white to red. I’ve used lerp and crossfading type of effects pretty often with UI so that’s my preferred method of switching between different colors and/or alpha values via script.

  9. guecybercutte@gmail.com says:

    how to change onmouseover with onmousedown without fadetime ?
    just click at mouse, then show text

    that script awesome

  10. John Kenneth Jugo says:

    Hi Jonathan When im adding my script in object there’s a problem- Failed to query D3D11 context for ID3DUserDefinedAnnotayion interface (hr = 0x80004002)? Please help 🙁 For my project. Thanks!

    • Sounds like something is having issues with DirectX 11 in your project. If you’re using a Mac and something in your project is utilizing DX11 (possible a shader or camera effect) then you would have that issue. If you’re using Windows, then something may be causing issues within your project in general but it’s relating to DirectX.

  11. do u have a script that you can see the text on the UI from all sides like if u were using a sphere and came up to it from all 360 avalibility I need it for a space game there will be severial spheres in the scene all will need this script

    • I would recommend using a raycast that detects when you hit a sphere. Then when you hit a sphere have the text appear on screen, or if you wanted it to be world space you could have it pop up at the point in which the raycast hits the sphere. Using “LookAt” you could have the text face the camera whenever it is visible.

  12. sreedevi says:

    Hi
    JONATHAN GONZALEZ

    Thanks for the tutorial

    My code is exactly the same as yours. However, my text only shows in Scene, but in Game mode, the text disappears and when the mouse hovers, nothing happens. What do you think I am doing wrong?

    • The text should fade in when hovering over it and fade out when not. If it’s just disappearing I would make sure your fading lines are not reversed. Also the text shouldn’t appear unless you’re hovering, so if it appears without the hover then I would say you do indeed have something reversed.

      • sreedevi says:

        Thanks for the reply..

        Its not at all displaying even i hover on object multiple times..

        • sreedevi says:

          But i clearly see by DisplayInfo bool variable is changing when i hover and unhover on object

          • I would check the text element component when playing the game. Chances are the alpha value is not updating properly. See if the alpha is changing at all when hovering or if it’s stuttering. Also make sure the text isn’t moving or appearing offscreen. Does the effect appear in the scene view while playing?

  13. sreedevi says:

    Sorry Jonathan Gonzalez i am not able to see the text.. but i am sure i placed the text object in the scene view only..

    • I mean you have the text in the hierarchy, click on it and see what the text component is doing in the inspector as your playing the game. That will give you a better indication of what the text is doing. If it’s not visible in the scene or game view at least the text component itself will give you a better idea of what it’s doing.

  14. Thank you for your tutorial…. its working for me perfect but i cant use it in two objects ……(i.e : i have two game object in scene ex door 1 and door 2 in one door name popup perfectly for another door its not poping up)

    • You need to remove the “GameObject.Find” otherwise it’s just going to find the first Text component it sees in the hierarchy and use that. Remove it and manually assign the text component. It should read something like “myText = myText.GetComponent();”

  15. Hey Jonathan, can you use this for a 2d game by any chance?

  16. Rui Fernandes says:

    Hi! I’m fairly new to coding but your script is pretty self-explanatory! Thanks for that! But i actually have a question, I’ve tried the script for Text and it works perfectly, but i kinda wanted to make the same interaction, but with a couple of RawImages, just a popup Gui but instead of Text i need Rawimages, any way you could explain how to do that please?

    • Yes you can use this for raw images. The fading effect is not specific to Text, it’s also applicable to images including raw images. To change it within the script replace the Text myText with your raw image instead. Then just change it within the fade section. Something like this:

      rawImg.color = Color.Lerp (myText.color, Color.white, fadeTime * Time.deltaTime);

      Everything else should be the same. You might also want to remove this:

      myText = GameObject.Find (“Text”).GetComponent ();

      Then you can just manually assign this and reuse it for any other popups you want.

Speak Your Mind

*