#🧰┃ui-toolkit
1 messages · Page 5 of 1
This matches the values I set
It's just the resolved value that flips the Y coordinate
is there a reason you're offsetting from bottom and not top?
Because the screen coordinates start at the bottom left
It's just more intuitive to set the X and Y value the same way when converting world space positions to screen space IMO
The origin of an element is its top left corner afaik
The element is only 12x12 size, it should still be close to where I expect it to be
Ah I think to center it wouldn't matter if it was bottom or top anyway, as the distance would come out the same.
I don't think I can think of what might be wrong, other than perhaps using style instead of resolvedStyle to get the size?
What is positionInPanelSpace?
It's just the screen position converted to panel space
Screen position of your cursor presumably?
Yes
Are you using the new input system?
Yes
I'm so confused as to why this worked before upgrading
I even reverted and checked to see if the values changed between upgrading
Top is the old working one, bottom is the new broken one
Values are very similar (mouse position is slightly different)
https://gdl.space/cilozicoqu.cs this works fine for me, is it different to your results?
That's pretty much exactly what my code is doing
I'm just not doing Screen.height - mousePosition.y
Since I'm using bottom
If I don't flip it, and use bottom it's wrong
Why
Ok, it's an initialization issue
That explains why it broke with the entities update, the system must be created at a different time
If I delay the creation, everything works as it used to
I don't understand how that can be though
Ah, I think I get it
I guess this ones on me for having a weird set up. If I was using the inspector when I designed this runtime stuff this probably wouldn't have happened
@rough scarab the reason is I have a full screen container that is pushing the crosshair to the bottom of the screen instead of the top left, which is why my bottom offsetting works
Ah, I'm missing Absolute
The entities update changed the system initialization order so the crosshair container is now at the top
That's why the crosshair is an entire screen height above my cursor, because the container is now at the top of the screen instead of the bottom
Why didn't you spot that using the debugger? Surely you looked at the hierarchy?
Because I'm an idiot and missed it
The container is width and height 0 so it's not highlighted in the hierarchy
Ah yeah. Oh well, at least it's resolved. There are a lot of traps with coordinate spaces and styling to run into
I'm guessing the correct way to actually do this is also absolutely position the template container from the spawned asset and then offset from the top like in your example
So it's not pushed around by other stuff
I'm still not sure with the runtime UI if I should be separating these things into their own UIDocument or not
Since that just seems to create an absolutely positioned full screen container
I would definitely consider a StretchToParentSize if it's children are just meant to be in screen space
That would only work if it's positioned absolutely
TemplateContainers use relative by default
Anyways sorry for wasting your time
All good, I wasn't very accurate on first assumptions this time around ):
It would set it to absolute; but maybe we're talking about calling it on a different object
Are there any issues with using many UIDocuments as layers?
Looking at the hierarchy they just seem to instantiate a visual element and then spawn the asset you set
Not sure how it's enforcing the sort order though
https://forum.unity.com/threads/all-ui-under-one-gameobject-or-several.1156772/#post-7422992 is fairly enlightening
They all use the same panel settings
I guess at the end of the day there is barely a difference between the two approaches. Either you use UIDocument as the container, or you create a visual element as the container and sort it yourself
Maybe even a very tiny performance boost for using multiple UI documents if you can better isolate the UI elements that are actually interactable to a single UI document and the other things are on other documents without a panel raycaster
Probably no difference in actuality I would assume though
I guess the sorting is somewhat useful since it seems to enforce the order on each frame against all other UI documents
Anyways I'm off to bed, thanks for the support ❤️
how to resize the text, to fit the visual element container??,
No such feature in uitk yet
so i want when my button :hover, i want to access its text element(child) and translate its y position to up, how i can do that?
.grid-item-toggle:hover Button > .unity-text-element is it like this?
Hello, I change the color of the canvas with the UI Toolkit, but it has no effect on the game. How can I fix this?
attach another VisualElement and assign background color style to it
How do I apply USS files?
either globally - add it to theme
or locally - add it in UI Builder/uxml
I'm not familiar with css (if it is css kekw)
but I don't remember ever seeing this one for USS
anybody know why I cant open the ui builder?
have already tried restarting the project
even when I create a brand new project in 2022.2.1f1 urp I still cant open ui builder
your style says 0 is inlined
either your element has explicit style declaration of height 0 or you assigned it through code
then I guess you simply declared height 0 explicitly
inlined
settings what?
if you define styles in code
they become inlined
you shouldn't do it if you want height to size automatically based on styles
do you override built in progress bar?
yeah...
I suggest to just create your own from scratch
😅
almost all built in Unity components are done in a very awful way
hardcoded sizes, margins and etc
also a huge confusion with class names that are 20 symbols long
sometimes they are combined
which makes overriding not possible, without code
potentially there is no container
just check in UI builder
what components are there
and what styles they have
oh
they define name
explicitly
and you defined name as empty string
they don't match
does anyone know how to create settings for which gamepad buttons do what in ui toolkit UIs? As an example dpad doesnt work for UI navigation and certain buttons are used for button clicks, i'd like to change these so that dpad selection works and different gamepad buttons can be used to click UI buttons
I guess you can try to send events yourself
you mean by overriding events and doing something like preventDefault method, etc.?
no
simply send existing ones
as in
mimic whatever event system does by default
sorry im trying to understand. do you have an example?
@gusty estuary I think I found a bug in the generated code. Why is the prev value default?
interesting
but this is a bug to submit for community toolkit repo
wait a second
check this method first
what method?
with default passed
yeah, this is partial method declaration
but still
interesting it uses default
I'll ask Sergio
ah nvm it's actually fine as long as you redefine the method
Yeah
I've added this
partial void OnTestIntChanging(int oldValue, int value)
{
throw new System.NotImplementedException();
}
and the generated code changed too
@lone mantle#169726357331378176 message
Anyone know how to draw with meshes/verts in UIToolkit?
The example they give literally doesn't work for me and I don't know if that is a bug or if their example is just out of date
https://docs.unity3d.com/Manual/UIE-radial-progress.html
on the other hand, using the painter2D does work but doesn't fit my use case
Nevermind i figured it out
Hello! In an EditorWindow, I have an InspectorElement that renders out as an IMGUIContainer. This element has hidden content to the right that is truncated by the ScrollView that it is parented to. Is there a way that I can alter the width or style of the InspectorElement (rendering as an IMGUIContainer) to have it fill the space but not overflow?
Wondering if it might be a case of this: https://forum.unity.com/threads/inspectorelement-seems-broken-still.1195420/
{
_inspectorTarget = inspectableVE;
VisualElement target = _inspectorTarget.GetVisualElement();
MapTileVisualElement mapTileVE = target as MapTileVisualElement;
if (mapTileVE != null)
{
Debug.Log($"Inspecting {mapTileVE.tileNode.locationName}");
InspectorElement selectionInspector = new InspectorElement(new SerializedObject(mapTileVE.tileNode));
selectionInspector.style.width = 100f; // Trying stuff here
selectionInspector.style.fontSize = 9;
_selectionScrollView.Clear();
_selectionScrollView.Add(selectionInspector); // Trying to populate with the default editor for mapTileVE.tileNode here
}
}``` Generating the InspectorElement object
Hi. I'm wondering if there's a simple way to render UIToolkit elements in the game world? I want dropped items to have text on top of them of the item they're representing, but google searching hasn't come up with anything. Wondering if I have to use the default GUI for this, or if there are ways to handle this.
Thank you.
no world space
use uGUI
Gotcha, thanks. Is that a planned feature later down the line for UIToolkit?
it's under consideration
and tbh, I wouldn't want it at this point
uGUI works just fine for now
while UITK needs some other features badly
UGUI by itself leaves a lot to be desired.
I mean, use UITK for panel UI, uGUI for world space
Okay. I have multiple UI Document GameObjects with scripts attached to them. I am registering callbacks on my buttons (which I have verified are being found), and while the ui shows them being pressed graphically, no callbacks are being called. Is my document being blocked or something? What is this?
use debugger to check whether any transparent elements blocks your buttons
Okay. Well I DID figure out that the problem that plagued me before about the panels not getting input was because of the transparent elements. In the debigger heirarchy, my trees are all under my panel settings; Are the panel settings the ultimate root of my documents, and so would putting different documents in different panel settings fix the issue?
oof, different panels will act differenetly
and I think they will compete with each other even more
instead, just keep your uxml
avoid useless element overlaps
or use proper attribute
so clicks are not blocked by element
Well the problem is that my UI is in front of my menu
although, not visually
I have the UI, my game menu, a console screen, and this new screen im working on, and im enabling and disabling things as they go. But the UI is always there in the back
In my approach if I use fullscreen view
I always disable it from root
So no overlaps can happen
also this gives me an ability
to catch clicks outside of any other element
if you really want to not disable your root fullscreen element
just use attribute
uugh
can't remember it's name
but it has values Position and None if I remember correctly
Well the pause menu and the other menus are disabled when they aren't needed, only the UI stays
how do I make sure it's always behind or doesnt receive events at all
wdym by UI?
I meant HUD, whoops
I have separate UI document game objects for the HUD, the pause menu, the console screen, and a playtester screen I'm currently working on. All of these use the same Panel Settings asset. My pause menu stopped receiving events, and when I looked at the debugger and used the pick element tool, it was picking out the HUD (behind* the pause menu, meaning they would never get those events. I believe this could be what is also impacting the playtester screen, which is also not receiving any events, but I dont know how to fix it.
first of all ensure your hud is on botton of hierarchy
(at index 0)
this way it'll be the last to get event
then
you can also change picking mode attribute (finally I remembered it's name)
which will make HUD to be ignored
does picking mode extend to its children?
Ayy- I'm trying to contain the width of a generated IMGUI container to its parent's dimensions. Does anyone have any insight into this?
I cannot pick my HUD. But my buttons still don't call their callbacks, even when clicked. how annoying
did you check debugger?
potentially something overlaps your buttons
also
check whether you have event system
it's required for any clicks
I have the event system and it registers the event. But it doesn't call the callback.
document.rootVisualElement.Q<Button>("close-button").RegisterCallback<ClickEvent>(_ =>
{
print("close menu");
Metro.Game.Unpause();
});
so it Should work
did you check debugger?
looks fine, I can select it no problem.
And the click animation plays and the event is called
yeah it's displaying no problem
well. right now im having a lot of trouble with unity complaining that the UIDocument element isn't there, but it works for a while after I recompile scripts, but I thin kthat's unrrelated...
when you use preview in UI builder
does it work?
as in, do you see style changes (hover, active)?
the buttons appear to be pressed when I click
does it happen in actual game?
yes, thats what ive been saying
then your callback works
It changes its look to look like it clicks, and the event registers
but my callback is not being called
code here, in Start()
must be in OnEnable
Ah
UIDocmunet scraps hierarchy when disabled
and all your callbacks are gone
on next enable
oooh
potentially that's what happened
for this reason you might want to use separate class for storing hierarchy
since recreating it every time is pretty performance expensive
Changed nothing. I should also add that I'm also attempting to register a KeyDown event (I was trying to debug) but it also doesnt call the callback
can you show code?
I just finished making a pastebin https://pastebin.com/3Zwewx87
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I'm using a lot of GetComponents while trying to debug the nullreference issue
and I could absolutely use a lot more lambdas (I like lambdas) but I removed them while troubleshooting
well, idk
everything seems ok
oh wait
lol
document.enabled = false;
why do you do that
when you do that
you scrap the hierarchy
Why: To hide and show the panel so it doesn't interfere with anything
When: Enable when shown, disable when not shown
wait
so youre saying
just look at OnDisable method of UIDocument kek
it's literally getting rid of visual element
I am registering lal the callbacks, and then disabling it, getting rid of all my callbacks
okay. I see.
So I should just set visible to false
...and also make it not interactive. somehow
will it also make pickingmode ignore?
it will make element as if it's not there at all
okay
btw, check out my package for UITK
Most of those headaches are thought of for you and bindings are way easier and don't require any code
https://github.com/bustedbunny/com.bustedbunny.mvvmtoolkit
oh my god it works. thank you very much hahah
oh, your package here allows for language binding. hmm that is something I was not looking forward to implementing
You are free not to use it. In future I consider removing explicit dependency on it and instead use #if directives
ill figure out how to use it when im not tired
Does this require me to edit the uxml by hand?
kind of. It's way easier to edit bindings in editor vs UI builder
other than that
it's not required
oh yeah I also have to figure out how UI Toolkit bindings work. that might be useful to me.
I don't use built in bindings
since they are Editor only
I implemented my own
i somehow have set the input text colour to white... How would I change it back to black?
@gusty estuary why is bindingContext private in the BaseView, and why is it of the base type? Am I supposed to set the ViewModel in the inspector, without the type checking and then cast it in my code? Don't you think that's terrible experience? Also, does your library support any form of DI by default?
yeah Inject attribute for all Views/ViewModels/Any other registered service
as for binding context - isn't there a property for it?
yeah but it's read-only
or make the base type generic and work with interfaces where your code depends on that BaseView
but in general, you are supposed to get reference to ViewModel however you want (for example with DI) and then just assign it BindingContext manually, or use serialization
I'd do that
il2cpp should have no problem with it, since they will be used for subclassing, hence will have a concrete type as the generic argument
so far all you need is just 1 line to cast to your type, yes
That's why I didn't really gave much thought to it
oh, I see what you mean
yeah but in the editor it can take any view model
no I did that before, and it was terrible workflow
while my code obviously only expects a set type
well yes, binding is asset based and doesn't have strong type requirments
thus binding context is the way it is
in a way - you should be able to swap out ViewModels easily
@gusty estuary What's the right way of making a table, aka creating a row for each (complex) element in a collection? I was thinking making a VisualTreeAsset and then instantiating it for each of the elements, binding it to the element of the collection (it contains view models) and then resolving the bindings. But is there a simpler way? Maybe inline like in the modern web frameworks where you can just iterate a collection? The code gets really complicated, I need to manage the lifetimes manually etc.
sorry, atm there is no collection binding, but it is in plans
In WPF I'd just have a UserControl with the underlying view definitions declared normally in the markup file, and then I'd just instantiate it manually
yeah, there are lots of thoughts about it
But here, the views seem to be designed for the whole documents
due to the fact that document parsing is not exposed
there will be a need for tricks
but atm you just subscribe collections the same way you would do normally with UITK
query for VE and set it up
yes
is it safe to not dispose of the BindingParser and stuff when I dereference the element from the ui?
BindingParser is disposable
just dispose of it
if you don't - bindings will keep running
Yeah I mean if I remove the visual element, is it going to be garbage collected together with the parser, or does it have some global references to it or some other nonsense
idk it might be obvious to you, but it's not obvious to me
BindingParser is subscribed to INotifyPropertyChanged event of binding context
what is your goal anyway?
Why do you have a need to change reference of it?
ok so it's like this
view model <- binding parser -> visual element
more like
ViewModel -> BindingParser -> VisualElement
it's 2 way only for ValueChanged binding
yeah well they are all both ways because of the events
oh yeah
sorry
I forgot about button callbacks too
well yeah, I guess that would be your 2nd
VM <-> parser <-> View
but once again, what's the reason to get rid of it?
lifecycle of View/ViewModel should be same as app lifecycle basically
or UIRoot to be precise
ok as long as nothing else refers to them, just removing the element and the model from the references should be enough
because the collection of rows is an observable collection, elements come in and go out continuously
I don't instantiate view classes for it (the MonoBehavior ones)
ooh
I think you do it wrong
ListVIew or TreeView support data updating themselves
based on source
you simply need to define delegates for creation of element/binding it
and if collection is updated
ah cool then
call Update or something like that
on them
yeah, internal elements should be private to ListView/TreeView
I'm a little concerned about its performance. My table will have thousands of elements, which will be added at the front
Ok thanks I'll look into it
@gusty estuary My UI gets created and shown on the screen even if I don't enable the view component. When I do enable it (like with a message like showed in your readme), a second copy of the ui appears. The first copy might be from the UIDocument. If I attach the UIDocument to UIRoot, two copies of the UI appear, if I remove the UIDocument from the UIRoot, none appear, even though my message is sent. I'm clearly missing something fundamental
You don't put anything in UIDocument
you only attach it to UIRoot
UIRoot attaches hierarchy itself to it
ah ok
So do I bind a property like this? <ui:TextField text="CurrencyName1" view-data-key="{%CurrencyName1}" />
It only binds it one-way though. Can you customize the binding direction like you can in WPF?
@gusty estuary
% is value changed
binds 2 way
I need a two way binding
No, it only binds one way, I just checked
ah hold on
I might be wrong one sec
Yeah ok you were right, I just messed up a little bit
as for customizing binding direction - not without custom controls
and I don't want users to force them
so, since Unity controls are only supposed to be 2 way bound are Inputs
But do I have to type the view-data-key thing every time? why not allow syntax like this:
<ui:TextField text="{CurrencyName1}" />
I don't have access to parser, so in order to allow such binding I'd need to hardcode it for this specific type INotifyValueChanged<string>
in WPF you do {Binding CurrencyName1}
and I don't really feel like doing it, since it'll be not very obvious
does the xml parser in ui toolkit handle {x} in some special way?
no
what I achieve by using view-data-key
is that it exists on literally all VEs
and it gives me pure string
that is not modified by the time I parse
wait there's no attached property system in UI Toolkit?
So I'm having a weird issue with Runtime UI. When I click buttons I don't get any callback being called
buttons[i].clickable.clicked += OnClicked;
private void OnClicked()
{
Debug.Log("HEY!");
}
Not sure why this isn't working I have set up the script as suggested in the docs
Am I supposed to also have a canvas in the scene? Or is there something else I'm missing?
Oh yeah I probably should mention I'm using the New Input System
Not sure if that is a problem or not.
do you have EventSystem in a scene?
yes
What is odd is when I click play the button is being highlighted when I mouse over the button
But when I click on any button no eventrs are fired
show whole code of how you bind
I'm not binding through code
I literally copied this from another project that works with uGUI
🤔
I just rechecked
there is no integration between new input system and UITK that allows you to not use any code
Oh I thought that was old documentation.
Welp I guess I have to remake my UI using uGUI 🤷♂️
do you strictly need to avoid coding or?
No I just do it that way since it is faster to set up
I made a package that allows you to bind using MVVM binding
maybe that would be interesting for you
I will try this out and see if it works out for me.
@gusty estuary Before I try what you suggested I do have one question. After reading over the documentation it does say this
A pointer click and a gamepad submit action are distinct at the event level in UI Toolkit. This means that if you, for example, do CSharp button.RegisterCallback<ClickEvent>(_ => ButtonWasClicked()); the handler is not invoked when the button is "clicked" with the gamepad (a NavigationSubmitEvent and not a ClickEvent). If, however, you do CSharp button.clicked += () => ButtonWasClicked(); the handle is invoked in both cases.
Based on this it should work
well yes, do you call this code though?
And in my project I do get the highlighting and selection effects as expected
Oh no I don't
in your example you also do button.clickable.clicked instead of just button.clicked
I mean I do the button.clicked callback to see what happens
which technically should be same thing
I have actually tried both
but I don't remember details
And neither fire off an event
can you show how you call it?
when and where
because it matters, in case your uxml is instantiated from UIDocument directly
private void Awake()
{
document = GetComponent<UIDocument>();
VisualElement root = document.rootVisualElement;
VisualElement menu_buttons = root.Query("Menu_Buttons");
List<Button> buttons = menu_buttons.Query<Button>().ToList();
for (int i = 0; i < buttons.Count; i++)
{
int index = i;
buttons[i].clicked += Test;
//buttons[i].clickable.clicked += OnClicked;
}
}
yeah
you are meant to do all bindings in OnEnable
because UIDocument nullifies VisualElement hierarchy
on disable
Oh I didn't know that
so in case your UIDocument was disabled after Awake, your bindings are as good as gone
Oh ok so it works now that I put it in OnEnable
That is something that should be stated in the documentation because I wouldn't have known that was a thing if you didn't say anything about it.
I see why all examples put all the set up in the Start method now 😅
they actually recommend disabling UI through style for performance
which is what I do in my framework
That makes sense
Question about that. So I have a page system for my UI that I use so I can do transitions and run callbacks when I swap UI in my game. If I just set a GameObject to inactive this would basically make the UiDocument nullify the root visual element right?
yes
to avoid that
instantiate your hierarchy on separate class
and simply reattach it to root of UIDocument on enable
or don't ever even touch UIDocument
simply control your UI through style
what should be enabled and what not
So it would be bad to call gameobject.SetActive()?
in what context?
Because the way it sounds is if I have a UiDocument on a GameObject I should be able to enable and disable it whenever I want to turn off all Ui attached
to do navigation between views?
No I mean switching from lets say a Title Screen to a Level Selection Screen
yeah, that's what I meant by navigation and yes, that would potentially be bad or potentially not
let's put it this way
I assume when the OnEnable is called it will just give control back to whatever script is running
if your Views are stored on UIDocuments
calling enable/disable
will be very slow
it'll have to parse uxml file and etc
do all bindings
but
if it's one time operation
that should be fine
since once you disable
you dispose of useless memory
for things like main menu and etc
Oh Ok I see what you are saying. It is sort of like how updating one element in uGUI makes the game have to rerender the whole GUI
it is similiar way in UITK though
but just way more efficient
since it's pure C#, and doesn't have c++ objects behind it
OK So what I probably should do change my UI navigation system to just tell the root of each of my pages to disable and enable when needed, but keep all the UiDocument objects always set to active
you can simply toggle between Flex and None enum in rootVisualElement.style.display
yes
Yeah that was what I was planning on doing.
And I assume if the display is set to None all the Ui Navigation doesn't work like in a Editor Window correct?
None is as good as it's not even there
Ok so just like in an Editor Window
no events are propagated to it, it's not displayed
One more question.
How would I handle setting up setting a first selected object like how it is done in uGUI since VisualElements aren't GameObjects?
Does RelayCommand CanExecute not work with INotifyPropertyChanged? It doesn't reenable the button when the property changes, even though the event for it is being raised.
Ah I have to also trigger update for the command property, I see
You need NotifyCanExecuteFor
it's attribute
or you can do manually
MyCommand.NotifyCanExecuteChanged();
wdym? First menu that is opened?
through code ig
or you can make some script that accepts your View object in inspector and enables it
yes, for the command, not for the bool
ugh? Could you elaborate what do you want?
I mean how do you set a object as selected like when you use EventSystem.current.SetSelectedGameObject();
I don't see a way to do that with VisualElement.
oh
you don't do that
in UITK
UI hierarchy must be self managed
RelayCommand takes a name of the "can use" property, what I'm saying is to refresh the command "can use" state in the UI I have to trigger the property changed of the command rather than of the "can use" property
click/keyboard and other events are managed through callbacks
Oh Ok Thanks
can use relies on method/property/field of bool
if your relay command has argument
you can pass it to method
one sec, I'll show some example from sample
oh wait, nvm I don't have one in sample
😅
I'll get one somewhere else
I've figured it out myself
all right
my most favourite usage of can use - radio buttons
since built in radio button group works like total garbage
[ObservableProperty] private int _curSelected;
[RelayCommand(CanUse(nameof(CanSelect)))] private int Select(int ind)
private bool CanSelect(int ind) => ind != CurSelected;
just 3 these lines give you a fully functional radio button group
also needs an attribute to notify can select changed, but I think you figured it out already
yeah
Hi, I have a question regarding listview elements. In my game I have a list of elements that get sorted by distance from the player. They're all in a list view, and in which case I refresh the list view every 5 seconds or so, so the list view re-sorts based on that distance.
However, when I hover over an entity, and it changes color because of hovering... is there a way to stop the little "flicker" that the listview gets from refreshing while hovering over elements? It's a bit annoying and makes it look a bit janky. Wondering if this is a common problem of some kind. Thanks!
I found a solution that seems to work for me. It doesn't seem like the greatest solution, but you could potentially make your own listview handler for this:
I created a simple "listview index" variable
public int elementHovered = -1;
This holds the element of the list view that you are currently hovered. Then you check only on element enter and leave whether or not you are on the element. You do all of the following in makeItem.
e.RegisterCallback<PointerEnterEvent>(ev => {
elementHovered = i;
e.style.backgroundColor = new StyleColor(Color.blue);
});
e.RegisterCallback<PointerLeaveEvent>(ev => {
elementHovered = -1;
e.style.backgroundColor = new StyleColor(Color.red);
});
You set the color on pointer enter / leave, as well as set which element is hovered on enter. (on leave you set it to -1, since no element can possibly be -1).
Then you do one final check at the beginning of makeItem to ensure on item creation, the color is set based on elementHovered
if (i == elementHovered)
e.style.backgroundColor = new StyleColor(Color.blue);
else
e.style.backgroundColor = new StyleColor(Color.red);
This is by no means a perfect way of going about it, but it seems like it works and is a workaround from how listview renders / refreshes its list
I'm really annoyed.
If you put a TextField in MultiColumnTreeView, the TextField cannot be selected correctly, and always loses focus on MouseUp
List/Tree views are meant to be single callback recievers
so you have 500 elements, but only 1 callback is registered for click - ListView itself
what you might want instead - make focus on your element through OnSelected
(not correct name)
but you figure
Right. use the Tree's onselected event to focus the element
tbh, not sure if you should use list view with input
I don't remember really
but I feel like
MultiColumnTreeView
should have an option to make cell input
once again - not sure
hmmm. still no luck
how about totally alternative approach
you put input field outside of table
when you select table
you simply activate selected object
so it gets affected by that single input
im still trying alternative ways of forcing focus on the text field in the list.
I need a list of editable fields so having them outside of the list feels backwards
nah that just prevents any child elements from grabbing focus
yeah it looks like the list views arent made with the expectation that children will grab focus
they kind of are
they made them
because propagating events to hiearachy with thousands of elements is really slow
well you can select list elements, but the events don't propagate down to the children
Yeah that does seem like the best option currently
with just a scroller
Man I am so close to finishing the first iteration of my editor window
I think I might just leave it in this semi broken state while i get everything else workign first
yeah those
it looks good enough and the frame line selector works. I just need to add the keyframe diamonds
You can make diamond element always there, but keep enabled state (style.display) based on whether there's a key
that would require a diamond element for every frame.
Nah I'm just drawing a custom mesh for each diamond (only 2 tris so its performant)
They still have to be updated every repaint when I zoom in/out, but thats not too much of an issue
doesn't sound like a good approach
why not?
I'm going to need a ton of frame diamonds, since each property can have one for each frame
hmm
so i need it to be performant. using the low level mesh drawer is the most performant way
zoom manipulator doesn't really work for my use case, also i already implemented my own
since it's really meant to be used with experimental shader graph
I see
all right,
wait a second
why do you need mesh
when you can use scale
of transform?
if you keep diamonds as visual elements
they will get scaled properly
what's even more important
you can easily make them not just diamonds
but text
sprite
whatever keyframe is meant to be basically
hmmm myabe. but I already designed my grid element for custom drawing so at this point its probably easier to do custom mesh drawing on repaint
i can still use sprites on them
and perform selections
how about texts?
for example if you want to see all values that will be assigned to int field of icd?
the keyframes wont have text,
but the mesh drawer also lets you draw text directly
already do that for the ruler frame segments as seen in my image
if I'm not mistaken
it's IMGUI
which will be extremely slow when there's a lot of elements
nope.
MeshGenerationContext, which is UIElements
yeah. sorry for the confusion
only issue with drawing the vertexes directly for tris is that it lets you draw them backwards, and they don't show
Why are there reverse normal cullings for a 2d UI?
actually don't answer that, i know why.
alertVisualElement.RemoveFromHierarchy();
if I remove element like this, and I had registered event
b_CancelBtn.RegisterCallback<ClickEvent>(ev => HideUIModule(ev));
do I need manually unregister event, or it will get destroyed automaticly?
Registered callbacks will stay. Allthough if you fully dereference this element. It will be destroyed by GC
so just in case it is better to remove call backs with b_CancelBtn.UnregisterCallback<ClickEvent>(ev => HideUIModule(ev));. Is there a way to unregister all callback from button if not providing specific one?
@gusty estuary how do I bind ListView to an INotifyCollectionChanged or an ObservableCollection?
Just setting its itemSource is not enough
in hindsight, duh, it's obviously not enough
ObservableCollection has callbacks
you can use those to update your lsitview
sorry, not collection binding atm
What is the binding path for properties like this:
The baking variable contains some key words like <> which are not allowed for some reason in the binding path
show full path
It's a field in monobehavior
this is confusing, shouldn't "Max" width lock it from being extended beyond it?
also 100% doesn't seem to take up whole width for some reason
hierarchy
And how do I do that? It only has .Refresh which recreates everything
it can update by id too
what id?
I just needed to use viewController ig
nope, this one removes the item from my items source, not reflects the events
@gusty estuary like literally what methods do I have to call to affect the list? I can't find anything. BaseListViewController seems to be modifying the ItemSource, and I don't seem to be able to communicate this to the ListView
This isn't good enough for me, I think, I'm adding items to the front. With only that one method I'll have to shuffle around everything
yeah it's way more profound than it seems at first
You can do all your sorting to your itemSource and just myListView.Refresh() it will re-bind those items
This should be straightforward, have the listView cached somewhere (singleton would be nice) and do the Refresh via your observablecollection callback
I have thousands of items in it
Doesn't matter, ListView does pooling by default
and it doesn't sound like a real solution
one question: does visual element use an array for the children internally, or a linked list?
why not? it only allocates what shown in your list container
and the elements will be re-used when user scroll up/down
just make sure you read their docs, specifically regarding virtualizationMethod in listview...
so i am trying to get started on UI toolkit by making a custom editor window,which i have done before but in IMGUI,but it gives me an error "item at index 0 is null"
var test = root.Q<ObjectField>("GOReplace");
specifically from this line,and i have no idea what is wrong,the ui element name is copied from the ui document,any idea why this is happening?
By the looks of it if it is giving you an error at that line your root visual element must be null
So you should probably figure out why it is null
Something must be setting it to null to cause that error
just restarted unity,that fixed it,also when i close the window i have to restart unity to open it again,why?
🤔
That is odd
That shouldn't happen
From my experience it is probably an error that is causing that
Because when there is an error Unity stops trying to render the Window
Do you have any code that runs when you close the window?
i am not sure
but looking at it now
it stopped being a problem,will come back with more info if this happens again
https://docs.unity3d.com/2021.3/Documentation/Manual/UIE-Keyboard-Events.html
Is there a controller equivalent for this?
Is there a way to have a constant animation on a UI element?
What do you mean?
I want to have a spinning element to represent something is in progress. I see there are transitions, but is there a way to have an infinite animation?
I don't think so. The way I would suggest doing it is to have a set number of sprites and loop through them to simulate the animation.
controllers propagate navigation events afaik
They do but I was looking for something where if I press the X button it would be able to send an event.
So basically something like a modifier key but for a controller
no, nothing like that
but you can send them yourself
I assume you want Root.SendEvent(yourEvent);
Oh I think that will work. I wasn't sure if it would when I was looking through the documentation.
Is there a way to use a script to change a VisualElement's percentage size?
Let's say I have a life bar and my unit goes from 90% life to 80% life, I'd like to just change its life bar width % from 90% to 80%
ve.transform.scale - you can also use ve.style.scale but the former is much more efficient
Thanks, will take a look, didn't even think transforms mattered to ui elements
it's very different from a GameObject transform - it just has the same name
isn't the latter is the new transform style api? that should be more efficient than the former I think (feel free to correct me if I'm wrong here) https://forum.unity.com/threads/introducing-transform-styles.1195972/
what's the simplest form of aligning a self growing visual element to the bottom center of the screen? i can only make it work with 2 visual elements where one has flex:column and a 2nd with flex:row. can this be done with only 1?
https://pastebin.com/V39MuzC4
I have a custom VisualElement that I would like to be able to update after adding stuff to it using VE.Add(). Under some circumstances when loading up the Unity Editor it works immediately, but often while I know the VE has been updated in code, I don't see changes in any EditorWindow. Does anyone know what's up? See the last line (and comment).
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Your object's parent might have to have it's flex direction set to (pictured) if the child has a fixed size.
@past ermine If that stil doesn't work, ensure (pictured) has "Grow" set to 0 on the child.
hm, my description wasn't very clear. the VE having a parent is what i want to prevent. it should just be in the root that has no style. but it seems unlikely now that this would work. the element itself is dynamic in size based on the elements (buttons) and needs a flex:row
(think of a simple mmo skill hotbar)
Oh, well then you're definitely needing to work in postion: absolute mode, where the parent is not relevant to the position of the child.
If you haven't already done so, make that change and then start by setting the position "bottom" attribute.
Make sure this is Absolute and not Relative.
i tried with absolute, left: 50% and bottom: 0px. the left one works fine but as soon as i set the bottom the element vanishes from my screen. 😄 no idea where it goes
What if it's like bottom: -20? Is the object anchoring from it's top? @past ermine
good call, yes it does
hm, why is this happening and is that fixable?
Still can't find a solution to this:
In the editor, the image looks just fine, but in-game, it seems to be doing something weird with either the compression or alpha.
Notice one is all blurry and the other is much more crisp.
Any help would be massively appreciated.
Why is this happening: UI Toolkit draws top-down by default, so you're setting the top exactly 1 screen height from the top of your screen, so rendering starts immediately below.
Try playing with this:
but it's rendering from the top. that's what's unexpected
Can you please share a better picture for human consumption? @hasty parcel
So you gotta make the origin of the object start at the bottom, so relatively the object draws absolute: bottom 0 at the lower-most pixel.
Bump: #🧰┃ui-toolkit message (The more I answer, the more my problem gets pushed up :/)
@past ermine Teal thing has:
ok, i found my problem. for some reason the root is 1437x0 in size. if i set it to my screen size it's working as expected
thanks for your help. sorry i can't help you with your problem. i've only used listViews and those worked fine with just adding. maybe something isn't refreshing correctly.
Hi. How do I make fix the header of this table? I need it to always match with the items in the ListView. The problem is that when there are too many items, the scrollbar appears and offsets the rows to the left a little bit. I though I'd add an invisible element with a fixed width equal to the scrollbar width to the header, but how do I reliably detect it when the scrollbar appears? And how do I get the width of the scrollbar? There doesn't seem to be an event for this.
try to make this element child of list
ain't gonna happen
I'll have to shuffle through all my code to implement that
actually, I can't make that work, because
- the header is bound to a view so I can't instantiate it together with the rows
makeItemdoesn't depend on the index
just you imagine how much stuff that would break, it's not an option
I haven't been able to find anything, but are there any good resources or tutorials for using UI toolkit to build a custom pixel art ui and have it be scaled properly to the game?
The one you linked is the more optimal one and was the first (former) method I mentioned. The alternate less optimal method is via .style which is the second (latter) method I mentioned.
begin with manual
it'll explain all core stuff
yeah but in regards to the normal ui toolkit no? not specifically with pixel art
yes
but you can't make specific UI if you can't make generic UI
hmm
I mean I know how the basics work and how to make a UI with the prebuilt elements and stuff
the top circle is from the ui and the bottom one is just a game object
they're both supposed to be the same size
16px, but if I set the ui element to be 16x16 it's way too small
then for pixel styled UI you'd mostly just need pixelizied sprites
they are indeed pixelized sprites 🙂
it's a 16x16 sprite set as background for an element
what's the question then?
how to get the sizing to be the same
you need to provide more details
it's unclear of what sizing you are talking about
well, my sprites are sized to 16 pixels per unit
for game objects
but if I set UI elements to be 16x16 they are much smaller
reading through the manual doesn't really provide any clarity unless I missed something
why can't you just make your elements proper size?
so they visible fine
because I would assume that 16x16 which is my sprite size would be the same size
so it's unclear what size would translate to equal size
16 pixels are 16 pixels 😅
it is exact size
🤷♂️
you define pixels on screen
right
is there no way to relate ui element sizes to unity units
no
UI toolkit is panel based and has 0 relations to world space
would anyone know how to make it so a label's text color changes from red to purple in a rainbow like style?
no custom materials support atm
but one way you can do it - through sprite/texture on background
wouldn't this just change the background and not the text itself?
🤔
that's even more complex
check out text manual
maybe there's some specific feature that can do it
https://docs.unity3d.com/2022.2/Documentation/Manual/UIE-color-gradient.html i found this and tried it before asking for help here,but it didn't work when i put it in the text and also it doesn't work on the whole text only on a single char and it only accepts 2 colors,guess i will just stick to black text
check with built in font first
custom fonts might not support rich text features
the thing is,i want a custom font
just check it first
whether it works
didn't work it arial aka unity's font
then odds are you did something wrong
<color=white><gradient="Light to Dark Green - Vertical">Light to Dark Green gradient</gradient></color>
is the line i typed and it doesn't work (the color part works,but not the gradient part)
did you create gradient asset?
where do i put it in?
sorry, no idea
but looks like
it's folder?
Place the color gradient asset into the path set for the Color Gradient Presets in the Panel Text Setting asset.
it works now,but there are 2 problems
-i want it to lerp from red to violet in a rainbow like order
-the gradient spans from character only,i want to span to the entire text
out of interest, are you all keeping your template containers or do you remove/work around it through code?
I kind of have to keep them, because they are root of uxml hierarchy
and they don't mess up your layout and styles with something like a dynamic growing container with elements?
they don't contain any styles at all
which is sad
I'd love to be able to define them
so instad I assign proper styles when I instantiate
yeah same. no, i mean i had the problem that they screwed up styles. not any style, styles related to layout size
so i have 2 problems
-how do i change the label color (not text),i tried changing the color but it only changes the color field
-how do i adjust the size of the actual toggle part
Input control label has a specific styles on it
you can override them
just open that toggle element
and inspect how it's constructed
are there tutorials/any sources for how to override them?
Manual has a styling manual
which explains styles and selectors in depth
is there a css floating around that has all the default styles in it? annoyingly all css data is stored in a scriptable object inside the editor resource file, so hard to extract
not that I know of
but usually
I don't need it
since I can see all default style values
when I simply inspect some element in UI Builder
it's under Matching Selectors
yeah but it's not like copy pasting them, is it? more like manual line by line
ugh
It's better to just take a look
any standard control that is not raw VisualElement has them
Hey, first time using the ui toolkit, i wanna try some stuff but i have no clue how to do or approach that. So i wanna have a button on the left side, if i click it a smal menu with different buttons should appear. Like in the pic(it doesnt look good but it shows how i wanna have it in the end). Any ideas how i could do that?
what exactly raises questions here?
How i could approach to do that. I haven't seen anything like a box which I could put outside of the window, which i just needa move into the view, a way to fully hide a container or slide it in and out or something like that. And all the tutorials i find aren't helping at all
you can just make elements hidden with display style
Feel like UI toolkit does a poor job at representing how it actually looks
It's unclear what you are comparing
So what's the problem?
how does one match themes or screen size?
I'm using 1920x1080 as base
Open debugger and check whether styles you applied are exactly same
err where does one see that
Top right of view
you mean this?
not sure what you mean with that
Like why would they apply differently in any sort of way when I only have this one thing I made with the toolkit?

I don't get it, if it might affect the size - why isn't it being displayed in the editor to begin with...
Seems backwards..
do you modify view in any way in runtime?
bruh
what?
Don't rely on it too much then
same issue
Open debugger in builder as well
And compare details until you find what's different
Also
Alright
Where do you set those
You set those youreslf in style

Sir, if you don't know what style does - remove it
But I'm not using any style sheets
So far you attached a bunch of potentially conflicting settings
Inlined styles are also styles
How to flex resize visual element with aspect ratio?
I need the image to keep being square, but it always stretch when it scales to min/max
Sadly I couldn't find any solution either except absolute pixel size
anyone figure out a way to have a string attribute as a dropdown, like enums? I want a dropdown with some predefined options that are somewhat dynamic.
You can do it by nesting visual elements but it's a pain: https://forum.unity.com/threads/ui-builder-problems-with-scale-images.927032/#post-6067764
Wow that is a pain lol
I hope they will address this in the future
you could setup a manipulator when the size changes that it maintains an aspect ratio.
lookup for DropDownField... it accepts List<string>
Thanks for the response but sadly it isn't that simple. Unless I am missing something, I am looking to add it to the inspector within the ui builder, something like the test enum there.
@tranquil sigil I figured a simple way to achieve 1:1 aspect ratio
using UnityEngine.UIElements;
public class SquareElement : VisualElement
{
MainSide m_type;
public SquareElement()
{
RegisterCallback<GeometryChangedEvent>(GeometryChanged);
}
void GeometryChanged(GeometryChangedEvent evt)
{
if (m_type is MainSide.Height) {
style.width = resolvedStyle.height;
} else {
style.height = resolvedStyle.width;
}
}
public new class UxmlTraits : VisualElement.UxmlTraits
{
UxmlEnumAttributeDescription<MainSide> m_side = new UxmlEnumAttributeDescription<MainSide>() { name = "Type" };
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
((SquareElement)ve).m_type = m_side.GetValueFromBag(bag, cc);
}
}
public new class UxmlFactory : UxmlFactory<SquareElement, UxmlTraits>
{
}
enum MainSide
{
Width,
Height,
}
}
a custom VisualElement that will make width/height same size as height/width
put whatever you want inside
and make it's size 100%/100%
it'll always be square
Still hoping to find a solution to the random blurriness once in-game. In editor it is nice and crisp. In game, its blurry. Any advice would be greatly appreciated.
I assume this is something everybody (but me) knows. Is there some z position setting that one uses to make text appear on a surface? I have a cube, I have a canvas as a child and a TextMeshPro object as a child of that. If the PosZ of that transform is 0 the text is embedded within the cube and not visible. At the moment I am setting the PosZ to -1.2 on the Rect Transform of the the text object but is that what everyone does?
I'm fairly certain this has something to do with how its handling transparency. I don't know what would be causing it to be inconsistent.
Omg thanks so much
I can now let go of all the hacky ways
You are literal angel, thanks so much
what exactly is blurry? can't see on screenshots
See the border? The bloom is from semi transparency. It's part of the sprite but the alpha is not mixing well with other UI elements.
Sounds like sprite problem
Hi, who know about dropdownfield to add options by list<string> ?
it is accepting list<string> already, so whats the issue?
how can i add the options to the dropdownfield i did this but is not working:
myDropdown.choices = myLevel;
myDropdown.value = myLevel[0];
myLevel is the list
myDropD.choices = new List<string>{"Meni1", "Menu2"};
then add callback to it
myDropD.RegisterValueChangedCallback(x =>{ Debug.Log(x.newValue);});
ok i will try thanks
What do you do for sprite animations in UI toolkit? Swap images?
No option for sprite animation for now afaik, but quite easy to do by manipulating the opacity in a loop
how do you do a particle system with UI toolkit?
ex) chest has sparks fly out when you open it
is render texture still the only way to do this?
if you need a 1:1 visual element can't you just padding top % then match the width to that % as well?
That's what I do for my icon / thumbnail visual elements and they always keep a 1:1 aspect ratio
that's one thing I found on unity forums at least when I had a similar issue
Also...is there a way to render objects in front of a ui document?
any reason why a template container doesn't have the same dimension as its parent?
In the PanelSettings, you can render it to a render texture.
And place the render texture into the world.
idk if events would work right, though.
that would make it worldspace no?
thought that wasn't a thing for ui toolkit?
It would make it worldspace.
Or you could have a render texture as a background-image and render a camera to the background image of a visual element
thats awesome thanks...I hadn't heard that it could even be worldspace
everything I saw said it couldn't be
I'm not sure that's what you're looking for though. I think you'd have to manually create a way to do a raycast to the plane and use that data to fire pointerevents if you want any events in the ui toolkit system.
But if this is just for non-interactive HUD, that should work.
Never tried it, so I apologize if that's wrong.
makes sense thanks 🙂
foiund some 3d script for it...but Im 2d so... 😦
uses meshrenderers and meshcolliders
making it work for 2d is above my abilities as I know literally nothing about 3d stuff lol
you are probably right...but atm that will take me awhile to figure out...just knowing I could make it into rendertexture may work 🙂
but if I end up having to do raycasts... :/
They aren't that bad 🙂 should be able to ask in the right channel here for help or even copy enough code from online sources
was told that its not my code so no one in #archived-code-general will help convert the 3d parts to 2d 😭
oh maybe you meant about regular raycasts for checking that
// Update(){
// if Input.mouseDown
// raycast from center of screen or mouse position
// for each collider, if collider.GetComponent<UIDocument>()
// Vector2 pointClickedOnScreen = (https://answers.unity.com/questions/583154/can-unitys-raycasting-determine-the-point-of-colli.html)
// Figure out how to fire a PointerDownEvent and supply pointClickedOnScreen
That's my naïve first thought on how it would work.
fair enough...UI Doc does all the clicker stuff for me rn so idk how it works at all
https://pastebin.com/hGqbCbH4
this is the code that works for 3d
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
just not sure how to get rid of the mesh things
Im not even sure how it works for 3d as I see no raycast for clicks
lol just put a 3D object in your 2D space.
ah, I mean 2d perspective ig then
Its just 3D where everything has the same Z val.
What is the binding path for this field that I should use in UI-Toolkit
Writing Test doesn't work
I need to make a custom editor for my scripts but I haven't been able to show these serialized properties
I just made a canvas and rendered it separately
I have seen demo scenes available in the past that demonstrate how to use UI Toolkit to make drag-and-drop systems, however if I recall correctly, it's no longer listed as an optional package in the package manager. How/where can I find demo scenes that exemplify this kind of behaviour?
how does that work?
wont the canvas be rendered behind the UI Doc?
delete the get/set
https://help.vertx.xyz/programming/variables/serialization/serializing-a-field-1#properties
The field will be serialized as
<PropertyName>k__BackingField
I can't input this in the binding path when using UI Builder
I mean that's not really a solution
You would need to use < instead of < and > instead of >
Okay, I'll try this
if the builder doesn't accept that, you'd have to do it in the UXML
I really think they should have thought about this kind of usage
honestly, I might consider that a bug, and something they haven't considered
do it in XML and if it does work there then I would probably report one
you have each UI doc on a canvas? or the particle system on a canvas? cause if just particle system wont that spawn behind the ui?
Particle on canvas
can I make label automatically resize based on the text it contains (preferably without script)?
basically what I found out is I need a content size fitter but in ui toolkit
Oh, I saw your question on reddit but didn't understand at first, you want a world space canvas but using 2D renderers and colliders is that right? (I'm the guy who made that post and code)
Okay so the Unity team made a function so the user can convert the position from screen space (the default one) to the space you need (in my code texture coordinate space), that why you don't see any raycast, the important part of the code is in the: ConvertScreenSpacePositionToPanelSpacePosition method the rest is simply to prepare your UIDocument to world space
I need to check if 2D colliders are returning the UV data inside the hitpoint but if it's the case it's pretty straightforward to change for 2D.
Basically yeah! Thats awesome man thanks 🙂
The part I mostly dont understand...how does the Doc know when/where you click on it? People above were talking about needing click events and raycast and stuff but didnt see any of that
It knows it thanks to internal events you don't need to worry about
Ah sweet 🙂
My guess is when you click the internal code check the position of your pointer against all the ui elements
and then pass the event to the elements if needed
Makes sense...what do the mesh colliders do in the code?
and thanks to the "ConvertScreenSpacePositionToPanelSpacePosition" method we are changing the actual pointer position
it help me get the uv position where the cursor/pointer is
that way I have a value between 0 and 1 that correspond to the cursor position
and next in the line 123 I'm converting that 0 - 1 back to the value the UIDocument need (meaning a value between 0 and the UIDocument size in pixels)
I guess even if the hit.textureCoord dosen't work it's also possible to use the bouding box of the 2D element because it's always going to face the camera in your project right?
right
I will take a look this afternoon might be a quick change
thanks fam! I was guessing it would be a fairly quick fix...however I have 0 knowledge of how meshes work or how shaders work so would only be a quick fix for someone who understood those lol ❤️
Okay so unfortunately it's not that easy to do, because the sprite renderer component can't directly take a render texture as input and it will be a waste of performance to convert it every frames.
But what you can do is using the default code for the 3D world space document and simply place the quad above what you need
The quad is a flat mesh anyway
Gotcha...Ill give it a try in a bit, might have to ask for some more help depending how it goes 🙂
Has anyone come up with a solution for the scroll-bar being super slow?
In the end we replaced e.g. all ScrollViews with our own custom VisualElement that inherits from ScrollView, listened to the mouse wheel event and multiplied it by like 500. So stupid but ultimately a quick fix, even replacing the instances in our uxml. Such an egregious bug though.
I need to get a height of an element, but it always returns NaN. How can I fix it?
Don't remember exactly but you should check layout or resolvedStyle but one of the properties have the width/ height up to date
My mental model of what happens with UITK is (it may not actually work like this):
- Frame1: Set a bunch of styles on a bunch of things
- Before display: process layout, calculate all the actual rects
- After display: set resolvedStyle values to those values just calculated
So if you want to read the calculated height, you can either just read resolvedStyle as Anthelme says - or, as is common - you may need to wait a frame before doing so. One nice thing (imo) about UITK is the update loop is independent of the main one thus it's advisable to use UITK's scheduler. In practice this looks like:
VisualElement bob;
bob.style.minHeight = 100;
bob.style.maxHeight = 200;
bob.style.flexGrow = 1;
bob.schedule.Execute(() =>
{
float resolvedHeight = bob.resolvedStyle.height;
// do something with the height
});```
This syntax automatically executes on the next frame. You can append calls to the Execute() method such as ExecuteLater() to eg happen after 1 second.
any suggestions how buttons should be handled that trigger on certain keybinds? i learned that you can attach classes onto visualElement.userData. is that the proper way? to manually call update on those script classes?
could you elaborate what you are trying to achieve?
i'm porting my unityUI hotbar UI. some container with skill buttons that have a keybinding, show cooldowns, etc... i'm just not sure how i should set this up in a nice way. guess i need some form of controller and the uitoolkit has no idea what's going on really 😄
you want to implement keybinds, that's it?
yeah, i mean, that's what i'm starting with. as mentioned i will also have to handle cooldowns
with a proper pattern, cooldowns should be handled by game logic, not UI logic
meanwhile if keybind is caught - you simply can dispatch event to hierarchy
or use other callbacks
that might subscribe directly
in short - treat UI the same way you treat rendering. You only send to it what you want to render, no complex logic to solve
hm, i have the cooldowns in a dynamic buffer. previously, ui elements were reading from this buffer individually and then i calculate the value. you suggest, it'd be better to have a system that updates the value of the circular progress bar, right?
yeah
don't ever make UI to calculate anything, just send ready data to it when you want it updated
makes sense. and same goes for keybinds? yeah, i can make that work. the whole data flow got turned on its head with uitoolkit and entities 😄
it really doesn't matter whether you use ECS or monob, you still need a bridge between UI and game logic
You can take a look at my package which provides data binding + localization support
https://github.com/bustedbunny/com.bustedbunny.mvvmtoolkit
it kind of enforces proper way on it's own (not package, but pattern itself)
it's MVVM though 😅