Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Please add methods to create UI controls programmatically

Discussion in 'UGUI & TextMesh Pro' started by eelstork, Dec 23, 2014.

  1. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    """You might wonder why we don’t have a API methods to create the various types of controls, including visuals and everything. The reason is that there are an infinite number of way e.g. a button could be setup. Does it use an image, text, or both? Maybe even multiple images? What is the text font, color, font size, and alignment? What sprite or sprites should the image use? By letting you make a prefab and instantiate that, you can set it up exactly the way you want. And if you later want to change the look and feel of your UI you can just change the prefab and then it will be reflected in your UI, including the dynamically created UI."""

    You might wonder why we want API methods to create the various types of controls. The reason is that we don't want to be coerced into making a prefab and instantiate that. And even though we want to set it up exactly the way we want, we can do all that in scripting anyways.

    Prefabs aren't the answer to everything.

    EDIT:

    I understand that it is possible to create UI elements programmatically. However the recommended approach doesn't work without prefabs. In some cases using prefabs results in a needlessly complex workflow.
    Admittedly there is a component oriented, DIY approach suggested by others. It appears to me that this approach is somewhat low level and results in code that isn't concise.

    In short I think factory methods are needed here to help the following people:
    - People who write sample code involving (but not focusing on) UI.
    - People who provide assets for distribution in the unity asset store. Assets that include UI elements but do not focus on the UI itself.
    - People who need to create UI elements dynamically.
    - People who like doing things in code, and would be happy to go with standard UI elements (if only temporarily, pending later customisation).

    For more detailed explanations about why I think this API is needed, please take the time to read the thread. If your opinion is redundant remember that there is a "like" button. Thanks.

     
    Last edited: Dec 25, 2014
    QFord, rakkarage and rahuxx like this.
  2. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537
    that will be great to have such feature to code UI from scripting also. Making WYSWYG with code support will be excellent work around for new UI system.
     
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    This reason is not good enough.
    You might wonder why we want to stick a pipe into our lungs and squeeze oxygen into it every few seconds. The reason is that we don't want to be coerced into breathing through our noses or mouths.
    I'm not against you on this, but you need a stronger case.
     
  4. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    I find your analogy rather obscure (I don't really get it, sorry); and creepy also.

    There's really no clear justification for NOT providing these APIs. It's just surprising that they aren't available, in that there's been UI toolkits around since the 1990s and before, surely they provide constructors for their widgets and let you instantiate (and customise) them programmatically. This is orthogonal to whether a wysiwyg editor is provided or not.

    It looks to me that it's entirely possible to build widgets programmatically as it is, but a lot of boiler plate and no direct equivalent to what is provided by the editor.

    Anyway. For want of a reason, my problem is that prefabs can use components, but script instances (as far as I know) cannot (at least not easily...) use prefabs until said prefabs are assigned manually (or maybe via a kind of wizard...). So, for example I wanted to have a little component that creates a button and makes it "float" above a 3D object. Having to link prefabs to all instances of said component is tedious. There are (ugly) workarounds of course.

    Not providing these APIs is as disingenuous as the lack of namespaces in early versions of Unity. When somebody reinvent wheels they should make round wheels, not say "let's innovate with a new cubic wheel design".
     
    Umai likes this.
  5. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    Additionally, there is another reason, which I think is similar to why there are APIs for building simple primitives (Cube, Sphere, Cylinder, ...). Being able to create stuff programmatically makes it easy to write self contained (one file) scripts, for example when creating tutorials.
     
  6. Zerot

    Zerot

    Joined:
    Jul 13, 2011
    Posts:
    135
    Because of how the UI system is setup, it hardly makes any sense to make a specific API for UI elements. The UI elements are just normal components that live on a GameObject. It would take only a few minutes to write a few functions that replicate the items from the create menu. Especially because the ui source is open source and you can just copy paste the functions and alter them a bit to remove the editor specific code.

    e.g. This contains all the create menu options for the ui. You can quickly copy and change this so it will work from the runtime.
     
  7. DanSuperGP

    DanSuperGP

    Joined:
    Apr 7, 2013
    Posts:
    408
    What's wrong with

    Gameobject buttonGO = new Gameobject();
    RectTransform buttonRectTransform = buttonGO.AddComponent<RectTransform>();
    buttonRectTransform.SetParent(theParent);
    Button buttonButton = buttonGO.AddComponent<Button>();

    etc etc... ?
     
    Kiwasi and cl9-2 like this.
  8. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    This is what I use to programmatically add UI elements. I also set up event triggers programmatically as well. For UI animations, I use LeanTween, not Mecanim (which the Unity examples use).
     
  9. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,332
    Agreed. Even if there were an API to make the automatic buttons, you'd still need that same amount of code to retrieve the RectTransforms, Button, Image, and Text components just so you can customize it to your liking. Unless you're suggesting they provide a method with a thousand parameters I don't see what this achieves that can't be done with just a few lines. You can even write a simple helper class/method to do this for you to your liking.

    If you want to complain about lack of API then there are way better areas to moan about *cough* shuriken.
     
    BMayne likes this.
  10. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    What's wrong is that you can't be kicked to see this to the end, showing that there is too much boiler plate. Opening a window in Windows is (used to be?) about 30 lines of code while doing the same in Java was 3-4 lines (or just one).

    Lack of information hiding/encapsulation. Sometimes you just want a button, at this moment you don't want to worry too much about the nuts and bolts of a button, because you are (hopefully) focusing on something else.
    Just because the parts are good doesn't mean you always want to be shopping for parts. Otherwise the widgets wouldn't even exist in the editor.

    Thank you for providing the link. I wouldn't know where to look; I have no interest in the fact that the API is open source; I hope that this is understandable. One reason I migrated to Unity is so that I no longer need to bother with engine source.
    If you really believe that it would take a few minutes to do this don't you think it would be good that the Unity staff bother with it rather than a few hundreds of developers re-creating over and over again the thin layer of usability that these APIs are missing?

    About the number of parameters needed in the constructor I think it's an argument against constructors (or factory methods) in general. Provide a constructor that will cover 80% of use cases, and let users customise the widget programmatically (or substitute a prefab).

    I think it's normal / excusable that the new UI is a bit rough on the edges; It's in beta so, it's a good time to identify areas that could do with improvements.

    Quoting Superpig: "So, when you find something that [...] would be perfect if they'd just add this one checkbox or whatever, the dev team want to hear from you."
    (his emphasis)

    I'm happy for you guys that you know the kung-fu and have time to read the source. Please don't mind me for wanting a little more usability.
     
  11. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    No, and no, and no. It won't be the same amount of code. And customising (whether programmatically or otherwise) is always easier than setting things up from scratch.
    But most importantly, what I (and maybe others...) need is an API that can be used to create simple widgets - leaving further customisation to later, never, or for other people to bother with, such as when you create a code asset for others to use.

    Yes, I can write the API myself.

    Shuriken isn't in beta anymore. I get enough flak as it is when asking for improved usability on new APIs why should I go and dig up graves in the middle of the night.
     
  12. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,332
    The only API addition I could agree with is some way to create a new parented GameObject that has a RectTransform, because this pattern seems universal to every UI element. If that was implemented then your hypothetical 'make a button' method wouldn't be required, because the code required to set buttons up would probably be identical.
     
    DanSuperGP likes this.
  13. DanSuperGP

    DanSuperGP

    Joined:
    Apr 7, 2013
    Posts:
    408
    Yes, I agree, that would be extremely helpful.
     
  14. BMayne

    BMayne

    Joined:
    Aug 4, 2014
    Posts:
    186
    Hey there,

    I don't think there is really any need for this. As people have pointed out already there is ways to make ui elements in code or you can just use a prefab. If you run into an issue where you have to do something over and over again just make a helper function. There is just so much to take into account that having an API. This could just lead to more confusion.

    If you do need these functions, extend the API and add them to your own projects ( I have done this a lot). Everyone has preferences and they are not going to cater to each project.

    Regards,
     
    DanSuperGP likes this.
  15. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    So called "ways to make UI elements in code" consists in poorly documented, low level implementation constructs that you'd normally use to design ad-hoc UI elements. Surely this can be improved?

    Using a prefab is fine but when you need to generate UI elements dynamically you don't "just use a prefab". Minimally you have to create the prefab, declare a field to link the prefab, and now all instances of your component have a field that needs to be populated. Manually? But what if you instantiate this component programmatically? Well, if so you need a kind of manager (referenced by the code which needs to populate the field...) which declares a field to link the prefab... This is what you refer to as "just use a prefab"?

    Providing factory methods would give us an intuitive counterpart to functionality provided in the editor.

    What's gonna happen here is that every asset provider building something that needs to generate UI elements dynamically will have to extend the API and somehow roll their own, puny "UIManager", where standardised components would have done a very good job.

    You can call it my preference if you want but as I already stated (if you even read before commenting) all major UI toolkits have classes for their UI widgets (not just factory methods) and you can build instances of these classes programmatically. I'm not asking for something non-standard. Instead I'm asking for something that looks non standard to be rectified. I don't really mind how many people comment here, it's still something non-standard. If there's a good reason to do things this way, it's neither in the manual, nor in the thread.
     
  16. eelstork

    eelstork

    Joined:
    Jun 15, 2014
    Posts:
    221
    Okay I probably won't be reading this thread anymore. Thanks to everybody who commented.
     
  17. tyoc213

    tyoc213

    Joined:
    Nov 14, 2011
    Posts:
    168
    Im migrating an app from the old UI... that means all is code no only: design and connect.

    So... like I see there is no direct way to create and attach things to a certain canvas or the only one canvas in the scene?


    By the way... now I remember scala that you can create at runtime mixes of different classes for example:


    Code (CSharp):
    1.  
    2. new button with interfaceSome1, color4, userProtected
    3.  

    So how I go about this one?

    Code (CSharp):
    1.  
    2.  
    3. voidStart () {
    4. canvas = GameObject.FindObjectOfType<Canvas> ();
    5. Buttonb = newButton ();
    6.  }
    7.  
    8.  
    9. // Gives:
    10.  
    11. Assets/MyScreen.cs(10,41): error CS0122: `UnityEngine.UI.Button.Button()' is inaccessible due to its protection level
    12.  
     
  18. DanSuperGP

    DanSuperGP

    Joined:
    Apr 7, 2013
    Posts:
    408
    You can't create anything derived from Monobehavior using the constructor. You need to create a GameObject... then add the button using AddComponent<Button>()

    See my comment above.
     
    tyoc213 likes this.