Search Unity

Frequently Asked UI Questions

Discussion in 'UGUI & TextMesh Pro' started by superpig, Aug 25, 2014.

Thread Status:
Not open for further replies.
  1. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    (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
     
    Last edited by a moderator: Oct 13, 2014
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Last edited by a moderator: Sep 15, 2014
    rakkarage, Kujo87 and amadlover like this.
  3. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Can I pause my game using Time.timeScale = 0 and still run animated UI Elements?
    Yes! :) Set the "Update Mode" to "Unscaled Time"



    Sample Pause Script [C#]
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4. #if UNITY_EDITOR
    5. using UnityEditor;
    6. #endif
    7.  
    8. public class PauseManager : MonoBehaviour {
    9.  
    10.     Canvas canvas;
    11.  
    12.     void Start()
    13.     {
    14.         canvas = GetComponent<Canvas>();
    15.         canvas.enabled = false;
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         if (Input.GetKeyDown(KeyCode.Escape))
    21.         {
    22.             Pause();
    23.         }
    24.     }
    25.  
    26.     public void Pause()
    27.     {
    28.         canvas.enabled = !canvas.enabled;
    29.         Time.timeScale = Time.timeScale == 0 ? 1 : 0;
    30.     }
    31.  
    32.     public void Quit()
    33.     {
    34.         #if UNITY_EDITOR
    35.         EditorApplication.isPlaying = false;
    36.         #else
    37.         Application.Quit();
    38.         #endif
    39.     }
    40. }
    Sample Pause Script [US/JS]
    Code (JavaScript):
    1. #pragma strict
    2. import UnityEngine.UI;
    3.  
    4. private var canvas : Canvas;
    5.  
    6. function Start()
    7. {
    8.     canvas = GetComponent.<Canvas>();
    9.     canvas.enabled = false;
    10. }
    11.  
    12. function Update()
    13. {
    14.     if (Input.GetKeyDown(KeyCode.Escape))
    15.     {
    16.         Pause();
    17.     }
    18. }
    19.  
    20. public function Pause()
    21. {
    22.     canvas.enabled = !canvas.enabled;
    23.     Time.timeScale = Time.timeScale == 0 ? 1 : 0;
    24. }
    25.  
    26. public function Quit()
    27. {
    28.     #if UNITY_EDITOR
    29.     EditorApplication.isPlaying = false;
    30.     #else
    31.     Application.Quit();
    32.     #endif
    33. }
     
    Kiori, randomperson42, Cenda and 2 others like this.
  4. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    theiss likes this.
  5. Blue Bean Apps

    Blue Bean Apps

    Joined:
    Aug 10, 2014
    Posts:
    261
    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. :p

    Thanks,

    - Chris
     
    Last edited: Dec 1, 2014
  6. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
  7. psk-psk6

    psk-psk6

    Joined:
    Apr 16, 2014
    Posts:
    14
    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
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    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
     
    shkar-noori likes this.
  9. Blue Bean Apps

    Blue Bean Apps

    Joined:
    Aug 10, 2014
    Posts:
    261
    0.png 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! :confused:

    EDIT: uiText.text is an unknown identifier, so it does not work.
     
    Last edited: Dec 7, 2014
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    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
     
  11. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    Code (CSharp):
    1. GetComponent<Text>().text = timeStr;
     
    shkar-noori likes this.
  12. kingdutka

    kingdutka

    Joined:
    Feb 1, 2011
    Posts:
    129
    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.
     
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Import the UnityEngine.UI namespace.

    --Eric
     
    Refrash likes this.
  14. kingdutka

    kingdutka

    Joined:
    Feb 1, 2011
    Posts:
    129
    I got it:
    GameObject.Find("P1Class").GetComponent<UnityEngine.UI.Text>().text = curClass;
     
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Or just import the namespace, so you don't have to keep typing UnityEngine.UI in front of all UI components.

    --Eric
     
    AM_1 and shkar-noori like this.
  16. Umai

    Umai

    Joined:
    Jun 18, 2013
    Posts:
    74
    For 2D games, how do we supply/specify 1x, 2x, 3x etc resolution imagery? This should be a contender for the FAQ!
     
  17. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
    I can't believe nobody has asked this yet. what about Localization???
     
    shkar-noori likes this.
  18. helioxfilm

    helioxfilm

    Joined:
    Apr 23, 2008
    Posts:
    259
    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?
     
  19. shivansps

    shivansps

    Joined:
    Feb 26, 2014
    Posts:
    60
    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.
     
  20. GTwice

    GTwice

    Joined:
    Nov 30, 2012
    Posts:
    1
    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?
     
  21. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    What you can do is to send the OnMouse* messages yourself. Set Camera.eventMask to 0 to disable the built-in messages, then attach a component which does the raycast - taking IsPointerOverGameObject into account - and uses SendMessage() to send the OnMouse* messages manually.
     
  22. shkar-noori

    shkar-noori

    Joined:
    Jun 10, 2013
    Posts:
    833
    What are the UI team working on currently, except for bug fixing, might it be the new text rendering system?
     
  23. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    How do I deselect item from code?

    E.g. I have few UI items with "Selectable" component enabled. Now I want to deselect all of them so none will be selected. How do I do that?
     
    Malkyne likes this.
  24. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    What is the UGUI equivalent to MonoBehaviour's OnMouseOver where I can do something for as long as the mouse is over an object?
     
  25. EParent

    EParent

    Joined:
    Feb 13, 2015
    Posts:
    36
    Do you have an example for the EventTrigger ?
     
Thread Status:
Not open for further replies.