Frequently Asked UI Questions

(mods/UTech: please feel free to modify and extend this post)

Can I release games made with the beta?

You can, but Unity recommend that you don’t rely on it - it’s a beta, which means there are bugs. But if it works well enough for what you’re doing then go right ahead. Note that beta currently does not include full Web Player support, as the 4.6 Web Player is in beta as well. Only other developers using the 4.6 beta will be able to play games targeting the Web Player, and this will display a red note.

How many more beta builds will there be before 4.6 is officially ‘finished?’

Nobody knows (no, really). It all depends on whether people keep finding bugs and what those bugs are. The UI team will continue releasing beta builds as needed to keep putting the latest changes into your hands for testing, and when the remaining issues are either too big for 4.6 or too small to worry about, they’ll call it done.

Which 4.5 changes are in the 4.6 beta and when do 4.5 changes get applied to 4.6?

You can see which 4.5 changes are in each beta on the release notes page. 4.6 will only pull changes from 4.5 when there is a 4.5.X release (e.g. 4.5.4), not patch releases (e.g. 4.5.3p3).

How do I stop clicks/touches on the UI from ‘going through it’ and being clicks in my game world?

Use EventSystem.current.IsPointerOverGameObject() to check whether the mouse is over a GUI element before you process your game world clicks. See this post for an example. Also, on mobile, you may need to specify which finger you’re asking about - see this thread for details.

How do I make a button have events for things other than OnClick?

Attach another component to the button that has those events. You could use the built-in EventTrigger component, or you can make your own component that implements the IPointerEnter and IPointerExit methods for a lighter-weight approach.

How do I use ColorTint with more than one Graphic?

Use the Animation transition mode to animate all your color changes, instead of using ColorTint. (Alternatively, you could derive your own component and override DoStateTransition and then implement whatever you need in there).

How do I make UI that works with the Oculus Rift?

Use ‘World Space’ mode on the Canvas so that the UI can be seen by both left-eye and right-eye cameras. You may want to make the Canvas a child of your OVRController object so that it moves with the player. For ‘look-to-point’ style input, just set the Canvas’s Event Camera to one of the two eye cameras - it’s slightly inaccurate but good enough in most cases. (If it isn’t, you’ll need to write a custom input module). See also this article.

How do I make my UI scale up and down to different screen resolutions? I tried using anchors but things become tiny at large screen sizes.

The anchor system can ensure that the ‘frames’ of graphics and text change appropriately as the screen size changes, but it doesn’t do anything about the content in those frames - it doesn’t adjust things like your font sizes, which is why they look tiny at higher resolutions.

Instead you want to use the Scale property to change the size; the simplest approach is to attach a ReferenceResolution component to your base Canvas, which will automatically scale the entire canvas up or down to fit the screen resolution. Note that you will probably still want to use the anchor system for dealing with different aspect ratios.

Please read the documentation HOWTO on this.

How do I make UI elements have non-rectangular hitboxes?

Add a component that implements ICanvasRaycastFilter. In your implementation of IsRaycastLocationValid, reject all points that are ‘outside’ your custom hitbox shape. It’s up to you how you want to do that, but for example for a circular hitbox you could measure the distance between the point and your object’s center and reject the point if that distance is greater than your circle’s radius. Or perhaps you could look up the alpha value of the pixel the hit is on, as per this script by senritsu.

How do I make UI elements be ignored by raycasting?

Either implement ICanvasRaycastFilter with an IsRaycastLocationValid method that always returns false, or use a CanvasGroup component with ‘Blocks Raycasts’ turned off.

How do I attach callbacks to events from code?

At runtime, use the addListener method to attach your callback - e.g. myButton.onClick.AddListener(MyCallback).

In the editor, use UnityEditor.Events.UnityEventTools.AddPersistentListener(myButton.onClick, MyCallback). This creates a ‘persistent’ listener, which can be loaded and saved as normal.

Be aware that the callback function you use for a persistent listener must be a member of a MonoBehaviour, ScriptableObject, or other UnityEngine.Object-derived class - this is required for serialization to work. If you wouldn’t be able to set up your listener by hand in the Inspector, you won’t be able to set it up via AddPersistentListener either.

How do I create a UI element from a prefab and add to to a Canvas?
Use transform.SetParent (parent, false). Do not use transform.parent = parent

9 Likes

How do I send custom events?
Here is a gist detailing how to send custom events.

How do I write a custom Joystick?
If you download the latest Sample Assets from the asset store for 4.6 you will see that there is an updated Joystick example project there :slight_smile:

3 Likes

Can I pause my game using Time.timeScale = 0 and still run animated UI Elements?
Yes! :slight_smile: Set the “Update Mode” to “Unscaled Time”

Sample Pause Script in C# and UnityScript

Sample Pause Script [C#]

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class PauseManager : MonoBehaviour {
  
    Canvas canvas;
  
    void Start()
    {
        canvas = GetComponent<Canvas>();
        canvas.enabled = false;
    }
  
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Pause();
        }
    }
  
    public void Pause()
    {
        canvas.enabled = !canvas.enabled;
        Time.timeScale = Time.timeScale == 0 ? 1 : 0;
    }
  
    public void Quit()
    {
        #if UNITY_EDITOR
        EditorApplication.isPlaying = false;
        #else
        Application.Quit();
        #endif
    }
}

