using UnityEngine;
using UnityEngine.UIElements;
[UxmlElement]
public partial class TestVisualElement : VisualElement
{
[UxmlAttribute]
public string TestString { get; set; }
public TestVisualElement()
{
Debug.Log(TestString);
}
}
The value is applied after the element is constructed, there’s no way we could do it before. You can use the property setter method to know when its set.
When I use this custom element directly in UI Document it works fine but if I make a template from it and use this template inside the document it returns null again
Thats normal, it resets values in the UI Builder.
You should adjust your code to expect a null string or change the default value for _actionName.
Maybe change it to private string _actionName = "";
I’m not sure I understand how private string _actionName = ""; should help.
I want to configure different strings for each instance of KeyBindingTemplate but it resets all of them to value of _actionName.
The UI Builder will set all the attributes to their default values. The default value for ActionName is currently null. Instead of setting it to “” you would be better checking if the value is null or empty in Initialize and not calling InputSystem.actions.FindAction if it is.
I mean, yeah, there will be no error if I check for null or empty but property is initialized with configured in UIBuilder string and after that gets reseted to default value. So at the end all instances reseted to whatever _actionName is.
This is what I have in Builder:
It’s properly initialized at start
After that it gets reseted without calling property setter
I think it’s a bug or I don’t know something about templates. My uxml structure looks like this:
Everything is fine but if I give SettingsWindow.uxml template some name all properties in custom controls inside it will fail to initialize.
Without name:
With name:
What could be the reason for this behavior?
Hi! This is a bit of a gravedig but it looks like I am facing the same issue in Unity 6000.0.51f1 (which I downloaded yesterday while trying to fix this)
I have this LocalizedButton component that has a LocalizationKey attribute, so that the text of the button is pulled from the localization tables.
I previously implemented it with UxmlFactory/UxmlTraits and it worked just fine, but now I decided to try and migrate it to the new UxmlElement/UxmlAttribute approach. The button mostly works fine but when I open the UI Builder window and select this button, the text becomes empty. Upon reopening the UI Builder or running the game the text shows up properly again. This bug makes it inconvenient to work with the UI builder and I thought maybe I’m doing something wrong.
Here’s the code of the button:
[UxmlElement]
public partial class LocalizedButton : Button
{
// [Preserve]
// public new class UxmlFactory : UxmlFactory<LocalizedButton, UxmlTraits> { }
//
// [Preserve]
// public new class UxmlTraits : LocalizableUxmlTraits { }
[UxmlAttribute]
public string LocalizationKey
{
get => _localizationKey;
set
{
_localizedString.TableEntryReference = value;
_localizationKey = value;
}
}
private string _localizationKey = "defaultValue";
private readonly LocalizedString _localizedString;
public LocalizedButton()
{
_localizedString = new LocalizedString(LocalizationSettings.StringDatabase.DefaultTable, string.Empty);
_localizedString.StringChanged += str => text = str;
}
}
The text is a UXML Attribute, so it will be replaced with the empty string when the element is synced by the UI Builder. Changing other UXML Attributes can create unpredictable behaviour in the builder.
If you want to control the text attribute you should either use a data binding or override the text attribute. See MyOverrideDrawerAttribute - Unity - Scripting API: UxmlAttributeAttribute
The Localization package already has data binding support. I recommend using that:
Thanks for the reply!
I am not sure how I would apply MyOverrideDrawerAttribute here since those PropertyAttributes that you linked seemingly only affect how the UI builder draws its own attribute editor sidebar.
But nonetheless, I made it work with the localization package’s data binding support so thanks for that!