Search Unity

Question How to get VisualElement's Bounding Box?

Discussion in 'UI Toolkit' started by YinZuoyu, Nov 25, 2020.

  1. YinZuoyu

    YinZuoyu

    Joined:
    Aug 25, 2015
    Posts:
    44
    upload_2020-11-25_15-11-6.png
    I need get this value in runtime.
     
  2. griendeau_unity

    griendeau_unity

    Unity Technologies

    Joined:
    Aug 25, 2020
    Posts:
    248
    Unfortunately the boundingBox property is internal at the moment.

    You can checkout our package locally, then either modify that property accessibility to be public, or grant your code access to all UIElementsModule internals by adding your assembly to the list of [assembly:InternalsVisibleTo("xxxx")] in com.unity.ui/Core/AssemblyInfo.cs.

    Alternatively, if your targeted platform allows it, another option would be to use reflection like this:
    typeof(VisualElement).GetProperty("boundingBox", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(yourElement);
     
    Last edited: Nov 25, 2020
    dsfgddsfgdsgd and YuuHao like this.
  3. YinZuoyu

    YinZuoyu

    Joined:
    Aug 25, 2015
    Posts:
    44
    I try to editor the AssemblyInfo.cs,but the script restored invariably.I think I need get access.But I don't know how to get it.
     
  4. acandael

    acandael

    Joined:
    Apr 7, 2021
    Posts:
    74
    Hello,

    I was also trying to access the boundingBox property. I have a VisualElement that gets populated at runtime, and I'd like to get its height once populated. Besides the boundingBox property, is there another property that I could use? It looks like style.height remains at its original value (?).

    Thanks a lot!
     
  5. griendeau_unity

    griendeau_unity

    Unity Technologies

    Joined:
    Aug 25, 2020
    Posts:
    248
    There are a few other options you can use depending on what your needs are.

    computedStyle.height
    resolvedStyle.height
    layout.height
    worldBound.height
     
    acandael likes this.
  6. VisionEEG

    VisionEEG

    Joined:
    Aug 29, 2018
    Posts:
    28
    The bounding box has the correct pixel values. When using a RenderTexture, it is useful to know exactly the number of pixels to assing UV properly. Why is it so hard to have the correct pixel values of the VisualElements? I'll use reflexivity as proposed in the second post.
     
  7. acandael

    acandael

    Joined:
    Apr 7, 2021
    Posts:
    74

    Back on this topic, I still have issues accessing the values of some properties. That is, I can access them, but they're all returning 0 values..

    Here in UIBuilder I have an element of type IMGUIContainer. I want to get that circle image's center coordinates, and I simply can't get anything else than (0,0) values, no matter what property I access. I tried localBound, worldBound, transform.position, layout.position, style.position, style.position.value, style.top, style.top.value, style.top.value, resolvedStyle.top, resolvedStyle.position. Nothing gives me any useful value.

    I also tried using reflection as mentioned above, still zeros everywhere.

    upload_2021-12-23_10-47-2.png

    If I use UI Toolkit Debugger on that element, I can see this:
    upload_2021-12-23_10-51-37.png

    --> How do I get these values at runtime?
    Is it possible at all?
    If not, is there any other way getting my circle's centre/bounds ?

    Thanks a lot,
    Arnaud
     
  8. Midiphony-panda

    Midiphony-panda

    Joined:
    Feb 10, 2020
    Posts:
    243
    You might try to get those properties too soon, before the layout has been calculated.

    Try getting those properties after a few frames, or registering for the GeometryChangedEvent callback on the target element at start.
     
    acandael likes this.
  9. acandael

    acandael

    Joined:
    Apr 7, 2021
    Posts:
    74
    That was it, thank you so much! :)
     
  10. acandael

    acandael

    Joined:
    Apr 7, 2021
    Posts:
    74
    Hi again,

    I still have one question though. Now I have a problem with the values returned.
    The white circle illustrated below is located at 588px from the top of the screen.
    upload_2021-12-23_13-59-13.png

    This value of 588px can be seen via the debugger, under "top":
    upload_2021-12-23_14-0-38.png

    Ok, so now.. I'm expecting to get that value, but I don't.

    Note that this circle element is within a VisualElement whose top value is 50px. There is no margin, no padding around the circle or around the parent VisualElement.

    Depending on what I look for, I have:
    • if using resolvedStyle.top or localBound, or layout: 543
    • if using worldBound: 593 (so 543 + 50 of the parent)
    So it looks like I'm 5px off, but I can't understand where they come from..

    Any idea?
    Thank you,
    Arnaud.
     
  11. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    Note that GeometryChangedEvent by design *does not mean what it says it means* and instead is called multiple times per layout with different 'magic' meanings. Last time I checked this wasn't in the docs but has been described in many forum threads.

    TLDR: you will generally receive incorrect view of the data the first time it is called. From previous threads the advice from Unity team has been to count how many times it's called in a row, and if the number is 2, then ignore the first one.

    I often see it return an initial value that's incorrect by 5-10%, and then immediately fire a second time (I think in the same frame?) with the correct values. I just re-render the entire UI everytime it comes in, because otherwise you're stuck debugging UIToolkit's private internals trying to get the real data that should have been provided to us via callback or API call. Of course then you have to figure out a way to do your layout without recursively triggering a new GeometryChangedEvent (a real one!), but they have a protection built-in now that if you do that the Editor will throw warnings/errors (it used to crash), so it's pretty easy to test/debug/fix.

    Log all GCE's, see if they are getting the same/different views of data, and then pick the one that fits your expected values.
     
  12. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Is this still the only way to do this in 2023? If so, could you please expand on what kind of limitations the "if your targeted platform allows it" alludes to? Many thanks!