Sample Pause Script [US/JS]

#pragma strict
import UnityEngine.UI;

private var canvas : Canvas;

function Start()
{
    canvas = GetComponent.<Canvas>();
    canvas.enabled = false;
}

function Update()
{
    if (Input.GetKeyDown(KeyCode.Escape))
    {
        Pause();
    }
}

public function Pause()
{
    canvas.enabled = !canvas.enabled;
    Time.timeScale = Time.timeScale == 0 ? 1 : 0;
}

public function Quit()
{
    #if UNITY_EDITOR
    EditorApplication.isPlaying = false;
    #else
    Application.Quit();
    #endif
}
5 Likes

Have a look: Unity - Manual: Making UI elements fit the size of their content

1 Like

I have a question regarding the text object that is attached to a canvas.

I have a text object that displays the player’s current time that stands by itself within the canvas, but is not attached to a button. In the script I have attached to the text object, I am trying to make the text component equal to the current time string, but there is no text component in the text object, so I can’t assign a value to the text. For example, with the GUI before 4.6, you could do: guiText.text = so and so, but I don’t know what identifier I should use to get the text component from within the script since there is no guiText component attached to the text object.

What should I use as an identifier to call the text component attached to a text object?

The answer is probably right in front of me. :stuck_out_tongue:

Thanks,

- Chris

should be text i think
http://docs.unity3d.com/ScriptReference/UI.Text-text.html

Correct me if I am wrong, The new GUI is Open Source + Every Component like MeshFilter, Transform is just another MonoBehaviour Script written by Awesome people at Unity = 4.3.4 can Get GUI Support If I import all the files in bitbucket and use it for PSM GUI development

No, that stuff is native C++ code.

No, the new UI code depends on engine features in 4.6 that don’t exist in 4.3.

–Eric

1 Like

1877196--120681--0.png1877196--120682--1.png

This is the difference I am talking about. See how with the GUI before 4.6 (right) has a GUIText component while the UI in 4.6 (left) has a Text (Script) component? With the GUIText component, you could simply call the GUIText component with the guiText identifier, but with the new UI, using the same guiText identifier does not work.

I want to know how I can call the text component with the new UI so that I can assign it a string value. For example, if I wanted to do this with the old GUI, I could say

guiText.text = timeStr;

but with the new UI, saying the same thing won’t update the text value with the value of timeStr. I think the new UI doesn’t have a guiText.text component attached to it, so it returns null.

Please help! :face_with_spiral_eyes:

EDIT: uiText.text is an unknown identifier, so it does not work.

You need to use GetComponent. Unity 5 is doing away with the shortcuts such as guiText anyway, so instead of guiText.whatever you would do GetComponent(GUIText).whatever. Same for the Text component. The GUIText component is different from the UI Text component. http://docs.unity3d.com/ScriptReference/UI.Text.html

–Eric

GetComponent<Text>().text = timeStr;
1 Like

This is not working for me:
"The type or namespace ‘Text’ could not be found (are you missing a using directive or an assembly reference?)

GUIText will save and compile but when run gives an error about the script trying to access a component that doesn’t exist. The object is clearly being found and most certainly has a UI.Text component as pictured by Blue Bean Apps.

Import the UnityEngine.UI namespace.

–Eric

1 Like

I got it:
GameObject.Find(“P1Class”).GetComponent<UnityEngine.UI.Text>().text = curClass;

Or just import the namespace, so you don’t have to keep typing UnityEngine.UI in front of all UI components.

–Eric

2 Likes

For 2D games, how do we supply/specify 1x, 2x, 3x etc resolution imagery? This should be a contender for the FAQ!

I can’t believe nobody has asked this yet. what about Localization???

1 Like

I hope my question lands at the good spot:

On case of many small sprites for a complex UI, is it better to create sprite atlases outside Unity and import them into the project, or it is better to import the sprites individually and let the sprite packer to do the atlas creation? In which case will I have less draw-calls? (I use Unity Pro iOS 4.61.) Until now I have used NGUI (and created the atlases with NGUI inside Unity) but I am at the beginning of a totally new mobile game, so maybe it is time to change to uGUI…

Are there any best practice guides for the workflow?

I ended up using a XML 3rd party system for loc support http://forum.unity3d.com/threads/add-multiple-language-support-to-your-unity-projects.206271/

If its an static text what i do is in the texts use the code for the xml and attach a small scritp intro text elements that read and store that code, them in a single update (cant be done at start) i take the code, and update the text with the xml value and i left one public funtion in there in order to be able to update all texts at once later on if the lang setting is changed.

Or just update it directly from a mayor scritp that must change its value, instead of passing the text string directly you call the lang function with the code, and thats returns the string.

It seems that all solutions to this have one thing in common - they are implemented on “receiver” game object. Which I find quite inconvenient - having to change the OnMouseDown() and other methods in every single current and future script attached to non-UI game object.

Is there maybe a more elegant way, like capturing the click on the canvas/panel/other UI element once, and not having to worry about doing it in every other place?