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. Dismiss Notice

Question Texture UXML attribute in C# template?

Discussion in 'UI Toolkit' started by ProtagonistKun, Feb 9, 2022.

  1. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    I have found that I can use the different UXML attributes to generate a field on the C# control. However there does not appear to be one hat I can use for a Texture2D field (or any other custom "complex" field I want to create) Is this currently still a limitation of UITK or am I missing something?

    The type of declaration I am referencing is as follows:
    Code (CSharp):
    1. private UxmlIntAttributeDescription Progress =
    2. new () { name = "fill-percentage", defaultValue = 0 };
    However, how do I create a similar field for a Texture2D?
     
  2. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    You could load the image through a custom style property, like the Image element does. Look at how it uses "--unity-image" to load the image in the Cs Reference. Then, in UXML, instead of using a custom attribute, you use the style attribute like this:
    style="--unity-image: url(\"myImage.png\")"
    . It's not very pretty but I think it should work.

    EDIT
    The example I gave is for an Image element; you'd probably want to name your custom property differently.
     
    Last edited: Feb 10, 2022
    ProtagonistKun likes this.
  3. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    I'm going to need to spend some (probably a lot) of time to figure that out. Seems quite far from what I'm used to doing. Thank you for the example, now I just need to decipher it for my usecase!
     
  4. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    No problem, if you get stuck feel free to hit me up; I might be able to help. Good luck.
     
  5. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    If you happen to know how to achieve this, I more than welcome your input as I am punching way above my weight on this issue.
     
  6. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Okay, the idea is that you could take advantage of CustomStyleProperty and CustomStyleResolvedEvent, as even if UXML attributes that refer to resources aren't supported yet, USS properties are more than able to reference images.

    The code in the element is relatively simple. It's something like this:
    Code (CSharp):
    1. class MyElement : VisualElement
    2. {
    3.     // This defines a custom uss property. You can use any name you want for it, but it must start with two dashes.
    4.     static CustomStyleProperty<Texture2D> textureProperty = new CustomStyleProperty<Texture2D>("--texture");
    5.  
    6.     // We need to listen for the CustomStyleResolvedEvent. We can register for it in the constructor.
    7.     public MyElement()
    8.     {
    9.         RegisterCallback<CustomStyleResolvedEvent>(OnCustomStyleResolved);
    10.     }
    11.  
    12.     // The CustomStyleResolvedEvent is used like this:
    13.     private void OnCustomStyleResolved(CustomStyleResolvedEvent evt)
    14.     {
    15.         if (evt.customStyle.TryGetValue(textureProperty, out var textureValue))
    16.         {
    17.             // The texture you want is in the textureValue variable. Do what you want with it.
    18.         }
    19.     }
    20. }
    If you're using UXML you can set the texture by using an inline style, something like
    <MyElement style="--texture: url(\"someTexture.png\")">
    The back slashes in the url are to escape the quotes; the url needs to be provided with quotes, but, since there are already quotes surrounding the whole inline style, they need to be escaped. UIBuilder doesn't support custom properties in inline styles, so this would only work for manually written/edited UXML.

    Image stuff in UIBuilder seems to be currently done with background images. Those can be set in inline styles, so depending on your needs, that could be another way to do it. Without knowing more about your use case, it's hard to know how it would work for you.
     
  7. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    The exact use-case I have is very similar to IMGUI. In that system we have buttons with all kinds of properties like highlighted, pressed, selected and disabled states (for both sprite swapping and color change)

    I wanted to emulate this system as it is quite convenient to have these states since buttons in UITK dont have any kind of states like they used to. I want to avoid having to resort to using an IMGUI container since I predict that will become legacy at some point and I do enjoy working with the new system (tho it does have its quirks/limits that are quite annoying)

    I am trying to make these as C# controls because it enforces the consistency I need from my UI designer who has limited(front-end) coding experience
     
  8. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    How does your designer use this controls? Do they use the UI builder? Are they writing c#? Are they writing UXML?

    EDIT
    Also, there're are many pseudo classes in USS that cover the different states you mentioned in a button. You may want to take a look at this: https://docs.unity3d.com/Manual/UIE-USS-Selectors-Pseudo-Classes.html
     
    Last edited: Feb 10, 2022
  9. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    The intended way to use it is similar to what he is used to with IMGUI, as in dragging images into the fields and setting up the controls. He is using the UI builder to an extent but has little knowledge of USS as a whole (as well as C#) for which I am mostly taking care of it myself. His job mostly extends to designing the UI with PS or AI and drafting it up in unity.

    We may need to adjust our workflow, or he might need to learn USS because of this limitation if Im honest.

    EDIT: AFter looking into the psuedo classes, that does seem liek the way to go rather than setting it up in the template. It would allow us a greater degree of dynamics on the UI creation which will be quite nice.
     
    Last edited: Feb 10, 2022
  10. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    :) Yeah, after I asked about your designer I thought "Wait a minute, button states have never been that troublesome for me in UITK".

    It still sounds like a good idea that a designer learns USS; it helps even when using UIBuilder, because that's what the builder is creating after all. USS is practically CSS with limits; you only get flexbox, a couple of properties are different, and lots of properties aren't available, but it's basically the same. There's a page in the Manual that mentions all the USS properties available. Even if your designer doesn't know CSS, it could be nice that what one learns about USS is transferable to web development.

    As a final tip, I frequently find myself checking the Mozilla CSS manuals when I need to know how to handle UITK styling. Their explanations are good and thorough, and they have interactive examples. I find it specially useful when trying to position things with flex layouts: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout
     
  11. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    Im currently looking at creating C# controls along with UXML templates for him to use and USS classes.that may prove a better approach.

    I did notice that nesting UXML templates can be finicky in earlier versions, references getting lost or something. I dont specifically remember what it was but I think I vaguely remember something about file paths being referenced instead of the asset ID

    EDIT: Instead of forcing inline styling, im going to make CSS style elements similar to bootstrap :)
     
    Last edited: Feb 10, 2022
    oscarAbraham likes this.